<script>
  import { onMount } from "svelte";
  import { Tooltip } from "bits-ui";
  import { api } from "./lib/api.js";
  import { chat } from "./lib/chat.svelte.js";
  import { applyAccent, applyTheme, preferredAccent, preferredTheme } from "./lib/theme.js";
  import Toast from "./lib/Toast.svelte";
  import Icon from "./lib/Icon.svelte";
  import ActivitySpine from "./lib/components/ActivitySpine.svelte";
  import ChatPage from "./pages/ChatPage.svelte";
  import TasksPage from "./pages/TasksPage.svelte";
  import AgentsPage from "./pages/AgentsPage.svelte";
  import MemoryPage from "./pages/MemoryPage.svelte";
  import LogsPage from "./pages/LogsPage.svelte";
  import SettingsPage from "./pages/SettingsPage.svelte";
  import OverviewPage from "./pages/OverviewPage.svelte";
  import ToolsPage from "./pages/ToolsPage.svelte";
  import PairingPage from "./pages/PairingPage.svelte";

  const pages = [
    { name: "chat", label: "聊天", description: "与 PicoBot 协作并管理会话" },
    { name: "overview", label: "概览", description: "查看运行状态与系统容量" },
    { name: "tools", label: "工具", description: "浏览工具、Skills 与 MCP 连接" },
    { name: "agents", label: "子代理", description: "查看活动中的子代理与历史运行" },
    { name: "logs", label: "日志", description: "检查实时事件与运行记录" },
    { name: "memory", label: "记忆", description: "查找和维护长期记忆" },
    { name: "tasks", label: "任务", description: "管理定时任务" },
    { name: "settings", label: "配置", description: "管理 Gateway 与 Agent 配置" }
  ];
  const icons = {
    chat: '<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>',
    overview: '<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>',
    tools: '<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>',
    agents: '<rect x="4" y="7" width="16" height="12" rx="2"/><path d="M12 7V4"/><path d="M8 4h8"/><circle cx="9" cy="13" r="1"/><circle cx="15" cy="13" r="1"/>',
    logs: '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="M16 13H8"/><path d="M16 17H8"/><path d="M10 9H8"/>',
    memory: '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/>',
    tasks: '<path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/>',
    settings: '<line x1="21" x2="14" y1="4" y2="4"/><line x1="10" x2="3" y1="4" y2="4"/><line x1="21" x2="12" y1="12" y2="12"/><line x1="8" x2="3" y1="12" y2="12"/><line x1="21" x2="16" y1="20" y2="20"/><line x1="12" x2="3" y1="20" y2="20"/><line x1="14" x2="14" y1="2" y2="6"/><line x1="8" x2="8" y1="10" y2="14"/><line x1="16" x2="16" y1="18" y2="22"/>'
  };
  let current = $state("chat");
  let menuOpen = $state(false);
  let online = $state(false);
  let version = $state("Gateway");
  let theme = $state("dark");
  let authReady = $state(false);
  let authenticated = $state(false);
  let toast = $state();
  const meta = $derived(pages.find((page) => page.name === current) || pages[0]);

  async function health() {
    try {
      const result = await api("/health");
      online = true;
      version = `Gateway v${result.version}`;
    } catch {
      online = false;
    }
  }

  function selectPage(name) {
    current = name;
    menuOpen = false;
  }

  function toggleTheme() {
    theme = theme === "dark" ? "light" : "dark";
    applyTheme(theme);
  }

  async function checkAuth() {
    try {
      const status = await api("/api/auth/status");
      authenticated = status.authenticated || !status.require_pairing;
    } catch {
      authenticated = false;
    } finally {
      authReady = true;
    }
  }

  function paired() {
    authenticated = true;
    health();
  }

  $effect(() => {
    if (authenticated) {
      chat.connect();
    } else {
      chat.disconnect();
    }
  });

  onMount(() => {
    const preferred = preferredTheme();
    const accent = preferredAccent();
    applyTheme(preferred);
    applyAccent(accent);
    theme = preferred;
    checkAuth().then(() => authenticated && health());
    const authRequired = () => (authenticated = false);
    const appearanceChanged = (event) => {
      if (event.detail?.theme === "light" || event.detail?.theme === "dark") theme = event.detail.theme;
    };
    window.addEventListener("picobot-auth-required", authRequired);
    window.addEventListener("picobot-appearance-change", appearanceChanged);
    const timer = setInterval(() => authenticated && health(), 30_000);
    return () => {
      clearInterval(timer);
      window.removeEventListener("picobot-auth-required", authRequired);
      window.removeEventListener("picobot-appearance-change", appearanceChanged);
      chat.disconnect();
    };
  });
</script>

{#if !authReady}
  <main class="pairing-screen"><div class="auth-loading"><span class="pulse"></span>正在检查设备授权…</div></main>
{:else if !authenticated}
  <PairingPage onpaired={paired} />
{:else}
  <Tooltip.Provider delayDuration={350}>
  <div class="shell">
    {#if menuOpen}<button class="nav-scrim" aria-label="关闭导航" onclick={() => (menuOpen = false)}></button>{/if}
    <aside class:open={menuOpen} class="sidebar">
      <div class="brand"><span class="brand-mark"><Icon name="bot" size={22} /></span><div><strong>PicoBot</strong><small>Agent workspace</small></div></div>
      <span class="nav-label">工作区</span>
      <nav aria-label="主导航">
        {#each pages as page}
          <button class:active={current === page.name} aria-current={current === page.name ? "page" : undefined} onclick={() => selectPage(page.name)}>
            <span class="nav-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">{@html icons[page.name]}</svg></span>
            {page.label}
          </button>
        {/each}
      </nav>
      <div class="gateway-status">
        <i class:online></i><div><b>{online ? "Gateway 已连接" : "Gateway 不可用"}</b><small>{version}</small></div>
      </div>
    </aside>
    <main class="app-main">
      <header class="topbar">
        <button class="menu icon-button" aria-label="打开导航" onclick={() => (menuOpen = !menuOpen)}><Icon name="panel" /></button>
        <div class="page-heading"><h1>{meta.label}</h1><p>{meta.description}</p></div>
        <ActivitySpine {version} />
        <button class="theme-toggle" aria-label={theme === "dark" ? "切换到浅色主题" : "切换到深色主题"} onclick={toggleTheme}>
          <Icon name={theme === "dark" ? "sun" : "moon"} /><span>{theme === "dark" ? "浅色" : "深色"}</span>
        </button>
      </header>
      {#if current === "chat"}<ChatPage notify={(text, error) => toast.show(text, error)} />
      {:else if current === "logs"}<LogsPage />
      {:else if current === "memory"}<MemoryPage />
      {:else if current === "tasks"}<TasksPage />
      {:else if current === "settings"}<SettingsPage notify={(text, error) => toast.show(text, error)} />
      {:else if current === "overview"}<OverviewPage />
      {:else if current === "tools"}<ToolsPage notify={(text, error) => toast.show(text, error)} />
      {:else if current === "agents"}<AgentsPage />
      {:else}<div class="empty-card">即将上线</div>{/if}
    </main>
  </div>
  <Toast bind:this={toast} />
  </Tooltip.Provider>
{/if}
