<template>
  <view class="page">
    <u-navbar class="navbar" :is-back="true" title="在线接诊" title-color="#1a1a1a" :border-bottom="true"></u-navbar>

    <view class="toolbar">
      <view class="store" @click="storePickerOpen = true">
        <text class="store-name">{{ currentStoreName || '选择门店' }}</text>
        <u-icon name="arrow-down-fill" size="20" color="#666"></u-icon>
      </view>
      <text class="store-hint">在线复诊列表与 PC 一致，不按门店筛选</text>
    </view>

    <view class="tabs-wrap white">
      <u-tabs
          bar-width="40"
          :height="70"
          :list="listTabs"
          :current="listTabIndex"
          :is-scroll="false"
          active-color="#6ACDBB"
          inactive-color="#8A92A3"
          bg-color="#fff"
          @change="onListTabChange"
      ></u-tabs>
    </view>

    <view class="list-wrap">
      <view v-if="patientList.length" class="list">
        <view
            v-for="(row, idx) in patientList"
            :key="row._wxKey"
            class="ol-card flex-row flex-ali-center"
            :data-idx="idx"
            @tap="onPatientCardTap"
        >
          <view class="ol-avatar-wrap">
            <u-image width="80rpx" height="80rpx" shape="circle" :src="rowAvatar(row)">
              <u-loading slot="loading"></u-loading>
            </u-image>
            <u-badge
                v-if="Number(row.unread_count) > 0"
                :count="Number(row.unread_count)"
                :offset="[-4, -4]"
                bgColor="#F44336"
                :overflow-count="99"
            ></u-badge>
          </view>

          <view class="ol-card-body flex-col flex-1">
            <!-- 第一行：姓名、基本信息、手机号、转诊标签 | 右侧时间 -->
            <view class="flex-row flex-jus-sp flex-ali-center">
              <view class="flex-row flex-ali-center flex-1 text-hide p-r-20">
                <text class="ol-name">{{ displayName(row) }}</text>
                <text class="ol-meta">{{ patientSexAgeText(row) }}</text>
                <text v-if="displayMobile(row)" class="ol-meta m-l-12">{{ displayMobile(row) }}</text>
                <u-tag
                    v-if="Number(row.is_from_transfer) === 1"
                    text="转诊"
                    type="warning"
                    size="mini"
                    class="ol-tag"
                ></u-tag>
              </view>
              <text class="ol-time">{{ formatRowMsgTime(row) }}</text>
            </view>

            <!-- 第二行：最新消息预览 | 右侧状态 -->
            <view class="flex-row flex-jus-sp flex-ali-center m-t-12">
              <view class="ol-preview text-hide flex-1 p-r-20">
                <text>{{ lastMessageDisplayLine(row) }}</text>
              </view>
              <view class="ol-status">
                <d-text
                    :text="statusText(row.status)"
                    :color="rowStatusColor(row.status)"
                    size="24"
                ></d-text>
              </view>
            </view>

            <!-- 单号暂时隐藏 -->
            <!--
            <view v-if="row.order_no" class="flex-row m-t-8">
              <text class="ol-sub">单号：{{ row.order_no }}</text>
            </view>
            -->
          </view>
        </view>
      </view>
      <view v-else class="empty">
        <d-empty text="暂无在线接诊患者"></d-empty>
      </view>
    </view>

    <u-popup v-model="storePickerOpen" mode="bottom" border-radius="24" length="55%" :safe-area-inset-bottom="true">
      <view class="popup-inner">
        <view class="popup-title">选择诊所</view>
        <scroll-view scroll-y class="popup-scroll">
          <view
              v-for="item in storeList"
              :key="item.id"
              class="store-row"
              @click="changeStore(item.id)"
          >
            <text :class="{'active-store-text': String(storeId) === String(item.id)}">{{ item.name || item.store_name }}</text>
            <u-icon v-if="String(storeId) === String(item.id)" name="checkmark-circle-fill" color="#6ACDBB" size="36"></u-icon>
          </view>
        </scroll-view>
        <view class="popup-footer">
          <view class="u-btn qx" @click="storePickerOpen = false">取消</view>
        </view>
      </view>
    </u-popup>
  </view>
</template>

<script>
import { getOnlineConsultationPatientListApi, getMyStoreListApi, switchStoreApi } from '@/api/reception.js';
import { normalizeRoomId } from '@/utils/chat/chatRoomManager.js';
import { formatSessionRelativeTime } from '@/utils/chat/sessionListFormat.js';

export default {
  data() {
    return {
      patientList: [],
      listType: 1,
      listTabs: [{ name: '当前接诊' }, { name: '历史接诊' }],
      storeList: [],
      currentStoreName: '',
      storePickerOpen: false,
      storeId: uni.getStorageSync('store_id') || '',
      loading: false
    };
  },
  computed: {
    listTabIndex() {
      return this.listType === 1 ? 0 : 1;
    }
  },
  onShow() {
    this.bootstrap();
  },
  onLoad() {
    this.__doctorImRoomUpdateHandler = this.applyDoctorImRoomUpdate.bind(this);
    uni.$on('doctor-im-room-update', this.__doctorImRoomUpdateHandler);
  },
  onUnload() {
    if (this.__doctorImRoomUpdateHandler) {
      uni.$off('doctor-im-room-update', this.__doctorImRoomUpdateHandler);
      this.__doctorImRoomUpdateHandler = null;
    }
  },
  methods: {
    applyDoctorImRoomUpdate(payload) {
      const rid = normalizeRoomId(payload && payload.roomId);
      if (!rid) return;
      const idx = this.patientList.findIndex((r) => normalizeRoomId(r.room_id) === rid);
      if (idx === -1) return;
      const row = this.patientList[idx];
      const copy = { ...row };
      if (payload.last_message_preview != null && String(payload.last_message_preview).trim() !== '') {
        copy.last_message_preview = payload.last_message_preview;
      }
      if (payload.last_message_time != null && payload.last_message_time !== '') {
        copy.last_message_time = payload.last_message_time;
      }
      if (payload.incrementUnread) {
        if (payload.unreadForRoom != null) {
          copy.unread_count = Number(payload.unreadForRoom);
        } else {
          copy.unread_count = Number(copy.unread_count || 0) + 1;
        }
      }
      const next = [...this.patientList];
      next.splice(idx, 1, copy);
      this.patientList = this.mapPatientRows(this.sortPatientList(next));
    },
    unwrap(res) {
      if (res == null) return null;
      if (res.result !== undefined && res.result !== null) return res.result;
      if (res.data && res.data.result !== undefined) return res.data.result;
      return res;
    },
    mapPatientRows(rows) {
      return (rows || []).map((row, idx) => {
        const room = row.room_id != null && row.room_id !== '' ? String(row.room_id) : 'r0';
        const reg = row.register_id != null ? row.register_id : row.id;
        const ord = row.order_no != null && row.order_no !== '' ? String(row.order_no) : '';
        const ub = Number(row.unread_count || 0);
        return {
          ...row,
          _wxKey: `${room}-${reg != null ? reg : 'x'}-${ord}-${ub}`,
        };
      });
    },
    lastMessageSortTs(row) {
      const t = row.last_message_time || row.updated_at || row.register_time;
      if (!t) return 0;
      const n = new Date(typeof t === 'number' && t < 1e12 ? t * 1000 : t).getTime();
      return Number.isNaN(n) ? 0 : n;
    },
    sortPatientList(rows) {
      if (!Array.isArray(rows)) return [];
      return [...rows].sort((a, b) => this.lastMessageSortTs(b) - this.lastMessageSortTs(a));
    },
    lastMessagePreview(row) {
      const p = row.last_message_preview;
      if (p != null && String(p).trim() !== '') return String(p);
      return '暂无消息';
    },
    patientSexAgeText(row) {
      const up = row && row.user_patient;
      if (!up) return '';
      const sex = Number(up.sex) % 2 !== 0 ? '男' : '女';
      const age = up.age != null && up.age !== '' ? `${up.age}岁` : '';
      const parts = [sex, age].filter(Boolean);
      return parts.length ? parts.join(' ') : '';
    },
    lastMessageDisplayLine(row) {
      return this.lastMessagePreview(row);
    },
    formatRowMsgTime(row) {
      return formatSessionRelativeTime(row);
    },
    rowAvatar(row) {
      const up = row && row.user_patient;
      if (up && up.avatar) return up.avatar;
      const sex = up ? Number(up.sex) : 0;
      return require(`@/static/image/${sex % 2 === 0 ? 'nv' : 'nan'}.png`);
    },
    rowStatusColor(st) {
      const s = Number(st);
      if (s === 1) return '#F44336';
      if (s === 2) return '#00C853';
      return '#C4C7CC';
    },
    onPatientCardTap(e) {
      const idx = Number(e?.currentTarget?.dataset?.idx);
      if (Number.isNaN(idx) || idx < 0) return;
      const row = this.patientList[idx];
      if (!row) return;
      this.goChat(row);
    },
    async bootstrap() {
      await this.loadStores();
      await this.loadPatientList();
    },
    async loadStores() {
      try {
        const res = await getMyStoreListApi();
        const raw = this.unwrap(res);
        this.storeList = Array.isArray(raw) ? raw : raw?.list || raw?.stores || [];
        this.storeId = uni.getStorageSync('store_id') || this.storeId;
        const cur = this.storeList.find((s) => String(s.id) === String(this.storeId));
        this.currentStoreName = cur ? (cur.name || cur.store_name) : '';
      } catch (e) {
        console.error(e);
      }
    },
    async changeStore(id) {
      try {
        await switchStoreApi({ store_id: id });
        uni.setStorageSync('store_id', id);
        this.storeId = id;
        const cur = this.storeList.find((s) => String(s.id) === String(id));
        this.currentStoreName = cur ? (cur.name || cur.store_name) : '';
        this.storePickerOpen = false;
      } catch (err) {
        uni.showToast({ title: '切换门店失败', icon: 'none' });
      }
    },
    onListTabChange(index) {
      const next = index === 0 ? 1 : 2;
      if (this.listType === next) return;
      this.listType = next;
      this.loadPatientList();
    },
    async loadPatientList() {
      this.loading = true;
      try {
        const res = await getOnlineConsultationPatientListApi({ type: this.listType });
        const raw = this.unwrap(res);
        const arr = Array.isArray(raw) ? raw : [];
        this.patientList = this.mapPatientRows(this.sortPatientList(arr));
      } catch (e) {
        console.error(e);
        this.patientList = [];
        uni.showToast({ title: '加载失败', icon: 'none' });
      } finally {
        this.loading = false;
      }
    },
    displayName(row) {
      return row.user_patient?.name || row.user?.nick_name || row.name || '患者';
    },
    displayMobile(row) {
      return row.user_patient?.mobile || row.user?.mobile || row.mobile || '';
    },
    statusText(st) {
      const m = { 1: '待接诊', 2: '接诊中', 3: '已结束' };
      return m[st] || '其他';
    },
    goChat(row) {
      if (!row || typeof row !== 'object') {
        return;
      }
      const regId = row.register_id != null ? row.register_id : row.id;
      const name = encodeURIComponent(this.displayName(row));
      const room = row.room_id || '';
      const up = row.user_patient_id || row.user_patient?.id || '';
      uni.navigateTo({
        url: `/subPackages/sub_online_reception/pages/chat?register_id=${regId}&room_id=${encodeURIComponent(
            String(room || '')
        )}&patient_name=${name}&user_patient_id=${up}`
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.page {
  min-height: 100vh;
  background: #f7f8fa;
}

.white {
  background: #fff;
}

.toolbar {
  padding: 20rpx 24rpx;
  background: #fff;
}

.tabs-wrap {
  padding: 0 16rpx;
}

.store {
  display: inline-flex;
  align-items: center;
  margin-bottom: 8rpx;
}

.store-name {
  font-size: 28rpx;
  color: #333;
  margin-right: 8rpx;
}

.store-hint {
  display: block;
  font-size: 22rpx;
  color: #999;
  line-height: 1.4;
  margin-top: 4rpx;
}

.list-wrap {
  padding: 20rpx;
}

.list {
  width: 100%;
}

/* 扁平、紧凑的卡片样式 */
.ol-card {
  background: #ffffff;
  border-radius: 16rpx;
  padding: 24rpx 20rpx;
  margin-bottom: 16rpx;
  position: relative;
}

.ol-avatar-wrap {
  width: 80rpx;
  position: relative;
  flex-shrink: 0;
  margin-right: 20rpx;
}

.ol-card-body {
  width: auto !important;
  height: auto !important;
  min-width: 0;
}

.ol-name {
  font-size: 32rpx;
  font-weight: 500;
  color: #333;
  margin-right: 16rpx;
}

.ol-meta {
  font-size: 24rpx;
  color: #888;
}

.ol-tag {
  margin-left: 12rpx;
  transform: scale(0.9);
  transform-origin: left center;
}

.ol-time {
  flex-shrink: 0;
  font-size: 22rpx;
  color: #999;
  margin-left: 16rpx;
}

.ol-sub {
  font-size: 24rpx;
  color: #666;
}

.ol-status {
  flex-shrink: 0;
  margin-left: 16rpx;
}

/* 消息预览只保留纯文本，去除臃肿背景 */
.ol-preview {
  font-size: 26rpx;
  color: #666;
  line-height: 1.4;
}

.text-hide {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.m-t-8 { margin-top: 8rpx; }
.m-t-12 { margin-top: 12rpx; }
.m-l-12 { margin-left: 12rpx; }
.p-r-20 { padding-right: 20rpx; }

.empty {
  padding: 120rpx 0;
  display: flex;
  justify-content: center;
  width: 100%;
}

/* 弹窗精简 */
.popup-inner {
  padding: 24rpx;
}

.popup-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #333;
  text-align: center;
  margin-bottom: 24rpx;
}

.popup-scroll {
  max-height: 50vh;
}

.store-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 26rpx 16rpx;
  border-bottom: 1rpx solid #f5f6f8;
  font-size: 28rpx;
  color: #333;

  &:last-child {
    border-bottom: none;
  }
}

.active-store-text {
  color: #6ACDBB;
  font-weight: 500;
}

.popup-footer {
  padding-top: 24rpx;
}

.qx {
  text-align: center;
  padding: 20rpx;
  color: #666;
  background: #f7f8fa;
  border-radius: 40rpx;
  font-size: 28rpx;
}
</style>