<template>
  <div
    class="desktop-view-wrapper"
    :class="{
      'is-collapsed': isCollapsed,
      'has-stream': hasMedia,
      'has-call-only': !!callStream && !desktopStream,
    }"
  >
    <div class="collapse-header" v-if="hasMedia" @click="toggleCollapse">
      <span>{{ headerTitle }}{{ isCollapsed ? "(已收起)" : "" }}</span>
      <a-button type="link">
        <template #icon>
          <UpOutlined v-if="!isCollapsed" />
          <DownOutlined v-else />
        </template>
      </a-button>
    </div>
    <div
      v-if="desktopStream"
      class="desktop-view"
      :class="{ 'is-fullscreen': isFullscreen }"
    >
      <div class="video-container" ref="videoContainer">
        <video ref="videoRef" autoplay playsinline></video>
        <div class="controls">
          <a-button
            type="primary"
            ghost
            @click="toggleFullscreen"
          >
            {{ isFullscreen ? "退出全屏" : "全屏" }}
          </a-button>
          <a-button danger ghost @click="endDesktop">结束桌面</a-button>
        </div>
      </div>
    </div>
    <div v-if="callStream" class="call-view">
      <audio ref="audioRef" autoplay playsinline></audio>
      <div class="call-info">
        <PhoneOutlined />
        <span>语音通话中</span>
      </div>
      <div class="call-controls">
        <a-button ghost @click="toggleCallMuted">
          {{ isCallMuted ? "取消静音" : "静音" }}
        </a-button>
        <a-button danger ghost @click="endCall">结束通话</a-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, ref, onMounted, onUnmounted } from "vue";
import { peer } from "../utils/peer";
import { message } from "ant-design-vue";
import { UpOutlined, DownOutlined, PhoneOutlined } from "@ant-design/icons-vue";

const props = defineProps<{
  peerId: string;
}>();

interface StreamEvent extends CustomEvent {
  detail: {
    stream: MediaStream;
    type: "desktop" | "call";
    peerId: string;
  };
}

interface MediaEndedEvent extends CustomEvent {
  detail: {
    type: "desktop" | "call";
    peerId: string;
  };
}

const videoRef = ref<HTMLVideoElement | null>(null);
const audioRef = ref<HTMLAudioElement | null>(null);
const videoContainer = ref<HTMLElement | null>(null);
const desktopStream = ref<MediaStream | null>(null);
const callStream = ref<MediaStream | null>(null);
const isFullscreen = ref(false);
const isCollapsed = ref(false);
const isCallMuted = ref(false);

const hasMedia = computed(() => !!desktopStream.value || !!callStream.value);
const headerTitle = computed(() => {
  if (desktopStream.value && callStream.value) return "远程桌面与通话";
  if (desktopStream.value) return "远程桌面";
  return "语音通话";
});

// 切换收起/展开状态
const toggleCollapse = () => {
  isCollapsed.value = !isCollapsed.value;
};

// 处理远程流
const handleStream = async (event: StreamEvent) => {
  const { stream: remoteStream, type } = event.detail;
  if (props.peerId !== event.detail.peerId) return;
  if (type === "desktop") {
    desktopStream.value = remoteStream;
    isCollapsed.value = false; // 收到流时自动展开
    await nextTick();
    if (videoRef.value) {
      videoRef.value.srcObject = remoteStream;
    }
  } else if (type === "call") {
    callStream.value = remoteStream;
    isCollapsed.value = false;
    await nextTick();
    if (audioRef.value) {
      audioRef.value.srcObject = remoteStream;
      audioRef.value.muted = isCallMuted.value;
      audioRef.value.play().catch(() => {
        message.warning("浏览器阻止了自动播放，请点击通话区域恢复声音");
      });
    }
  }
};

// 处理媒体结束
const handleMediaEnded = (event: MediaEndedEvent) => {
  const { type } = event.detail;
  if (props.peerId !== event.detail.peerId) return;
  if (type === "desktop") {
    desktopStream.value = null;
    if (videoRef.value) {
      videoRef.value.srcObject = null;
    }
    message.info("远程桌面共享已结束");
  } else if (type === "call") {
    callStream.value = null;
    if (audioRef.value) {
      audioRef.value.srcObject = null;
    }
    message.info("语音通话已结束");
  }
};

const endDesktop = () => {
  peer.endMedia(props.peerId, "desktop");
};

const endCall = () => {
  peer.endMedia(props.peerId, "call");
};

const toggleCallMuted = () => {
  isCallMuted.value = !isCallMuted.value;
  if (audioRef.value) {
    audioRef.value.muted = isCallMuted.value;
  }
};

// 切换全屏
const toggleFullscreen = async () => {
  if (!videoContainer.value) return;

  try {
    if (!isFullscreen.value) {
      if (videoContainer.value.requestFullscreen) {
        await videoContainer.value.requestFullscreen();
      }
    } else {
      if (document.exitFullscreen) {
        await document.exitFullscreen();
      }
    }
  } catch (err) {
    message.error("切换全屏失败");
  }
};

// 监听全屏变化
const handleFullscreenChange = () => {
  isFullscreen.value = !!document.fullscreenElement;
};

const streamListener: EventListener = (event) => {
  handleStream(event as StreamEvent);
};
const mediaEndedListener: EventListener = (event) => {
  handleMediaEnded(event as MediaEndedEvent);
};

onMounted(() => {
  peer.on("stream", streamListener);
  peer.on("media-ended", mediaEndedListener);
  document.addEventListener("fullscreenchange", handleFullscreenChange);
});

onUnmounted(() => {
  peer.off("stream", streamListener);
  peer.off("media-ended", mediaEndedListener);
  document.removeEventListener("fullscreenchange", handleFullscreenChange);

  // 清理视频流
  desktopStream.value?.getTracks().forEach((track) => track.stop());
  callStream.value?.getTracks().forEach((track) => track.stop());
});
</script>

<style scoped>
.desktop-view-wrapper {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: #000;
  transition: all 0.3s ease;
  height: 0;
  overflow: hidden;
}

.desktop-view-wrapper.has-stream {
  height: 300px;
}

.desktop-view-wrapper.has-call-only {
  height: 104px;
}

.desktop-view-wrapper.is-collapsed {
  height: 40px !important;
}

.collapse-header {
  height: 40px;
  background: #1a1a1a;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  cursor: pointer;
  user-select: none;
}

.collapse-header:hover {
  background: #2a2a2a;
}

.desktop-view {
  width: 100%;
  height: calc(100% - 40px);
  background: #000;
  position: relative;
}

.video-container {
  width: 100%;
  height: 100%;
  position: relative;
}

video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.controls {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  opacity: 0;
  transition: opacity 0.3s;
  display: flex;
  gap: 10px;
}

.video-container:hover .controls {
  opacity: 1;
}

.is-fullscreen {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
}

.call-view {
  height: 64px;
  padding: 0 16px;
  background: #111;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-top: 1px solid #2a2a2a;
}

.call-info,
.call-controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

:deep(.ant-empty-description) {
  color: #fff;
}

:deep(.anticon) {
  vertical-align: 0;
}
</style>
