<template>
  <div class="flex-container">
    <TUIConversation
      class="conversation"
      @handleSwitchConversation="handleSwitchConversation"
      @handUpdateOrderStatus="updateOrderStatus"
      @newConversationUpdated="newConversationUpdated"
      @updateHlwDoctorOnlineStatus="updateHlwDoctorOnlineStatus"
    />
    <TUIChat
      v-if="mergeStatus === '需处理'"
      class="chat"
      :order="order"
      @handRefundConsultation="handRefundConsultation"
      @endConsultation="endConsultation"
      @countdownFinished="endConsultation"
      @onMessageListUpdated="onMessageListUpdated"
    >
      <div class="noChatView">请在左侧选择会话，进入聊天</div>
    </TUIChat>
    <history-chat-room
      :selectHistoryUser="selectHistoryUser"
      :diagnosisExist="diagnosisExist"
      :isShowIllnessSummary="isShowIllnessSummary"
      class="w-full"
      v-else
    />
  </div>
  <illness-summary :order="order" :visible="summaryVisible" @close="summaryVisible = false" />
  <diagnosis-drawer
    :canEdit="canEditDiagnosis"
    :order="order"
    :visible="visible"
    :prescriptionStartTime="order && order.prescriptionStartTime"
    :prescriptionEndTime="order && order.prescriptionEndTime"
    @close="visible = false"
    @onDiagnosisSubmited="onDiagnosisSubmitted"
  />
  <reject-modal :order="order" :visible="rejectVisible" @close="rejectVisible = false" @refund="refund" />
  <archive-drawer :patient="order" :visible="archiveVisible" @close="archiveVisible = false" />
</template>
<script setup>
import { ref, onMounted, onUnmounted, provide, computed, watch } from "vue";
import { TUIConversation, TUIChat } from "../../../TUIKit/components";
import illnessSummary from "./illness-summary/illness-summary.vue";
import diagnosisDrawer from "./diagnosis-drawer/diagnosis-drawer.vue";
import rejectModal from "./reject-modal";
import {
  getConsultOrder,
  updateConsultOrderStatus,
  refundConsultation,
  finishConsultOrder,
  acceptConsultOrder,
  getHlwDoctorList,
  updateHlwDoctor,
  orderHasDiagnosis,
  getOrderDiagnosis,
} from "@/api/hlw";
import { TUIStore, StoreName } from "@tencentcloud/chat-uikit-engine";
import historyChatRoom from "../history-chat-room/history-chat-room.vue";
import dayjs from "dayjs";
import { ElMessage } from "element-plus";
import { getStatus } from "@/utils/hlw-order";
import { colorMap } from "@/utils/hlw-order";
import { useVideoConsultStore } from "@/store/video-consult";
import archiveDrawer from "@/components/archive-drawer/archive-drawer.vue";

const order = ref({});
const onlineStatus = ref(sessionStorage.getItem("onlineStatus") || "offline");
const mergeStatus = ref("需处理");
const summaryVisible = ref(false);
const orderList = ref([]);
const visible = ref(false);
const rejectVisible = ref(false);
const diagnosisExist = ref(true);
const canEditDiagnosis = ref(false);
const doctor = ref({});
const archiveVisible = ref(false);

provide('chat-order-detail', order)

const videoConsultStore = useVideoConsultStore();
const lastHandledVideoSignalId = ref("");

const isShowIllnessSummary = computed(() => order.value && order.value._id);
function showIllnessSummary() {
  summaryVisible.value = true;
}
function showDiagnosisDrawer(allowEdit = false) {
  canEditDiagnosis.value = allowEdit;
  visible.value = true;
}

function showPendingOrderArchive() {
  archiveVisible.value = true;
}

provide("showIllnessSummary", showIllnessSummary);
provide("currentOrder", order);
provide("showPendingOrderArchive", showPendingOrderArchive);

provide("showDiagnosisDrawer", showDiagnosisDrawer);
provide("pdateHlwDoctorOnlineStatus", updateHlwDoctorOnlineStatus);
provide("selectUser", handSelectUser);
provide("isShowIllnessSummary", isShowIllnessSummary);
provide("orderList", orderList);
provide("mergeStatus", mergeStatus);
provide("onlineStatus", onlineStatus);
provide("diagnosisExist", diagnosisExist);
provide("openVideoConsult", openVideoConsult);
// 是否已为当前医生开通视频问诊功能（人员管理业务配置）
const videoConsultEnabled = computed(() => {
  return !!(doctor.value && doctor.value.enableVideoConsult);
});
provide("videoConsultEnabled", videoConsultEnabled);
const selectHistoryUser = ref(null);

// 统一处理来自 TIM 自定义消息的视频问诊信令
function handleVideoConsultSignalFromMessage(message) {
  console.log("[VIDEO][PC] handleVideoConsultSignalFromMessage: incoming", {
    id: message && message.ID,
    type: message && message.type,
    payload: message && message.payload,
    videoStatus: videoConsultStore.status,
  });
  const msgId = message && message.ID ? String(message.ID) : "";
  if (msgId && lastHandledVideoSignalId.value === msgId) return;
  if (msgId) lastHandledVideoSignalId.value = msgId;
  const isIncoming = !!(message && message.flow === "in");
  if (
    !message ||
    message.type !== "TIMCustomElem" ||
    !message.payload ||
    message.payload.description !== "VIDEO_CONSULT"
  ) {
    console.log("[VIDEO][PC] not VIDEO_CONSULT, ignore");
    return;
  }
  const signal = message.payload.data;
  console.log("[VIDEO][PC] signal", {
    signal,
    statusBefore: videoConsultStore.status,
  });
  // 只处理来自对端的信令，避免自己发送的消息触发重复 leaveRoom
  if (!isIncoming) return;
  if (
    signal === "VIDEO_CONSULT_HANGUP" ||
    signal === "VIDEO_CONSULT_CANCEL" ||
    signal === "VIDEO_CONSULT_REJECT"
  ) {
    const leaveOptions =
      signal === "VIDEO_CONSULT_HANGUP"
        ? { skipSendSignal: false, reason: "peer_hangup" }
        : signal === "VIDEO_CONSULT_REJECT"
        ? { skipSendSignal: false, reason: "peer_reject" }
        : { skipSendSignal: true, reason: "peer_cancel" };
    if (videoConsultStore.status !== "idle") {
      console.log("[VIDEO][PC] signal triggers leaveRoom", {
        signal,
        status: videoConsultStore.status,
      });
      videoConsultStore.leaveRoom(leaveOptions);
    } else {
      console.log(
        "[VIDEO][PC] signal received but status is idle, skip leaveRoom"
      );
    }
    // 无论当前房间状态如何，收到结束类信令都应关闭视频弹窗
    videoConsultStore.closeUI();
    if (signal === "VIDEO_CONSULT_REJECT") {
      ElMessage.warning("患者已拒绝本次视频问诊");
    }
  } else if (signal === "VIDEO_CONSULT_BUSY") {
    if (videoConsultStore.status !== "idle") {
      console.log("[VIDEO][PC] BUSY signal triggers leaveRoom", {
        status: videoConsultStore.status,
      });
      videoConsultStore.leaveRoom({ skipSendSignal: true, reason: "peer_busy" });
    }
    // 忙线时同样关闭弹窗，避免长时间停留在占线界面
    videoConsultStore.closeUI();
    ElMessage.warning("患者当前正在进行其他视频问诊，请稍后再试");
  }
}


function openVideoConsult() {
  if (!order.value || !order.value.orderId) {
    ElMessage.warning("请先选择问诊订单");
    return;
  }
  // 若已有其他订单的视频问诊在进行，则只弹出窗口提示，不重复发起
  if (videoConsultStore.status !== "idle" && videoConsultStore.activeOrderId && videoConsultStore.activeOrderId !== order.value.orderId) {
    ElMessage.warning("当前已有其他问诊订单的视频问诊进行中，请先结束当前视频问诊");
    videoConsultStore.openUI(videoConsultStore.currentOrder || order.value);
    return;
  }
  videoConsultStore.openUI(order.value);
  // 如果当前没有视频会话，则在全局弹窗中自动发起
}

// 选择历史聊天记录
function handSelectUser(user) {
  selectHistoryUser.value = user;
}
// 退诊并退款
async function handRefundConsultation(orderId) {
  rejectVisible.value = true;
}
async function refund(arr) {
  // 如果有正在进行的视频问诊，先结束视频问诊
  if (videoConsultStore.status !== "idle" && videoConsultStore.activeOrderId === order.value.orderId) {
    console.log("[VIDEO][PC] refund: ending video consult before cancelling order");
    await videoConsultStore.leaveRoom({ reason: "consult_cancelled", skipSendSignal: false });
  }
  
  order.value.orderStatus = "cancelled";
  order.value.status = "已取消";
  rejectVisible.value = false;
}
// 倒计时结束
async function endConsultation() {
  // 如果有正在进行的视频问诊，先结束视频问诊
  if (videoConsultStore.status !== "idle" && videoConsultStore.activeOrderId === order.value.orderId) {
    console.log("[VIDEO][PC] endConsultation: ending video consult before finishing order");
    await videoConsultStore.leaveRoom({ reason: "consult_ended", skipSendSignal: false });
  }
  
  const { data, success, message } = await finishConsultOrder({
    orderId: order.value.orderId,
  });
  if (success) {
    order.value.orderStatus = "finished";
    order.value.status = "已结束";
  } else {
    ElMessage.warning(message);
  }
}
async function handleSwitchConversation(conversationID, fateOrder) {
  if (fateOrder && fateOrder.orderStatus === "pending") {
    const { data, success, message } = await acceptConsultOrder({
      orderId: fateOrder.orderId,
      doctorCode: sessionStorage.getItem("doctorNo"),
    });
    if (!success) {
      ElMessage.error(message || '接诊失败');
      order.value = {}
      return
    }
    fateOrder.expireTime = data.expireTime;
    fateOrder.status = "处理中";
    fateOrder.orderStatus = "processing";
    fateOrder.statusColor = colorMap[fateOrder.orderStatus];
    const selectedOrderIndex = orderList.value.findIndex((i) => i.orderId === fateOrder.orderId);
    orderList.value[selectedOrderIndex] = fateOrder;

    // 接单后：仅采用后端返回的处方开始时间（若提供）并写入订单对象
    if (data && (data.serverPrescriptionStartTime || data.prescriptionStartTime)) {
      const serverStart = Number(data.serverPrescriptionStartTime || data.prescriptionStartTime);
      fateOrder.prescriptionStartTime = serverStart;
    }
  }
  order.value = fateOrder;

  // 切换订单后，从后端诊断记录同步处方结束时间（避免本地计算）
  if (fateOrder && fateOrder.orderId) {
    await syncPrescriptionTimesFromServer(fateOrder.orderId, fateOrder.doctorCode || sessionStorage.getItem("doctorNo"));
  }
}

// 从后端诊断记录同步处方时间（严格以服务端为准）
async function syncPrescriptionTimesFromServer(orderId, doctorNo) {
  try {
    if (!orderId) return;
    const { success, data } = await getOrderDiagnosis({ orderId, doctorNo });
    if (!success) return;
    const record = data && data.data ? data.data : null;
    if (!record) return;
    const start = Number(record.prescriptionStartTime) || null;
    const end = Number(record.prescriptionEndTime) || null;
    // 将服务端时间写入当前订单对象
    if (start && order.value && order.value.orderId === orderId) {
      order.value.prescriptionStartTime = start;
    }
    if (end && order.value && order.value.orderId === orderId) {
      order.value.prescriptionEndTime = end;
    }
  } catch (e) {
    // 忽略同步失败，使用本地兜底
  }
}
watch(
  () => mergeStatus.value,
  (n) => {
    if (n === "需处理") {
      getConsultOrderList();
    }
  });
function newConversationUpdated() {
  getConsultOrderList();
}
function onMessageListUpdated(list) {
  // 获取到最后 一条记录
  if (list && list.length) {
    const lastMessage = list[list.length - 1];
    console.log("[VIDEO][PC] onMessageListUpdated lastMessage", {
      id: lastMessage && lastMessage.ID,
      type: lastMessage && lastMessage.type,
      payload: lastMessage && lastMessage.payload,
    });
    const { conversationID } = lastMessage;
    const userID = typeof conversationID === "string" ? conversationID.replace("C2C", "") : "";
    if (lastMessage && lastMessage.type === "TIMCustomElem" && ["FINISHED", "COMPLETED", "CANCELLED", "AUDIFAIL"].includes(lastMessage.payload.data)) {
      // 会话结束 更新订单状态
      // completed 已完成  cancelled 已取消 finished 已结束
      orderList.value.forEach((i) => {
        if (i.orderId === userID) {
          if (lastMessage.payload.data === "AUDIFAIL") {
            i.status = "处理中";
            i.orderStatus = "processing";
            i.statusColor = colorMap[i.orderStatus];
          } else {
            i.status = lastMessage.payload.data === "FINISHED" ? "已结束" : lastMessage.payload.data === "COMPLETED" ? "已完成" : "已取消";
            i.orderStatus = lastMessage.payload.data === "FINISHED" ? "finished" : lastMessage.payload.data === "COMPLETED" ? "completed" : "cancelled";
            i.statusColor = colorMap[i.orderStatus];
          }
        }
      });
    } else if (
      lastMessage &&
      lastMessage.type === "TIMCustomElem" &&
      lastMessage.payload &&
      lastMessage.payload.description === "VIDEO_CONSULT"
    ) {
      const signal = lastMessage.payload.data;
      const isIncoming = !!(lastMessage.flow === "in");
      if (!isIncoming) return;
      if (
        signal === "VIDEO_CONSULT_HANGUP" ||
        signal === "VIDEO_CONSULT_CANCEL" ||
        signal === "VIDEO_CONSULT_REJECT"
      ) {
        const leaveOptions =
          signal === "VIDEO_CONSULT_HANGUP"
            ? { skipSendSignal: false, reason: "peer_hangup" }
            : signal === "VIDEO_CONSULT_REJECT"
            ? { skipSendSignal: false, reason: "peer_reject" }
            : { skipSendSignal: true, reason: "peer_cancel" };
        // 只要存在进行中的视频问诊，就结束当前房间，避免信令遗漏导致医生端一直停留在等待界面
        if (videoConsultStore.status !== "idle") {
          videoConsultStore.leaveRoom(leaveOptions);
        }
        // 收到结束类信令时，确保关闭视频弹窗
        videoConsultStore.closeUI();
        if (signal === "VIDEO_CONSULT_REJECT") {
          ElMessage.warning("患者已拒绝本次视频问诊");
        }
      } else if (signal === "VIDEO_CONSULT_BUSY") {
        if (videoConsultStore.status !== "idle") {
          videoConsultStore.leaveRoom({ skipSendSignal: true, reason: "peer_busy" });
        }
        // 忙线场景也关闭弹窗，避免医生端一直停留在等待界面
        videoConsultStore.closeUI();
        ElMessage.warning("患者当前正在进行其他视频问诊，请稍后再试");
      }
    } else if (lastMessage && lastMessage.type === "TIMCustomElem" && lastMessage.payload.data === "MEDICALADVICE") {
      orderList.value.forEach((i) => {
        if (i.orderId === userID) {
          i.status = "已完成";
          i.orderStatus = "completed";
          i.statusColor = colorMap[i.orderStatus];
        }
      });
    }
  }
}

function handleGlobalVideoMessageListUpdated(list) {
  if (!Array.isArray(list) || !list.length) return;
  const lastMessage = list[list.length - 1];
  console.log("[VIDEO][PC] handleGlobalVideoMessageListUpdated lastMessage", {
    id: lastMessage && lastMessage.ID,
    type: lastMessage && lastMessage.type,
    payload: lastMessage && lastMessage.payload,
  });
  handleVideoConsultSignalFromMessage(lastMessage);
}


async function getConsultOrderList(orderId) {
  const res = await getConsultOrder({
    page: 1,
    pageSize: 1000,
    doctorCode: sessionStorage.getItem("doctorNo"),
    mergeStatus: mergeStatus.value,
  });
  orderList.value = res.data.data.map((item) => {
    const { text, color } = getStatus(item);
    return {
      ...item,
      status: text,
      statusColor: color,
    };
  });
}

async function getHlwDoctorDetail() {
  const { data, success, message } = await getHlwDoctorList({
    doctorCode: sessionStorage.getItem("doctorNo"),
    serviceStatus: "enabled",
    page: 1,
    pageSize: 10,
  });
  if (!success) {
    ElMessage.error(message || "获取医生信息失败");
    return
  }
  doctor.value = data && Array.isArray(data.data) && data.data[0] ? data.data[0] : null;
  onlineStatus.value = doctor.value && doctor.value.onlineStatus ? doctor.value.onlineStatus : "offline";
}
async function updateHlwDoctorOnlineStatus(newOnlineStatus) {
  const res = await updateHlwDoctor({
    doctorNo: sessionStorage.getItem("doctorNo"),
    params: {
      onlineStatus: newOnlineStatus,
    },
  });
  if (res.success) {
    onlineStatus.value = newOnlineStatus;
    sessionStorage.setItem("onlineStatus", newOnlineStatus);
    ElMessage.success("修改成功");
  } else ElMessage.error("修改失败");
}

async function queryDiagnosisExist() {
  if (order.value.orderId && order.value.patientId) {
    const res = await orderHasDiagnosis({
      orderId: order.value.orderId,
      patientId: order.value.patientId,
    });
    diagnosisExist.value = res.data && typeof res.data.exist === "boolean" ? res.data.exist : false;
  } else {
    diagnosisExist.value = true;
  }
}

// 诊断提交成功后停止计时
async function onDiagnosisSubmitted() {
  // 诊断提交成功后，从后端刷新一次处方结束时间
  if (order.value && order.value.orderId) {
    await syncPrescriptionTimesFromServer(order.value.orderId, order.value.doctorCode || sessionStorage.getItem("doctorNo"));
  }
  queryDiagnosisExist();
}

onMounted(async () => {
  await getHlwDoctorDetail();
  getConsultOrderList();
  TUIStore.watch(StoreName.CHAT, {
    messageList: handleGlobalVideoMessageListUpdated,
  });
});

onUnmounted(() => {
  TUIStore.unwatch(StoreName.CHAT, {
    messageList: handleGlobalVideoMessageListUpdated,
  });
});

watch(
  () => order.value.orderId,
  (n) => {
    if (n) {
      queryDiagnosisExist();
    } else {
      diagnosisExist.value = false;
    }
  },
  { immediate: true }
);

// 当音视频会话状态从非 idle 变为 idle 时，自动关闭视频问诊弹窗
watch(
  () => videoConsultStore.status,
  (newStatus, oldStatus) => {
    if (oldStatus !== "idle" && newStatus === "idle" && videoConsultStore.uiVisible) {
      console.log("[VIDEO][PC] status changed to idle, auto close video dialog");
      videoConsultStore.closeUI();
    }
  }
);
</script>
<style lang="scss">
.flex-container {
  display: flex;
  height: 100%;
  background: #fff;
  overflow: hidden;
}

.conversation {
  width: 300px !important;
  flex-shrink: 0;
  /* 防止缩小 */
  border-right: 1px solid #eee;
  height: 100%;
}

.chat {
  flex-grow: 1;
  /* 占据剩余空间 */
}

.noChatView {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  font-size: 20px;
  width: 100%;
  height: 100%;
}
</style>
