<script lang="ts" setup>
import { onMounted, ref, computed, h } from "vue";
import PeerCard from "./PeerCard.vue";
import TransferItem from "./TransferItem.vue";
import {
  NLayout,
  NLayoutHeader,
  NLayoutContent,
  NLayoutSider,
  NSpace,
  NText,
  NEmpty,
  NGrid,
  NGi,
  NMenu,
  NBadge,
  NButton,
  NIcon,
  NDrawer,
  NDrawerContent,
  useDialog,
  NInput,
} from "naive-ui";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import {
  faSatelliteDish,
  faInbox,
  faBars,
  faXmark,
} from "@fortawesome/free-solid-svg-icons";
import { type MenuOption } from "naive-ui";
import { Peer } from "../../bindings/mesh-drop/internal/discovery/models";
import { Transfer } from "../../bindings/mesh-drop/internal/transfer";
import {
  GetPeers,
  GetPeerByIP,
} from "../../bindings/mesh-drop/internal/discovery/service";
import { Events } from "@wailsio/runtime";
import {
  GetTransferList,
  SendFile,
  SendText,
  SendFolder,
} from "../../bindings/mesh-drop/internal/transfer/service";
import { Dialogs, Clipboard } from "@wailsio/runtime";

const peers = ref<Peer[]>([]);
const transferList = ref<Transfer[]>([]);
const activeKey = ref("discover");
const showMobileMenu = ref(false);
const isMobile = ref(false);

// 监听窗口大小变化更新 isMobile
onMounted(() => {
  checkMobile();
  window.addEventListener("resize", checkMobile);
});

const checkMobile = () => {
  isMobile.value = window.innerWidth < 768;
  if (!isMobile.value) showMobileMenu.value = false;
};

// --- 菜单选项 ---
const renderIcon = (icon: any) => {
  return () => h(NIcon, null, { default: () => h(FontAwesomeIcon, { icon }) });
};

const menuOptions = computed<MenuOption[]>(() => [
  {
    label: "Discover",
    key: "discover",
    icon: renderIcon(faSatelliteDish),
  },
  {
    label: () =>
      h(
        "div",
        {
          style:
            "display: flex; align-items: center; justify-content: space-between; width: 100%",
        },
        [
          "Transfers",
          pendingCount.value > 0 ?
            h(NBadge, { value: pendingCount.value, max: 99, type: "error" })
          : null,
        ],
      ),
    key: "transfers",
    icon: renderIcon(faInbox),
  },
]);

// --- 后端集成 ---
onMounted(async () => {
  peers.value = await GetPeers();
});

// --- 事件监听 ---

Events.On("peers:update", (event) => {
  peers.value = event.data;
});

Events.On("transfer:refreshList", async () => {
  transferList.value = await GetTransferList();
});

// --- 计算属性 ---
const pendingCount = computed(() => {
  return transferList.value.filter(
    (t) => t.type === "receive" && t.status === "pending",
  ).length;
});

// --- 操作 ---

const handleSendFile = async (ip: string) => {
  try {
    const filePath = await Dialogs.OpenFile({
      Title: "Select file to send",
    });
    if (!filePath) return;
    const peer = await GetPeerByIP(ip);
    if (!peer) return;
    await SendFile(peer, ip, filePath);
    activeKey.value = "transfers";
  } catch (e: any) {
    console.error(e);
    alert("Failed to send file: " + e);
  }
};

const handleSendFolder = async (ip: string) => {
  const opts: Dialogs.OpenFileDialogOptions = {
    Title: "Select folder to send",
    CanChooseDirectories: true,
    CanChooseFiles: false,
    AllowsMultipleSelection: false,
  };
  const folderPath = await Dialogs.OpenFile(opts);
  if (!folderPath) return;
  const peer = await GetPeerByIP(ip);
  if (!peer) return;
  await SendFolder(peer, ip, folderPath as string);
  activeKey.value = "transfers";
};

const dialog = useDialog();
const handleSendText = (ip: string) => {
  const textContent = ref("");
  const d = dialog.create({
    title: "Send Text",
    content: () =>
      h(NInput, {
        value: textContent.value,
        "onUpdate:value": (v) => (textContent.value = v),
        type: "textarea",
        placeholder: "Type something to send...",
        autosize: { minRows: 3, maxRows: 8 },
      }),
    positiveText: "Send",
    negativeText: "Cancel",
    onPositiveClick: async () => {
      if (!textContent.value) return;
      try {
        const peer = await GetPeerByIP(ip);
        if (!peer) return;
        await SendText(peer, ip, textContent.value);
        activeKey.value = "transfers";
      } catch (e: any) {
        console.error(e);
        alert("Failed to send text: " + e);
      }
    },
  });
};

const handleSendClipboard = async (ip: string) => {
  const text = await Clipboard.Text();
  if (!text) {
    alert("Clipboard is empty");
    return;
  }
  const peer = await GetPeerByIP(ip);
  if (!peer) return;
  await SendText(peer, ip, text);
  activeKey.value = "transfers";
};

const removeTransfer = (id: string) => {
  transferList.value = transferList.value.filter((t) => t.id !== id);
};

const handleMenuUpdate = (key: string) => {
  activeKey.value = key;
  showMobileMenu.value = false;
};
</script>

<template>
  <!-- 小尺寸头部 -->
  <n-layout-header v-if="isMobile" bordered class="mobile-header">
    <n-space
      align="center"
      justify="space-between"
      style="height: 100%; padding: 0 16px">
      <n-text class="logo">Mesh Drop</n-text>
      <n-button
        text
        style="font-size: 24px"
        @click="showMobileMenu = !showMobileMenu">
        <n-icon>
          <FontAwesomeIcon :icon="showMobileMenu ? faXmark : faBars" />
        </n-icon>
      </n-button>
    </n-space>
  </n-layout-header>

  <!-- 小尺寸抽屉菜单 -->
  <n-drawer
    v-model:show="showMobileMenu"
    placement="top"
    height="200"
    v-if="isMobile">
    <n-drawer-content>
      <n-menu
        :value="activeKey"
        :options="menuOptions"
        @update:value="handleMenuUpdate" />
    </n-drawer-content>
  </n-drawer>

  <n-layout
    has-sider
    position="absolute"
    :style="{ top: isMobile ? '64px' : '0' }">
    <!-- 桌面端侧边栏 -->
    <n-layout-sider
      v-if="!isMobile"
      bordered
      width="240"
      content-style="padding: 24px;">
      <div class="desktop-logo">
        <n-text class="logo">Mesh Drop</n-text>
      </div>
      <n-menu
        :value="activeKey"
        :options="menuOptions"
        @update:value="handleMenuUpdate" />
    </n-layout-sider>

    <n-layout-content class="content">
      <div class="content-container">
        <!-- 发现页视图 -->
        <div v-if="activeKey === 'discover'">
          <n-space vertical size="large" v-if="peers.length > 0">
            <n-grid x-gap="16" y-gap="16" cols="1 500:2 700:3">
              <n-gi v-for="peer in peers" :key="peer.id">
                <PeerCard
                  :peer="peer"
                  @sendFile="handleSendFile"
                  @sendFolder="handleSendFolder"
                  @sendText="handleSendText"
                  @sendClipboard="handleSendClipboard" />
              </n-gi>
            </n-grid>
          </n-space>

          <div v-else class="empty-state">
            <n-empty description="Scanning for peers...">
              <template #icon>
                <n-icon class="radar-icon">
                  <FontAwesomeIcon :icon="faSatelliteDish" />
                </n-icon>
              </template>
            </n-empty>
          </div>
        </div>

        <!-- 传输列表视图 -->
        <div v-else-if="activeKey === 'transfers'">
          <div v-if="transferList.length > 0">
            <TransferItem
              v-for="transfer in transferList"
              :key="transfer.id"
              :transfer="transfer" />
          </div>
          <div v-else class="empty-state">
            <n-empty style="user-select: none" description="No transfers yet">
              <template #icon>
                <n-icon>
                  <FontAwesomeIcon :icon="faInbox" />
                </n-icon>
              </template>
            </n-empty>
          </div>
        </div>
      </div>
    </n-layout-content>
  </n-layout>
</template>

<style scoped>
.mobile-header {
  height: 64px;
  z-index: 1000;
}

.desktop-logo {
  margin-bottom: 24px;
  padding-left: 8px;
}

.logo {
  font-size: 1.25rem;
  font-weight: 700;
  color: #38bdf8;
}

.content-container {
  padding: 24px;
}

.empty-state {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 90vh;
}

.radar-icon {
  animation: spin 3s linear infinite;
  color: #38bdf8;
  opacity: 0.5;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
