<script>
  import Sidebar from "./components/Sidebar.svelte";
  import Dashboard from "./routes/Dashboard.svelte";
  import Docker from "./routes/Docker.svelte";
  import Gitea from "./routes/Gitea.svelte";
  import Files from "./routes/Files.svelte";
  import Terminal from "./routes/Terminal.svelte";
  import OpenClaw from "./routes/OpenClaw.svelte";
  import Settings from "./routes/Settings.svelte";
  import ChatSummary from "./routes/ChatSummary.svelte";
  import Conversations from "./routes/Conversations.svelte";
  import Security from "./routes/Security.svelte";
  import LiteLLM from "./routes/LiteLLM.svelte";
  import CcConnect from "./routes/CcConnect.svelte";
  import InfoEngine from "./routes/InfoEngine.svelte";
  import OPC from "./routes/OPC.svelte";
  import Transmission from "./routes/Transmission.svelte";
  import Login from "./routes/Login.svelte";
  import { onMount } from "svelte";
  import { getToken, checkAuth, setToken, currentUser, setCurrentUser, getPreferences, savePreferences, tryRefreshSession, logout as logoutSession } from "./lib/api.js";

  const KNOWN_PAGES = new Set([
    "dashboard",
    "docker",
    "gitea",
    "files",
    "terminal",
    "openclaw",
    "chat-digest",
    "conversations",
    "settings",
    "security",
    "litellm",
    "cc-connect",
    "info-engine",
    "opc",
    "transmission",
  ]);

  let page = $state("dashboard");
  let dark = $state(false);
  let sidebarOpen = $state(false);
  let authorized = $state(false);
  let loading = $state(true);
  let userRole = $state("");
  let allowedPages = $state([]);
  let allowedSidebarLinks = $state("*");
  let sidebarOrder = $state(null);
  let orderSaveTimer = null;

  function getRequestedPage() {
    const requestedPage = new URLSearchParams(window.location.search).get("page");
    return KNOWN_PAGES.has(requestedPage) ? requestedPage : null;
  }

  function canOpenPage(pageId) {
    if (!pageId || !KNOWN_PAGES.has(pageId)) return false;
    if (pageId === "settings") return userRole === "admin";
    if (["litellm", "cc-connect", "info-engine"].includes(pageId)) return hasPageAccess("dashboard");
    return hasPageAccess(pageId);
  }

  function syncPageQuery(pageId) {
    const url = new URL(window.location.href);
    if (pageId === "dashboard") url.searchParams.delete("page");
    else url.searchParams.set("page", pageId);
    if (pageId !== "terminal") url.searchParams.delete("host");
    history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`);
  }

  async function fetchUserInfo() {
    try {
      const data = await checkAuth();
      setCurrentUser(data);
      userRole = data.role || "admin";
      allowedPages = data.pages || "*";
      allowedSidebarLinks = data.sidebar_links || "*";
      // Fetch sidebar preferences
      try {
        const prefs = await getPreferences();
        sidebarOrder = prefs.sidebar_order || null;
      } catch {}
    } catch (e) {
      console.error("Failed to fetch user info:", e);
    }
  }

  function handleOrderChange(newOrder) {
    sidebarOrder = newOrder;
    clearTimeout(orderSaveTimer);
    orderSaveTimer = setTimeout(() => {
      savePreferences({ sidebar_order: newOrder }).catch((e) => {
        console.error("Failed to save sidebar order:", e);
      });
    }, 500);
  }

  function hasPageAccess(pageId) {
    if (allowedPages === "*") return true;
    return Array.isArray(allowedPages) && allowedPages.includes(pageId);
  }

  onMount(async () => {
    // Theme init
    if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
      dark = true;
      document.documentElement.classList.add('dark');
    } else {
      dark = false;
      document.documentElement.classList.remove('dark');
    }

    // Try proxy auth first (Authelia forward-auth sets Remote-User header)
    try {
      const proxyRes = await fetch("/api/auth/proxy", { credentials: "same-origin" });
      if (proxyRes.ok) {
        const data = await proxyRes.json();
        setToken(data.access_token);
        authorized = true;
        await fetchUserInfo();
        const requestedPage = getRequestedPage();
        if (canOpenPage(requestedPage)) page = requestedPage;
        loading = false;
        return;
      }
    } catch (e) {
      // Proxy auth not available, fall through to regular auth
    }

    // Regular token auth check — always try refresh to get fresh cookies
    const refreshed = await tryRefreshSession();
    if (!refreshed && !getToken()) {
      loading = false;
      authorized = false;
      return;
    }

    try {
        await fetchUserInfo();
        authorized = true;
        const requestedPage = getRequestedPage();
        if (canOpenPage(requestedPage)) page = requestedPage;
    } catch (e) {
        console.error("Auth check failed:", e);
        setToken("");
        authorized = false;
    } finally {
        loading = false;
    }
  });

  $effect(() => {
    if (!authorized || loading || !canOpenPage(page)) return;
    syncPageQuery(page);
  });

  function toggleTheme() {
    dark = !dark;
    if (dark) {
       document.documentElement.classList.add("dark");
       localStorage.theme = 'dark';
    } else {
       document.documentElement.classList.remove("dark");
       localStorage.theme = 'light';
    }
  }

  async function logout() {
      try {
        await logoutSession();
      } catch (e) {
        console.error("Logout failed:", e);
      }
      setToken("");
      window.location.reload();
  }
</script>

{#if loading}
  <div class="flex h-screen items-center justify-center bg-surface-50 dark:bg-surface-950">
    <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600"></div>
  </div>
{:else if !authorized}
  <Login />
{:else}
  <div class="flex h-screen overflow-hidden bg-surface-50 dark:bg-surface-900">
    <Sidebar bind:page {dark} {toggleTheme} {logout} bind:sidebarOpen {allowedPages} {allowedSidebarLinks} {userRole} {sidebarOrder} onOrderChange={handleOrderChange} />
    <main class="flex-1 overflow-auto">
      <div class="max-w-[1400px] mx-auto p-6 lg:p-8">
        <!-- Mobile hamburger -->
        <button class="md:hidden mb-4 p-2 rounded-lg text-surface-600 dark:text-surface-300 hover:bg-surface-200 dark:hover:bg-surface-700" onclick={() => sidebarOpen = true} aria-label="Open menu">
          <svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" /></svg>
        </button>
        {#if page === "dashboard" && hasPageAccess("dashboard")}
          <Dashboard />
        {:else if page === "docker" && hasPageAccess("docker")}
          <Docker />
        {:else if page === "gitea" && hasPageAccess("gitea")}
          <Gitea />
        {:else if page === "files" && hasPageAccess("files")}
          <Files />
        {:else if page === "openclaw" && hasPageAccess("openclaw")}
          <OpenClaw />
        {:else if page === "chat-digest" && hasPageAccess("chat-digest")}
          <ChatSummary />
        {:else if page === "conversations" && hasPageAccess("conversations")}
          <Conversations />
        {:else if page === "settings" && userRole === "admin"}
          <Settings />
        {:else if page === "security" && hasPageAccess("security")}
          <Security />
        {:else if page === "litellm" && hasPageAccess("dashboard")}
          <LiteLLM />
        {:else if page === "cc-connect" && hasPageAccess("dashboard")}
          <CcConnect />
        {:else if page === "info-engine" && hasPageAccess("dashboard")}
          <InfoEngine />
        {:else if page === "opc" && hasPageAccess("opc")}
          <OPC />
        {:else if page === "transmission" && hasPageAccess("transmission")}
          <Transmission />
        {:else if page !== "terminal"}
          <Dashboard />
        {/if}

        {#if hasPageAccess("terminal")}
          <div class:hidden={page !== "terminal"}>
            <Terminal />
          </div>
        {/if}
      </div>
    </main>
  </div>
{/if}
