<template>
  <div
    v-if="visible"
    class="vc-overlay"
    :class="{ 'vc-overlay--mini': isMinimized }"
    :style="overlayStyle"
  >
    <div
      class="video-shell"
      :class="{ 'is-minimized': isMinimized }"
      @mousedown="onMiniMouseDown"
    >
      <div class="video-stage">
        <!-- 远端/本地视频：通过 class 控制主画面 / 小窗 -->
        <video
          id="mrtc-remote-video"
          class="video-element"
          autoplay
          playsinline
          disablePictureInPicture
          controlsList="nodownload nofullscreen noremoteplayback"
          :class="remoteVideoClass"
          @click="onVideoClick('remote')"
        ></video>
        <video
          id="mrtc-local-video"
          class="video-element"
          autoplay
          playsinline
          muted
          disablePictureInPicture
          controlsList="nodownload nofullscreen noremoteplayback"
          :class="localVideoClass"
          @click="onVideoClick('local')"
        ></video>
        <audio id="mrtc-remote-audio" autoplay></audio>
        <input id="mrtc-local-stream-id" type="hidden" />
        <input id="mrtc-remote-stream-id" type="hidden" />
        <input id="mrtc-remote-feed-id" type="hidden" />

        <!-- 顶部信息栏：未接通展示患者信息，接通展示通话时长 -->
        <div class="top-bar" v-if="!isMinimized">
          <div v-if="callStatus === 'calling'" class="top-info">
            <div class="user-info">
              <div class="user-name">{{ patientName }}</div>
              <div class="call-tip">等待对方接受邀请...</div>
            </div>
          </div>
          <div v-else-if="callStatus === 'connected'" class="top-info connected">
            <div class="timer">{{ formattedTime }}</div>
          </div>
          <button
            v-if="callStatus !== 'idle'"
            class="mini-btn"
            type="button"
            @click="toggleMinimize"
          >
            <svg viewBox="0 0 24 24" width="20" height="20">
              <polyline
                points="4 14 10 14 10 20"
                stroke="white"
                stroke-width="2"
                fill="none"
              />
              <polyline
                points="20 10 14 10 14 4"
                stroke="white"
                stroke-width="2"
                fill="none"
              />
            </svg>
          </button>
        </div>

        <!-- 底部渐变遮罩 + 状态提示（非最小化） -->
        <div class="bottom-overlay" v-if="!isMinimized && callStatus !== 'idle'">
          <span class="status-text">{{ statusText }}</span>
        </div>

        <!-- 控制栏（模拟 demo 的圆形按钮样式） -->
        <div class="controls-bar" v-if="!isMinimized && callStatus !== 'idle'">
          <button class="circle-btn" type="button" @click="onToggleAudio">
            <!-- 开麦 / 静音图标 -->
            <svg
              v-if="store.localAudioEnabled"
              width="24"
              height="24"
              viewBox="0 0 24 24"
              stroke="currentColor"
              stroke-width="2"
              fill="none"
            >
              <path
                d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"
              ></path>
              <path d="M19 10v2a7 7 0 0 1-14 0v-2"></path>
              <line x1="12" y1="19" x2="12" y2="23"></line>
              <line x1="8" y1="23" x2="16" y2="23"></line>
            </svg>
            <svg
              v-else
              width="24"
              height="24"
              viewBox="0 0 24 24"
              stroke="currentColor"
              stroke-width="2"
              fill="none"
            >
              <line x1="1" y1="1" x2="23" y2="23"></line>
              <path
                d="M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6"
              ></path>
              <path
                d="M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23"
              ></path>
            </svg>
          </button>

          <button class="circle-btn hangup" type="button" @click="onHangup">
            <svg
              width="32"
              height="32"
              viewBox="0 0 24 24"
              fill="white"
            >
              <path
                d="M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08c-.18-.17-.29-.42-.29-.7 0-.28.11-.53.29-.71C3.34 8.36 7.46 6 12 6s8.66 2.36 11.71 5.67c.18.18.29.43.29.71 0 .28-.11.53-.29.71l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28-.79-.74-1.69-1.36-2.67-1.85-.33-.16-.56-.5-.56-.9v-3.1C15.15 9.25 13.6 9 12 9z"
              ></path>
            </svg>
          </button>

          <button class="circle-btn" type="button" @click="onToggleVideo">
            <svg
              v-if="store.localVideoEnabled"
              width="24"
              height="24"
              viewBox="0 0 24 24"
              stroke="currentColor"
              stroke-width="2"
              fill="none"
            >
              <path d="M23 7l-7 5 7 5V7z"></path>
              <rect
                x="1"
                y="5"
                width="15"
                height="14"
                rx="2"
                ry="2"
              ></rect>
            </svg>
            <svg
              v-else
              width="24"
              height="24"
              viewBox="0 0 24 24"
              stroke="currentColor"
              stroke-width="2"
              fill="none"
            >
              <line x1="1" y1="1" x2="23" y2="23"></line>
              <path
                d="M21 21l-2-2m-2 5l-4-2H5a2 2 0 0 1-2-2V7c0-1.1.9-2 2-2h2"
              ></path>
            </svg>
          </button>
        </div>

        <!-- 未开始/已结束占位 -->
        <div class="idle-mask" v-if="callStatus === 'idle'">
          <span>当前没有进行中的视频问诊</span>
        </div>

        <!-- 悬浮小窗下的挂断 / 放大控制 -->
        <div
          v-if="isMinimized && callStatus !== 'idle'"
          class="mini-controls"
        >
          <button
            class="mini-btn-circle"
            type="button"
            @click.stop="toggleMinimize"
            title="放大"
          >
            <svg
              width="16"
              height="16"
              viewBox="0 0 24 24"
              stroke="white"
              stroke-width="2"
              fill="none"
            >
              <polyline points="15 3 21 3 21 9"></polyline>
              <polyline points="9 21 3 21 3 15"></polyline>
              <line x1="21" y1="3" x2="14" y2="10"></line>
              <line x1="3" y1="21" x2="10" y2="14"></line>
            </svg>
          </button>
          <button
            class="mini-btn-circle mini-btn-red"
            type="button"
            @click.stop="onHangup"
            title="挂断"
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="white">
              <path
                d="M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08c-.18-.17-.29-.42-.29-.7 0-.28.11-.53.29-.71C3.34 8.36 7.46 6 12 6s8.66 2.36 11.71 5.67c.18.18.29.43.29.71 0 .28-.11.53-.29.71l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28-.79-.74-1.69-1.36-2.67-1.85-.33-.16-.56-.5-.56-.9v-3.1C15.15 9.25 13.6 9 12 9z"
              ></path>
            </svg>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, watch, ref, onUnmounted } from "vue";
import { useVideoConsultStore } from "@/store/video-consult";

const props = defineProps({
  visible: { type: Boolean, default: false },
  order: { type: Object, default: () => ({}) },
});

const emits = defineEmits(["close"]);

const store = useVideoConsultStore();

// 悬浮小窗尺寸（最大宽高，用于同比例缩放）
const MINI_MAX_WIDTH = 360;
const MINI_MAX_HEIGHT = 210;

// UI 状态
const isMinimized = ref(false);
const isSwapped = ref(false);
const callSeconds = ref(0);
let timer = null;

// 悬浮小窗位置（左上角坐标）
const miniLeft = ref(0);
const miniTop = ref(0);
const miniWidth = ref(MINI_MAX_WIDTH);
const miniHeight = ref(MINI_MAX_HEIGHT);
const isDragging = ref(false);
let dragStartX = 0;
let dragStartY = 0;
let dragStartLeft = 0;
let dragStartTop = 0;

// 远端是否已接入（用于区分“未接通/已接通”）
const hasRemote = computed(
  () => Array.isArray(store.remoteSids) && store.remoteSids.length > 0
);

// idle | calling | connected
const callStatus = computed(() => {
  if (store.status === "idle") return "idle";
  if (!hasRemote.value) return "calling";
  return "connected";
});

const statusText = computed(() => {
  if (store.status === "connecting") return "正在建立音视频通道...";
  if (store.status === "inRoom" && !hasRemote.value) return "已建立通道，等待患者加入...";
  if (store.status === "inRoom" && hasRemote.value) return "视频问诊通话中";
  if (store.status === "error") return store.errorMessage || "视频问诊异常";
  return "未开始视频问诊";
});

const patientName = computed(
  () => (props.order && props.order.patientName) || "患者"
);

// 覆盖层样式：非最小化时全屏，最小化时仅占小窗区域
const overlayStyle = computed(() => {
  if (!isMinimized.value) {
    return {};
  }
  return {
    top: miniTop.value + "px",
    left: miniLeft.value + "px",
    width: miniWidth.value + "px",
    height: miniHeight.value + "px",
    right: "auto",
    bottom: "auto",
  };
});

const formattedTime = computed(() => {
  const m = String(Math.floor(callSeconds.value / 60)).padStart(2, "0");
  const s = String(callSeconds.value % 60).padStart(2, "0");
  return `${m}:${s}`;
});

// 本地/远端主画面 & 小窗逻辑
const localIsMain = computed(() => {
  if (callStatus.value === "calling") return true;
  if (callStatus.value !== "connected" || !hasRemote.value) return true;
  return isSwapped.value;
});

const remoteIsMain = computed(
  () => callStatus.value === "connected" && hasRemote.value && !isSwapped.value
);

const localIsPip = computed(
  () =>
    callStatus.value === "connected" && hasRemote.value && !localIsMain.value
);

const remoteIsPip = computed(
  () =>
    callStatus.value === "connected" && hasRemote.value && !remoteIsMain.value
);

// 小窗只展示“主画面”：谁是主画面，就在小窗展示谁
const localVideoClass = computed(() => {
  const showAsMain = isMinimized.value ? localIsMain.value : localIsMain.value;
  const showAsPip = !isMinimized.value && localIsPip.value;
  return {
    "video-main": showAsMain,
    "video-pip": showAsPip,
    "video-hidden": (!showAsMain && !showAsPip) || callStatus.value === "idle",
  };
});

const remoteVideoClass = computed(() => {
  const showAsMain = isMinimized.value ? remoteIsMain.value : remoteIsMain.value;
  const showAsPip = !isMinimized.value && remoteIsPip.value;
  const hiddenByState = callStatus.value !== "connected" || !hasRemote.value;
  return {
    "video-main": showAsMain && !hiddenByState,
    "video-pip": showAsPip && !hiddenByState,
    "video-hidden": !showAsMain && !showAsPip || hiddenByState,
  };
});

function handleClose() {
  emits("close");
}

async function onHangup() {
  await store.leaveRoom();
}

function onToggleAudio() {
  store.toggleAudio();
}

function onToggleVideo() {
  store.toggleVideo();
}

function toggleMinimize() {
  if (callStatus.value === "idle") return;
  if (!isMinimized.value) {
    // 进入悬浮模式时，先按当前主画面的比例计算小窗宽高，再初始化位置到底部右侧
    updateMiniSize();
    const vw = window.innerWidth || 0;
    const vh = window.innerHeight || 0;
    const padding = 20;
    miniLeft.value = Math.max(padding, vw - miniWidth.value - padding);
    miniTop.value = Math.max(padding, vh - miniHeight.value - padding);
  }
  isMinimized.value = !isMinimized.value;
}

function onVideoClick(which) {
  // 悬浮小窗模式下不做画面切换
  if (isMinimized.value) return;
  if (callStatus.value !== "connected" || !hasRemote.value) return;
  if (which === "local" && !localIsPip.value) return;
  if (which === "remote" && !remoteIsPip.value) return;
  isSwapped.value = !isSwapped.value;
}

function startTimer() {
  if (timer) clearInterval(timer);
  timer = setInterval(() => {
    callSeconds.value += 1;
  }, 1000);
}

function stopTimer() {
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
}

// 通话接通时开始计时，结束/断开时停止
watch(
  () => callStatus.value,
  (val, oldVal) => {
    if (val === "connected" && oldVal !== "connected") {
      callSeconds.value = 0;
      startTimer();
      if (isMinimized.value) {
        // 连接成功且当前是小窗时，按远端画面比例更新小窗大小
        setTimeout(updateMiniSize, 0);
      }
    } else if (oldVal === "connected" && val !== "connected") {
      stopTimer();
    }
  }
);

onUnmounted(() => {
  stopTimer();
  window.removeEventListener("mousemove", onMiniMouseMove);
  window.removeEventListener("mouseup", onMiniMouseUp);
});

// 通话结束（status 回到 idle）时自动关闭容器
watch(
  () => store.status,
  (val) => {
    if (val === "idle" && props.visible) {
      isMinimized.value = false;
      isSwapped.value = false;
      emits("close");
    }
  }
);

// 弹窗打开时绑定 DOM ID 并尝试发起/恢复视频
watch(
  () => props.visible,
  async (val) => {
    if (val) {
      store.setDomIds({
        localVideoId: "mrtc-local-video",
        localStreamIdInputId: "mrtc-local-stream-id",
        remoteVideoId: "mrtc-remote-video",
        remoteAudioId: "mrtc-remote-audio",
        remoteStreamIdInputId: "mrtc-remote-stream-id",
        remoteFeedIdInputId: "mrtc-remote-feed-id",
      });
      if (store.status === "idle" && props.order && props.order.orderId) {
        await store.start(props.order);
      }
    }
  }
);

function onMiniMouseDown(e) {
  if (!isMinimized.value) return;
  // 点击小窗内的控制按钮时不触发拖拽
  if (e.target && e.target.closest && e.target.closest(".mini-controls")) {
    return;
  }
  isDragging.value = true;
  dragStartX = e.clientX;
  dragStartY = e.clientY;
  dragStartLeft = miniLeft.value;
  dragStartTop = miniTop.value;
  window.addEventListener("mousemove", onMiniMouseMove);
  window.addEventListener("mouseup", onMiniMouseUp);
}

function onMiniMouseMove(e) {
  if (!isDragging.value) return;
  const dx = e.clientX - dragStartX;
  const dy = e.clientY - dragStartY;
  const vw = window.innerWidth || 0;
  const vh = window.innerHeight || 0;
  const padding = 10;
  let nextLeft = dragStartLeft + dx;
  let nextTop = dragStartTop + dy;
  nextLeft = Math.min(Math.max(padding, nextLeft), vw - miniWidth.value - padding);
  nextTop = Math.min(Math.max(padding, nextTop), vh - miniHeight.value - padding);
  miniLeft.value = nextLeft;
  miniTop.value = nextTop;
}

function onMiniMouseUp() {
  if (!isDragging.value) return;
  isDragging.value = false;
  window.removeEventListener("mousemove", onMiniMouseMove);
  window.removeEventListener("mouseup", onMiniMouseUp);
}

// 根据当前主画面的视频尺寸，按比例缩放小窗宽高
function updateMiniSize() {
  // 仅在浏览器环境下尝试访问 DOM
  if (typeof window === "undefined") return;
  // 确定当前主画面是本地还是远端
  let mainId = "";
  if (callStatus.value === "calling" || (!hasRemote.value && callStatus.value !== "idle")) {
    mainId = "mrtc-local-video";
  } else if (hasRemote.value) {
    mainId = remoteIsMain.value ? "mrtc-remote-video" : "mrtc-local-video";
  }
  if (!mainId) return;
  const el = document.getElementById(mainId);
  if (!el || !el.videoWidth || !el.videoHeight) {
    miniWidth.value = MINI_MAX_WIDTH;
    miniHeight.value = MINI_MAX_HEIGHT;
    return;
  }
  const vw = el.videoWidth;
  const vh = el.videoHeight;
  if (!vw || !vh) {
    miniWidth.value = MINI_MAX_WIDTH;
    miniHeight.value = MINI_MAX_HEIGHT;
    return;
  }
  const ratio = vw / vh;
  let targetW = MINI_MAX_WIDTH;
  let targetH = targetW / ratio;
  if (targetH > MINI_MAX_HEIGHT) {
    targetH = MINI_MAX_HEIGHT;
    targetW = targetH * ratio;
  }
  miniWidth.value = Math.max(160, Math.round(targetW));
  miniHeight.value = Math.max(120, Math.round(targetH));
}
</script>

<style scoped>
.vc-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  z-index: 2000;
  display: flex;
  justify-content: center;
  align-items: center;
}

.vc-overlay--mini {
  background: transparent;
}

.video-shell {
  position: relative;
  width: 900px;
  max-width: 100%;
  height: 560px;
  max-height: calc(100% - 80px);
  background: #2c2f38;
  border-radius: 16px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.video-shell.is-minimized {
  width: 100%;
  height: 100%;
  background: #222;
  border-radius: 16px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}

.video-stage {
  position: relative;
  flex: 1;
  background: #000;
  overflow: hidden;
}

.video-element {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}

.video-hidden {
  display: none;
}

.video-main {
  z-index: 1;
}

.video-pip {
  z-index: 2;
  width: 200px;
  height: 130px;
  top: 16px;
  left: 16px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6);
  cursor: pointer;
}

.top-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 12px 16px;
  z-index: 3;
  pointer-events: none;
}

.top-info {
  margin-right: auto;
  color: #fff;
  pointer-events: auto;
}

.top-info.connected {
  margin-right: 0;
}

.user-info {
  text-align: left;
}

.user-name {
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 4px;
}

.call-tip {
  font-size: 14px;
  opacity: 0.85;
}

.timer {
  color: #fff;
  font-size: 16px;
  font-weight: 500;
}

.mini-btn {
  pointer-events: auto;
  background: rgba(0, 0, 0, 0.4);
  border: none;
  border-radius: 8px;
  padding: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.bottom-overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 8px 16px 12px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);
  color: #fff;
  font-size: 12px;
  z-index: 3;
  display: flex;
  align-items: flex-end;
}

.status-text {
  opacity: 0.9;
}

.idle-mask {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #999;
  font-size: 14px;
  z-index: 4;
  background: rgba(0, 0, 0, 0.45);
}

.mrtc-video-footer {
  display: none;
}

/* 控制栏（仿 demo） */
.controls-bar {
  height: 90px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.9), transparent);
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 30px;
  position: absolute;
  bottom: 0;
  width: 100%;
  z-index: 30;
}

.circle-btn {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
  border: none;
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s;
}

.circle-btn:hover {
  background: rgba(255, 255, 255, 0.3);
}

.circle-btn.hangup {
  background: #ff4d4f;
  width: 60px;
  height: 60px;
}

.circle-btn.hangup:hover {
  background: #ff7875;
}

/* 悬浮小窗控制按钮 */
.mini-controls {
  position: absolute;
  right: 8px;
  bottom: 8px;
  display: flex;
  gap: 8px;
  z-index: 40;
}

.mini-btn-circle {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mini-btn-red {
  background: #ff4d4f;
}
</style>
