<template>
  <DesktopView :peerId="sign2peerid(targetId)" />
  <div class="container">
    <!-- 连接状态 -->
    <div class="status-bar">
      <div class="peer-info">
        我的ID: <span class="id-text">{{ myId || "等待连接..." }}</span>
        <Button type="primary" @click="copyId" v-if="myId">复制</Button>
        <Button type="link" @click="shareUrl" v-if="myId">分享</Button>
        <span
          v-if="connectedPeerId"
          class="connection-badge"
          :class="{ inbound: isInboundConnected }"
        >
          {{ isInboundConnected ? "被连接" : "已连接" }}:
          <span class="connected-peer">{{ connectedPeerLabel }}</span>
        </span>
      </div>
      <!-- 显示流量 丢包率-->
      <div class="status-info">
        <div class="status-item">
          <span>流量:</span>
          <span>{{ formatSize(transInfo.bytes) }}/s</span>
        </div>
        <div class="status-item">
          <span>包数:</span>
          <span>{{ transInfo.packets }}/s</span>
        </div>
      </div>

      <div class="connect-section">
        <div class="connect-actions">
          <div
            class="connect-item"
            :class="{ disabled: !isConnected, active: isDesktopActive }"
            title="桌面预览"
            @click="requestDesktop"
          >
            <img src="/static/desktop.png" alt="桌面" />
          </div>
          <div
            class="connect-item"
            :class="{ disabled: !isConnected, active: isCallActive }"
            title="语音通话"
            @click="requestCall"
          >
            <img src="/static/phone.png" alt="通话" />
          </div>
          <div
            class="connect-item"
            :class="{ disabled: !isConnected, active: isCameraActive }"
            title="摄像头"
            @click="requestCamera"
          >
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
            >
              <path d="M23 7l-7 5 7 5V7z" />
              <rect x="1" y="5" width="15" height="14" rx="2" />
            </svg>
          </div>
        </div>
        <input
          v-model="targetId"
          :placeholder="!myId ? '请稍后...' : '输入对方ID'"
          :disabled="isConnected || !myId"
        />
        <Button @click="handleConnect" :disabled="!targetId || isConnected">
          {{ isConnected ? "已连接" : "连接" }}
        </Button>
      </div>
    </div>

    <!-- 文件传输区域 -->
    <div class="file-transfer" :class="{ 'mobile-layout': isPhone }">
      <!-- 本地文件区域 -->
      <FileView
        v-if="!isPhone"
        :isRemote="false"
        :selectedFiles="selectedLocalFiles"
      />

      <!-- 传输控制 -->
      <div
        v-if="!isPhone"
        class="transfer-controls"
        :class="{ 'mobile-controls': isPhone }"
      >
        <Clipboard v-if="isConnected" />
        <Button
          type="primary"
          :disabled="!isConnected || selectedLocalFiles.length === 0"
          @click="handleSend"
        >
          发送
        </Button>
        <Button
          type="primary"
          :disabled="!isConnected || selectedRemoteFiles.length === 0"
          @click="handleReceive"
          :loading="receiveLoading"
        >
          接收
        </Button>
      </div>

      <!-- 远程文件区域 -->
      <FileView :isRemote="true" :selectedFiles="selectedRemoteFiles" />
    </div>
  </div>
  <FileTransferView />
</template>

<script setup lang="ts">
import Clipboard from "./item/clipboard.vue";
import { ref, onMounted } from "vue";
import { peer } from "./utils/peer";
import FileView from "./item/fileView.vue";
import { notification } from "ant-design-vue";
import { fileMgrInstance, type FileData } from "./utils/fileMgr";
import { Button } from "ant-design-vue";
import DesktopView from "./item/desptopView.vue";
import {
  formatSize,
  getUrlParam,
  localCurrentFile,
  remoteCurrentFile,
  sign2peerid,
} from "./utils/common";
import FileTransferView from "./item/fileTranserView.vue";

const isPhone = ref(false);
const receiveLoading = ref(false);
const myId = ref("");
const targetId = ref("");
const connectedPeerId = ref("");
const connectedPeerLabel = ref("");
const isInboundConnected = ref(false);
const isConnected = ref(false);
const isDesktopActive = ref(false);
const isCallActive = ref(false);
const isCameraActive = ref(false);
// 文件系统相关
const selectedLocalFiles = ref<string[]>([]);
const selectedRemoteFiles = ref<string[]>([]);
//根据文档宽度
onMounted(() => {
  isPhone.value = document.body.clientWidth < 768;
});

const requestDesktop = () => {
  if (!isConnected.value) return;
  if (isDesktopActive.value) {
    peer.endMedia(sign2peerid(targetId.value), "desktop");
    return;
  }
  peer.requestDesktop(targetId.value);
};
const requestCall = () => {
  if (!isConnected.value) return;
  if (isCallActive.value) {
    peer.endMedia(sign2peerid(targetId.value), "call");
    return;
  }
  peer.requestCall(targetId.value);
};
const requestCamera = () => {
  if (!isConnected.value) return;
  if (isCameraActive.value) {
    peer.endMedia(sign2peerid(targetId.value), "camera");
    return;
  }
  peer.requestCamera(targetId.value);
};

const shareUrl = async () => {
  if (myId.value) {
    const url =
      window.location.origin + window.location.pathname + "?sign=" + myId.value;
    await copyToClipboard(url);
    notification.success({
      message: "链接已复制",
      description: "已成功复制到剪贴板",
    });
  }
};

// 复制ID
const copyId = async () => {
  if (myId.value) {
    try {
      await copyToClipboard(myId.value);
      notification.success({
        message: "ID已复制",
        description: "已成功复制到剪贴板",
      });
    } catch (error) {
      notification.error({
        message: "复制失败",
        icon: "error",
      });
    }
  }
};
//复制到剪贴板
const copyToClipboard = async (text: string) => {
  await navigator.clipboard.writeText(text);
};

// 连接处理
const handleConnect = () => {
  if (!targetId.value) return;
  peer.connect(targetId.value);
};

const updateConnectedPeer = (peerId: string, inbound: boolean) => {
  connectedPeerId.value = peerId;
  connectedPeerLabel.value = inbound ? `${peerId.slice(0, 8)}...` : targetId.value;
  isInboundConnected.value = inbound;
  isConnected.value = !inbound;
};

const clearConnectedPeer = (peerId?: string) => {
  if (peerId && connectedPeerId.value && connectedPeerId.value !== peerId) return;
  connectedPeerId.value = "";
  connectedPeerLabel.value = "";
  isInboundConnected.value = false;
  isConnected.value = false;
};

const isActivePeer = (peerId: string) => {
  const targetPeerId = targetId.value ? sign2peerid(targetId.value) : "";
  return peerId === connectedPeerId.value || peerId === targetPeerId;
};
let lastBytes = 0;
let lastPackets = 0;
const transInfo = ref({
  bytes: 0,
  packets: 0,
});
const checkBytes = () => {
  transInfo.value.bytes = peer.transbytesNum - lastBytes;
  transInfo.value.packets = peer.transpackNum - lastPackets;
  lastBytes = peer.transbytesNum;
  lastPackets = peer.transpackNum;
  setTimeout(() => {
    checkBytes();
  }, 1000);
};
const handleSend = async () => {
  notification.info({
    message: "未完成",
    description: "开发中...",
  });
};
const handleReceive = async () => {
  receiveLoading.value = true;
  const rootFile = await fileMgrInstance.getRootFile();
  console.log(localCurrentFile.value.path);
  try {
    let getFileHandles: Promise<FileData | FileData[]>[] = [];
    selectedRemoteFiles.value.forEach((filepath) => {
      getFileHandles.push(
        fileMgrInstance.remoteRootFile
          .getFileInfo(filepath)
          .getFile(
            false,
            localCurrentFile.value.path.replace(rootFile.path, ""),
            remoteCurrentFile.value.path
          )
      );
    });
    await Promise.all(getFileHandles);
  } catch (err) {
    notification.error({
      message: "接收文件失败",
    });
  }
  receiveLoading.value = false;

  await localCurrentFile.value.loadLocalDirectory();
};
// 事件监听
onMounted(() => {
  peer.init();
  peer.on("open", ((event: CustomEvent) => {
    myId.value = event.detail;
    const sign = getUrlParam("sign");
    if (sign) {
      targetId.value = sign;
      handleConnect();
    }
  }) as EventListener);

  peer.on("connection-open", ((event: CustomEvent) => {
    if (event.detail.peer == peer.remoteConnection?.peer) {
      checkBytes();
      updateConnectedPeer(event.detail.peer, false);
      fileMgrInstance.remoteRootFile.loadLocalDirectory();
      notification.success({
        message: "连接成功",
      });
    } else {
      updateConnectedPeer(event.detail.peer, true);
      notification.success({
        message: "出现新的连接",
      });
    }
  }) as EventListener);

  peer.on("peer-disconnected", ((event: CustomEvent) => {
    clearConnectedPeer(event.detail.peer);
    isDesktopActive.value = false;
    isCallActive.value = false;
    isCameraActive.value = false;
    notification.error({
      message: event.detail.peer + "连接已断开",
    });
  }) as EventListener);

  peer.on("error", ((event: CustomEvent) => {
    notification.error({
      message: "发生错误",
    });
    console.error("连接错误:", event.detail);
  }) as EventListener);

  peer.on("stream", ((event: CustomEvent) => {
    if (!isActivePeer(event.detail.peerId)) return;
    if (event.detail.type === "desktop") {
      isDesktopActive.value = true;
    } else if (event.detail.type === "call") {
      isCallActive.value = true;
    } else if (event.detail.type === "camera") {
      isCameraActive.value = true;
    }
  }) as EventListener);

  peer.on("desktop-started", ((event: CustomEvent) => {
    if (isActivePeer(event.detail.peerId)) {
      isDesktopActive.value = true;
    }
  }) as EventListener);

  peer.on("call-started", ((event: CustomEvent) => {
    if (isActivePeer(event.detail.peerId)) {
      isCallActive.value = true;
    }
  }) as EventListener);

  peer.on("camera-started", ((event: CustomEvent) => {
    if (isActivePeer(event.detail.peerId)) {
      isCameraActive.value = true;
    }
  }) as EventListener);

  peer.on("media-ended", ((event: CustomEvent) => {
    if (!isActivePeer(event.detail.peerId)) return;
    if (event.detail.type === "desktop") {
      isDesktopActive.value = false;
    } else if (event.detail.type === "call") {
      isCallActive.value = false;
    } else if (event.detail.type === "camera") {
      isCameraActive.value = false;
    }
  }) as EventListener);
});

</script>

<style scoped>
.container {
  padding: 20px;
  display: flex;
  flex-direction: column;
  height: calc(100vh - 75px);
  gap: 20px;
}

.status-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  background: #f5f5f5;
  border-radius: 8px;
}

.peer-info {
  display: flex;
  align-items: center;
  gap: 10px;
}

.connection-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border: 1px solid #95de64;
  border-radius: 999px;
  background: #f6ffed;
  color: #389e0d;
  font-size: 12px;
  white-space: nowrap;
}

.connection-badge.inbound {
  border-color: #91caff;
  background: #e6f4ff;
  color: #0958d9;
}

.connected-peer {
  font-family: monospace;
}

.connect-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 30px;
  height: 30px;
  background: #dff1ff;
  border-radius: 8px;
  cursor: pointer;
  border: 1px solid #82c7fb;
}
.connect-item:hover {
  background: #cae5f9;
}
.connect-item.active {
  background: #b7eb8f;
  border-color: #52c41a;
}
.connect-item.active:hover {
  background: #95de64;
}
.connect-item.disabled {
  background: #f0f0f0;
  border-color: #d9d9d9;
  cursor: not-allowed;
  opacity: 0.55;
}
.connect-item.disabled:hover {
  background: #f0f0f0;
}
.connect-item.disabled img {
  filter: grayscale(1);
}
.connect-item img {
  width: 100%;
  height: 100%;
}

.connect-item svg {
  width: 22px;
  height: 22px;
  margin: auto;
  color: #1677ff;
}

.connect-actions,
.connect-section {
  display: flex;
  gap: 10px;
}

.file-transfer {
  display: flex;
  flex: 1;
  gap: 20px;
  min-height: 0;
}

.file-transfer.mobile-layout {
  flex-direction: column;
}

.file-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  border: 1px solid #ddd;
  border-radius: 8px;
  overflow: hidden;
}

.panel-header {
  padding: 10px;
  background: #f5f5f5;
  border-bottom: 1px solid #ddd;
}

.path-nav {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 5px;
}

.file-list {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
}

.file-item {
  display: flex;
  align-items: center;
  padding: 8px;
  cursor: pointer;
  border-radius: 4px;
  gap: 10px;
}

.file-item:hover {
  background: #f5f5f5;
}

.file-item.selected {
  background: #e3f2fd;
}

.file-icon {
  font-size: 24px;
}

.file-info {
  flex: 1;
}

.file-name {
  font-weight: 500;
}

.file-meta {
  font-size: 12px;
  color: #666;
}

.panel-footer {
  padding: 10px;
  background: #f5f5f5;
  border-top: 1px solid #ddd;
  display: flex;
  gap: 10px;
}

.transfer-controls {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
}

.transfer-progress {
  padding: 10px;
  background: #f5f5f5;
  border-radius: 8px;
}

.progress-info {
  display: flex;
  justify-content: space-between;
  margin-bottom: 5px;
}

.progress-bar {
  height: 4px;
  background: #ddd;
  border-radius: 2px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: #007aff;
  transition: width 0.3s ease;
}

input {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

input:disabled {
  background: #f5f5f5;
}

.id-text {
  font-weight: bold;
  color: #007aff;
}

/* 移动端适配样式 */
@media screen and (max-width: 768px) {
  .status-bar {
    flex-direction: column;
    gap: 10px;
  }

  .connect-section {
    width: 100%;
  }

  .connect-section input {
    flex: 1;
  }

  .status-info {
    width: 100%;
    display: flex;
    justify-content: space-around;
  }
}
</style>
