import { useState, type ReactNode } from "react";
import { Database, Flask, List, SidebarSimple, SignOut, X } from "@phosphor-icons/react";

import { SidebarContent } from "./Sidebar";
import { useAuth } from "@/context/AuthContext";
import { useSettings } from "@/context/SettingsContext";
import { useLocalStorage } from "@/hooks/useLocalStorage";
import { cn } from "@/lib/utils";

/**
 * Workspace shell: a floating glass island nav on top, the thread in the
 * centre, and the source/ingest rail on the right. The rail is collapsible on
 * desktop (state persists across reloads) and becomes the off-canvas drawer
 * below `lg`.
 */
export function AppShell({ nav, children }: { nav?: ReactNode; children: ReactNode }) {
  const [open, setOpen] = useState(false);
  const [railOpen, setRailOpen] = useLocalStorage<boolean>("rr_rail_open", true);
  const { session, logout } = useAuth();
  const { kbOnly, setKbOnly } = useSettings();

  return (
    <div className="relative flex h-[100dvh] flex-col overflow-hidden bg-zinc-950">
      {/* First tab stop: lets keyboard users bypass the nav and the rail. */}
      <a href="#main-content" className="skip-link">
        Skip to main content
      </a>

      {/* Ambient wash — single accent hue, no purple. */}
      <div className="pointer-events-none fixed inset-0 z-0" aria-hidden>
        <div className="absolute left-[8%] top-[-14%] h-[520px] w-[720px] rounded-full bg-accent/[0.07] blur-[140px]" />
        <div className="absolute bottom-[-18%] right-[2%] h-[420px] w-[560px] rounded-full bg-accent/[0.03] blur-[150px]" />
      </div>
      <div className="grain" aria-hidden />

      {/* Floating island nav */}
      <header className="relative z-30 flex shrink-0 justify-center px-4 pt-5">
        <div className="island w-full max-w-3xl lg:w-auto lg:max-w-none">
          <button
            onClick={() => setOpen(true)}
            className="icon-btn lg:hidden"
            aria-label="Open menu — views, scope and sources"
          >
            <List className="h-4 w-4" />
          </button>

          <div className="flex items-center gap-2 pr-3 lg:border-r lg:border-white/[0.07]">
            <Flask className="h-4 w-4 text-accent" />
            <span className="text-[13.5px] font-medium tracking-tight text-white">ResearchRAG</span>
          </div>

          {nav && <nav className="hidden gap-1 sm:flex">{nav}</nav>}

          <div className="ml-auto flex items-center gap-2 lg:ml-0 lg:border-l lg:border-white/[0.07] lg:pl-3">
            <button
              onClick={() => setKbOnly(!kbOnly)}
              className={cn("pill hidden sm:flex", kbOnly && "pill-active")}
              title={
                kbOnly
                  ? "Answers use your ingested papers only"
                  : "Falls back to live OpenAlex / web when the KB seems irrelevant"
              }
            >
              <Database className="h-3.5 w-3.5" />
              {kbOnly ? "Library only" : "Library + web"}
            </button>
            {/* Desktop-only: below `lg` the rail is the drawer, which has its
                own trigger on the left of the island. */}
            <button
              onClick={() => setRailOpen(!railOpen)}
              className={cn("icon-btn hidden lg:grid", railOpen && "text-accent")}
              title={railOpen ? "Hide sources rail" : "Show sources rail"}
              aria-label={railOpen ? "Hide sources rail" : "Show sources rail"}
              aria-expanded={railOpen}
            >
              <SidebarSimple className="h-4 w-4" />
            </button>
            <button
              onClick={logout}
              className="icon-btn"
              title={session ? `Sign out ${session.displayName}` : "Sign out"}
              aria-label="Sign out"
            >
              <SignOut className="h-4 w-4" />
            </button>
          </div>
        </div>
      </header>

      {/* Thread + rail — full bleed, so the rail stays flush with the right
          edge. Collapsing it hands the whole width back to the thread. */}
      <div
        className={cn(
          "relative z-10 grid min-h-0 flex-1 gap-6 px-4 pb-4 pt-1 lg:px-6",
          railOpen && "lg:grid-cols-[minmax(0,1fr)_clamp(288px,26vw,352px)]",
        )}
      >
        <main id="main-content" tabIndex={-1} className="min-h-0 min-w-0 focus:outline-none">
          {children}
        </main>
        <aside
          className={cn(
            "hidden min-h-0 overflow-y-auto scrollbar-thin pb-2",
            railOpen && "rail-in lg:block",
          )}
        >
          <SidebarContent />
        </aside>
      </div>

      {/* Mobile drawer */}
      {open && (
        <div className="fixed inset-0 z-40 lg:hidden">
          <div
            className="absolute inset-0 bg-black/70 backdrop-blur-sm"
            onClick={() => setOpen(false)}
          />
          <aside className="absolute right-0 top-0 h-full w-[22rem] max-w-[88vw] overflow-y-auto scrollbar-thin border-l border-white/[0.07] bg-zinc-950 p-3 shadow-2xl animate-fade-up">
            <button
              onClick={() => setOpen(false)}
              className="icon-btn absolute right-4 top-4 z-10"
              aria-label="Close panel"
            >
              <X className="h-4 w-4" />
            </button>
            {/* The island nav hides below `sm`, so the drawer carries the view
                switcher and the library-scope toggle on phones. */}
            <SidebarContent showIdentity nav={nav} onNavigate={() => setOpen(false)} />
          </aside>
        </div>
      )}
    </div>
  );
}
