import { Show, createSignal, onMount, type Component } from "solid-js";
import { fetchAllState, fetchVersion } from "./api/rest";
import { openEventStream } from "./api/sse";
import { replaceAll, state } from "./stores/state";
import { scope, setScope } from "./stores/scope";
import ScopeSelector from "./components/ScopeSelector";
import Overview from "./views/Overview";
import DebugPanel from "./views/DebugPanel";
import type { VersionInfo } from "./types";
import logoUrl from "./assets/logo-bimi.svg";
import { isAdmin } from "./stores/mode";

const App: Component = () => {
  const [error, setError] = createSignal<string | undefined>();
  const [version, setVersion] = createSignal<VersionInfo | undefined>();

  onMount(async () => {
    try {
      const [snaps, ver] = await Promise.all([fetchAllState(), fetchVersion()]);
      replaceAll(snaps);
      setVersion(ver);
      if (!scope() && snaps.length > 0) {
        setScope(snaps[0].maglevd.name);
      }
      openEventStream();
    } catch (err) {
      setError(`${err}`);
    }
  });

  // The admin toggle is only shown when the server reports that admin
  // credentials are configured. Without this gate, we'd link operators
  // to a /admin/ URL that returns 404 and surprise them.
  const adminAvailable = () => version()?.admin_enabled === true;

  return (
    <div class="app">
      <header class="app-header">
        <div class="brand">
          <a
            class="brand-logo"
            href="https://git.ipng.ch/ipng/vpp-maglev/"
            target="_blank"
            rel="noopener"
            title="vpp-maglev on git.ipng.ch"
          >
            <img src={logoUrl} alt="IPng" />
          </a>
          <strong>maglev</strong>
          {version() && (
            <span class="version" title={`commit ${version()!.commit} · built ${version()!.date}`}>
              {version()!.version} ({version()!.commit})
            </span>
          )}
        </div>
        <ScopeSelector />
        <Show when={isAdmin || adminAvailable()}>
          <span class="mode-tag">{isAdmin ? "admin" : "view"}</span>
        </Show>
        <Show when={adminAvailable()}>
          <a
            class="admin-toggle"
            href={isAdmin ? "/view/" : "/admin/"}
            title={isAdmin ? "exit admin mode" : "enter admin mode"}
          >
            {isAdmin ? "exit admin" : "admin…"}
          </a>
        </Show>
      </header>

      {error() && <div class="banner err">{error()}</div>}
      {!error() && Object.keys(state.byName).length === 0 && <p class="loading">Loading…</p>}

      <Overview />

      {/* Admin-only sections — everything below this line is hidden on
          /view/ and only rendered when the SPA was loaded at /admin/.
          The basic-auth gate on /admin/ means only authenticated users
          ever reach this branch. Future admin-only features drop in
          here, one per <Show> block, so the /view-vs-/admin diff stays
          localized and reviewable. */}
      <Show when={isAdmin}>
        <DebugPanel />
      </Show>
    </div>
  );
};

export default App;
