// PortalTable Dashboard — app shell: sidebar, topbar, command palette (⌘K),
// new-project dialog, routing between views, toast host, mount.

const { useState: useStateA, useEffect: useEffectA, useRef: useRefA } = React;

const NAV = [
  { group: "WORKSPACE", items: [
    { id: "overview", label: "Overview", icon: "gauge" },
    { id: "clients", label: "Clients", icon: "users", badge: 10 },
    { id: "projects", label: "Projects", icon: "grid", badge: 7 },
    { id: "approvals", label: "Approvals", icon: "checklist", badge: 4, badgeTone: "amber" },
  ] },
  { group: "DELIVERY", items: [
    { id: "files", label: "Files", icon: "file" },
    { id: "invoices", label: "Invoices", icon: "card", badge: 1, badgeTone: "red" },
    { id: "messages", label: "Messages", icon: "message", badge: 2, badgeTone: "accent" },
  ] },
  { group: "PORTAL", items: [
    { id: "branding", label: "Portal branding", icon: "palette" },
    { id: "team", label: "Team", icon: "users" },
    { id: "settings", label: "Settings", icon: "shield" },
  ] },
];
const VIEW_MAP = {
  overview: "OverviewView", clients: "ClientsView", projects: "ProjectsView",
  approvals: "ApprovalsView", files: "FilesView", invoices: "InvoicesView",
  messages: "MessagesView", branding: "BrandingView", team: "TeamView", settings: "SettingsView",
};
const TITLES = { overview: "Overview", clients: "Clients", projects: "Projects", approvals: "Approvals", files: "Files", invoices: "Invoices", messages: "Messages", branding: "Portal branding", team: "Team", settings: "Settings" };

/* -------------------------------------------------------------------------- */
/* Sidebar                                                                     */
/* -------------------------------------------------------------------------- */
function Sidebar({ route, navigate, open, onClose }) {
  return (
    <aside style={{
      width: 248, flexShrink: 0, height: "100vh", position: "sticky", top: 0, alignSelf: "flex-start",
      background: "var(--ink-900)", borderRight: "1px solid var(--line-2)",
      display: "flex", flexDirection: "column",
    }} className={"pd-sidebar" + (open ? " pd-open" : "")}>
      <div style={{ height: 60, display: "flex", alignItems: "center", gap: 10, padding: "0 18px", borderBottom: "1px solid var(--line-2)" }}>
        <Logo size={26} />
        <button onClick={onClose} aria-label="Close menu" className="pd-sidebar-close"
          style={{ display: "none", marginLeft: "auto", width: 32, height: 32, placeItems: "center", borderRadius: 8, background: "transparent", border: "1px solid var(--line-2)", color: "var(--fg-2)", cursor: "pointer" }}>
          <Ic name="x" size={16} />
        </button>
      </div>

      {/* demo perspective switch */}
      <DemoSwitch current="agency" />

      {/* workspace switcher */}
      <div style={{ padding: "14px 14px 8px" }}>
        <DropdownMenu align="left" width={216}
          trigger={(open) => (
            <button style={{ width: 220, display: "flex", alignItems: "center", gap: 10, padding: "8px 10px", borderRadius: 10, cursor: "pointer", fontFamily: "inherit", background: open ? "var(--ink-800)" : "var(--ink-950)", border: "1px solid var(--line-2)" }}>
              <span style={{ width: 28, height: 28, borderRadius: 8, background: "var(--fg-1)", color: "var(--ink-900)", display: "grid", placeItems: "center", fontWeight: 700, fontSize: 12, fontFamily: "var(--font-mono)" }}>SN</span>
              <span style={{ flex: 1, textAlign: "left", minWidth: 0 }}>
                <span style={{ display: "block", fontSize: 13, fontWeight: 600, color: "var(--fg-1)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>Studio Northstar</span>
                <span style={{ display: "block", fontSize: 11, color: "var(--fg-3)" }}>Agency · 5 seats</span>
              </span>
              <Ic name="arrowDown" size={14} style={{ color: "var(--fg-3)" }} />
            </button>
          )}
          items={[
            { label: "WORKSPACES", header: true },
            { label: "Studio Northstar", icon: "check", onClick: () => {} },
            { label: "Acme Consulting", icon: "grid", onClick: () => window.pdToast("Switched workspace") },
            { separator: true },
            { label: "Create workspace", icon: "plus", onClick: () => window.pdToast("New workspace") },
          ]} />
      </div>

      <nav style={{ flex: 1, overflowY: "auto", padding: "4px 12px 12px" }}>
        {NAV.map((section) => (
          <div key={section.group} style={{ marginBottom: 14 }}>
            <div style={{ padding: "8px 10px 6px", fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.1em", color: "var(--fg-4)" }}>{section.group}</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 2 }}>
              {section.items.map((it) => <NavItem key={it.id} item={it} active={route === it.id} onClick={() => it.href ? (window.location.href = it.href) : navigate(it.id)} />)}
            </div>
          </div>
        ))}
      </nav>

      {/* upgrade card */}
      <div style={{ padding: 12 }}>
        <div style={{ borderRadius: 12, border: "1px solid var(--line-2)", background: "var(--ink-950)", padding: 14 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <span style={{ display: "inline-flex", padding: 5, borderRadius: 7, background: "var(--accent)", color: "var(--fg-inverse)" }}><Ic name="sparkle" size={14} /></span>
            <span style={{ fontSize: 13, fontWeight: 600, color: "var(--fg-1)" }}>Agency plan</span>
          </div>
          <div style={{ fontSize: 12, color: "var(--fg-3)", margin: "8px 0 10px", lineHeight: 1.45 }}>Unlimited portals · 2 of 5 seats used.</div>
          <Progress value={40} tone="accent" />
        </div>
      </div>
    </aside>
  );
}
function NavItem({ item, active, onClick }) {
  const [h, setH] = useStateA(false);
  return (
    <button onClick={onClick} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        width: "100%", display: "flex", alignItems: "center", gap: 11, padding: "8px 10px", borderRadius: 9,
        border: 0, cursor: "pointer", fontFamily: "inherit", fontSize: 13.5, fontWeight: active ? 600 : 500,
        background: active ? "var(--ink-800)" : h ? "var(--ink-800)" : "transparent",
        color: active ? "var(--fg-1)" : h ? "var(--fg-1)" : "var(--fg-2)",
        transition: "background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out)", position: "relative",
      }}>
      {active && <span style={{ position: "absolute", left: -12, top: 8, bottom: 8, width: 3, borderRadius: 2, background: "var(--accent)" }} />}
      <Ic name={item.icon} size={17} style={{ color: active ? "var(--fg-1)" : "var(--fg-3)" }} />
      <span style={{ flex: 1, textAlign: "left" }}>{item.label}</span>
      {item.badge !== undefined && (
        <span style={{
          fontFamily: "var(--font-mono)", fontSize: 10.5, fontWeight: 600, minWidth: 18, height: 18, padding: "0 5px",
          borderRadius: 999, display: "grid", placeItems: "center",
          background: item.badgeTone === "red" ? "var(--red-soft)" : item.badgeTone === "amber" ? "var(--amber-soft)" : item.badgeTone === "accent" ? "var(--accent)" : "var(--ink-800)",
          color: item.badgeTone === "red" ? "var(--red)" : item.badgeTone === "amber" ? "var(--amber)" : item.badgeTone === "accent" ? "var(--fg-inverse)" : "var(--fg-3)",
          border: item.badgeTone === "accent" ? "none" : `1px solid ${item.badgeTone === "red" ? "rgba(200,68,59,0.26)" : item.badgeTone === "amber" ? "rgba(181,121,11,0.28)" : "var(--line-2)"}`,
        }}>{item.badge}</span>
      )}
    </button>
  );
}

/* -------------------------------------------------------------------------- */
/* Topbar                                                                      */
/* -------------------------------------------------------------------------- */
function Topbar({ route, onOpenCmd, onOpenNav }) {
  return (
    <header className="pd-topbar" style={{
      height: 60, flexShrink: 0, position: "sticky", top: 0, zIndex: 40,
      background: "rgba(255,255,255,0.8)", backdropFilter: "blur(14px)",
      borderBottom: "1px solid var(--line-2)", display: "flex", alignItems: "center", gap: 14, padding: "0 26px",
    }}>
      <button onClick={onOpenNav} aria-label="Open menu" className="pd-hamburger"
        style={{ display: "none", width: 36, height: 36, placeItems: "center", borderRadius: 8, background: "transparent", border: "1px solid var(--line-2)", color: "var(--fg-1)", cursor: "pointer", flexShrink: 0 }}>
        <Ic name="menu" size={18} />
      </button>

      <div style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 13.5, minWidth: 0 }}>
        <span className="pd-crumb-ws" style={{ display: "inline-flex", alignItems: "center", gap: 8 }}>
          <span style={{ color: "var(--fg-3)" }}>Studio Northstar</span>
          <Ic name="chevronRight" size={14} style={{ color: "var(--fg-4)" }} />
        </span>
        <span style={{ color: "var(--fg-1)", fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{TITLES[route]}</span>
      </div>

      <button onClick={onOpenCmd}
        style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: 10, height: 36, padding: "0 12px", borderRadius: 9, cursor: "pointer", background: "var(--ink-900)", border: "1px solid var(--line-3)", color: "var(--fg-3)", fontFamily: "inherit", width: 260, flexShrink: 0 }}
        className="pd-cmd-trigger">
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"><circle cx="11" cy="11" r="7" /><path d="m21 21-4.3-4.3" /></svg>
        <span className="pd-cmd-label" style={{ fontSize: 13, flex: 1, textAlign: "left", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>Search or jump to…</span>
        <span className="pd-cmd-kbd"><Kbd>⌘K</Kbd></span>
      </button>

      <DropdownMenu align="right" width={240}
        trigger={(open) => <span><IconButton icon="bell" label="Notifications" active={open} /></span>}
        items={[
          { label: "NOTIFICATIONS", header: true },
          { label: "Devin Park commented", icon: "message", onClick: () => window.pdToast("Opening message…") },
          { label: "INV-2039 is overdue", icon: "card", tone: "danger", onClick: () => window.pdToast("Opening invoice…") },
          { label: "Lena approved the calendar", icon: "check", onClick: () => window.pdToast("Opening approval…") },
          { separator: true },
          { label: "Mark all as read", icon: "checklist", onClick: () => window.pdToast("All caught up") },
        ]} />

      <DropdownMenu align="right" width={220}
        trigger={(open) => (
          <button aria-label="Account menu" style={{ display: "flex", alignItems: "center", padding: 3, borderRadius: 999, cursor: "pointer", background: "transparent", border: "1px solid", borderColor: open ? "var(--line-3)" : "transparent" }}>
            <span style={{ width: 32, height: 32, borderRadius: 999, background: "#111317", color: "#fff", display: "grid", placeItems: "center", fontSize: 12, fontWeight: 600, fontFamily: "var(--font-mono)", boxShadow: open ? "0 0 0 2px var(--ink-900), 0 0 0 4px var(--accent-line)" : "none", transition: "box-shadow var(--dur-2) var(--ease-out)" }}>AR</span>
          </button>
        )}
        items={[
          { label: "Alex Rivera", header: true },
          { label: "Profile", icon: "users", onClick: () => window.pdToast("Profile") },
          { label: "Workspace settings", icon: "shield", onClick: () => window.pdNavigate && window.pdNavigate("settings") },
          { label: "Theme", icon: "palette", kbd: "Light", onClick: () => {} },
          { separator: true },
          { label: "Sign out", icon: "external", tone: "danger", onClick: () => window.pdToast({ tone: "info", title: "Signed out" }) },
        ]} />
    </header>
  );
}

/* -------------------------------------------------------------------------- */
/* Command palette (⌘K)                                                        */
/* -------------------------------------------------------------------------- */
function CommandPalette({ open, onClose, navigate }) {
  const [q, setQ] = useStateA("");
  const [sel, setSel] = useStateA(0);
  const inputRef = useRefA(null);
  useEffectA(() => { if (open) { setQ(""); setSel(0); setTimeout(() => inputRef.current && inputRef.current.focus(), 40); } }, [open]);

  const commands = [
    ...Object.keys(TITLES).map((id) => ({ id, group: "Go to", label: TITLES[id], icon: NAV.flatMap((s) => s.items).find((i) => i.id === id).icon, action: () => navigate(id) })),
    { id: "new_project", group: "Actions", label: "New project", icon: "plus", action: () => window.pdNewProject() },
    { id: "invite_client", group: "Actions", label: "Invite client", icon: "users", action: () => { navigate("clients"); window.pdToast({ tone: "success", title: "Invite sent" }); } },
    { id: "new_invoice", group: "Actions", label: "Create invoice", icon: "card", action: () => { navigate("invoices"); window.pdToast({ tone: "success", title: "Draft created" }); } },
  ];
  const filtered = q ? commands.filter((c) => c.label.toLowerCase().includes(q.toLowerCase())) : commands;
  const groups = filtered.reduce((acc, c) => { (acc[c.group] = acc[c.group] || []).push(c); return acc; }, {});
  const flat = filtered;

  useEffectA(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === "ArrowDown") { e.preventDefault(); setSel((s) => Math.min(s + 1, flat.length - 1)); }
      else if (e.key === "ArrowUp") { e.preventDefault(); setSel((s) => Math.max(s - 1, 0)); }
      else if (e.key === "Enter") { e.preventDefault(); if (flat[sel]) { flat[sel].action(); onClose(); } }
    };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open, flat, sel, onClose]);

  if (!open) return null;
  let idx = -1;
  return (
    <Overlay onClose={onClose} padding={0}>
      <div onMouseDown={(e) => e.stopPropagation()} style={{ position: "fixed", top: "16vh", left: "50%", transform: "translateX(-50%)", width: "92%", maxWidth: 560 }}>
        <div style={{ background: "var(--ink-900)", border: "1px solid var(--line-2)", borderRadius: 16, boxShadow: "var(--pd-shadow-lg)", overflow: "hidden", animation: "pdPop 200ms var(--ease-out)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 11, padding: "15px 18px", borderBottom: "1px solid var(--line-2)" }}>
            <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="var(--fg-3)" strokeWidth="1.8" strokeLinecap="round"><circle cx="11" cy="11" r="7" /><path d="m21 21-4.3-4.3" /></svg>
            <input ref={inputRef} value={q} onChange={(e) => { setQ(e.target.value); setSel(0); }} placeholder="Search clients, projects, actions…"
              style={{ flex: 1, border: 0, outline: 0, background: "transparent", fontSize: 15, color: "var(--fg-1)", fontFamily: "inherit" }} />
            <Kbd>Esc</Kbd>
          </div>
          <div style={{ maxHeight: 360, overflowY: "auto", padding: 8 }}>
            {flat.length === 0 && <div style={{ padding: 28, textAlign: "center", color: "var(--fg-3)", fontSize: 13.5 }}>No results for "{q}"</div>}
            {Object.keys(groups).map((g) => (
              <div key={g} style={{ marginBottom: 6 }}>
                <div style={{ padding: "8px 10px 4px", fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.08em", color: "var(--fg-4)" }}>{g}</div>
                {groups[g].map((c) => {
                  idx++; const active = idx === sel; const myIdx = idx;
                  return (
                    <button key={c.id} onMouseEnter={() => setSel(myIdx)} onClick={() => { c.action(); onClose(); }}
                      style={{ width: "100%", display: "flex", alignItems: "center", gap: 11, padding: "9px 10px", borderRadius: 9, border: 0, cursor: "pointer", fontFamily: "inherit", fontSize: 13.5, fontWeight: 500, background: active ? "var(--ink-800)" : "transparent", color: active ? "var(--fg-1)" : "var(--fg-2)", textAlign: "left" }}>
                      <span style={{ width: 26, height: 26, borderRadius: 7, display: "grid", placeItems: "center", background: active ? "var(--accent)" : "var(--ink-800)", color: active ? "var(--fg-inverse)" : "var(--fg-3)" }}><Ic name={c.icon} size={14} /></span>
                      <span style={{ flex: 1 }}>{c.label}</span>
                      {active && <Ic name="arrowRight" size={14} style={{ color: "var(--fg-3)" }} />}
                    </button>
                  );
                })}
              </div>
            ))}
          </div>
        </div>
      </div>
    </Overlay>
  );
}

/* -------------------------------------------------------------------------- */
/* New project dialog                                                          */
/* -------------------------------------------------------------------------- */
function NewProjectDialog({ open, onClose }) {
  const [name, setName] = useStateA("");
  const [client, setClient] = useStateA(PD_CLIENTS[0].name);
  useEffectA(() => { if (open) { setName(""); setClient(PD_CLIENTS[0].name); } }, [open]);
  function create() {
    if (!name.trim()) { window.pdToast({ tone: "error", title: "Name required" }); return; }
    window.pdToast({ tone: "success", title: "Project created", body: `${name} · ${client}` });
    onClose();
  }
  return (
    <Dialog open={open} onClose={onClose} eyebrow="NEW PROJECT" title="Start a project"
      footer={<React.Fragment><Button variant="ghost" size="md" onClick={onClose}>Cancel</Button><Button variant="primary" size="md" icon="check" onClick={create}>Create project</Button></React.Fragment>}>
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        <label style={{ display: "flex", flexDirection: "column", gap: 7 }}>
          <span style={{ fontSize: 12.5, color: "var(--fg-2)", fontWeight: 500 }}>Project name</span>
          <input value={name} onChange={(e) => setName(e.target.value)} autoFocus placeholder="e.g. Q3 Brand Refresh" style={inputStyleM} />
        </label>
        <label style={{ display: "flex", flexDirection: "column", gap: 7 }}>
          <span style={{ fontSize: 12.5, color: "var(--fg-2)", fontWeight: 500 }}>Client</span>
          <div style={{ position: "relative" }}>
            <select value={client} onChange={(e) => setClient(e.target.value)} style={{ ...inputStyleM, appearance: "none", cursor: "pointer" }}>
              {PD_CLIENTS.map((c) => <option key={c.id}>{c.name}</option>)}
            </select>
            <span style={{ position: "absolute", right: 12, top: 12, color: "var(--fg-3)", pointerEvents: "none" }}><Ic name="arrowDown" size={15} /></span>
          </div>
        </label>
        <div style={{ display: "flex", alignItems: "center", gap: 10, padding: 12, borderRadius: 10, background: "var(--accent-soft)", border: "1px solid var(--accent-line)" }}>
          <Ic name="database" size={16} style={{ color: "var(--accent-ink)" }} />
          <span style={{ fontSize: 12.5, color: "var(--fg-2)" }}>Tasks sync to the client's workspace automatically.</span>
        </div>
      </div>
    </Dialog>
  );
}

/* -------------------------------------------------------------------------- */
/* App                                                                         */
/* -------------------------------------------------------------------------- */
function DashApp() {
  const [route, setRoute] = useStateA(() => { const h = location.hash.replace("#", ""); return VIEW_MAP[h] ? h : "overview"; });
  const [cmdOpen, setCmdOpen] = useStateA(false);
  const [npOpen, setNpOpen] = useStateA(false);
  const [navOpen, setNavOpen] = useStateA(false);
  const scrollRef = useRefA(null);

  function navigate(r) { setRoute(r); location.hash = r; setNavOpen(false); window.scrollTo(0, 0); }
  useEffectA(() => { window.pdNavigate = navigate; window.pdNewProject = () => setNpOpen(true); }, []);
  useEffectA(() => {
    const onHash = () => { const h = location.hash.replace("#", ""); if (VIEW_MAP[h]) setRoute(h); };
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); setCmdOpen((o) => !o); }
      else if (e.key === "Escape") { setNavOpen(false); }
    };
    window.addEventListener("hashchange", onHash);
    window.addEventListener("keydown", onKey);
    return () => { window.removeEventListener("hashchange", onHash); window.removeEventListener("keydown", onKey); };
  }, []);

  const View = window[VIEW_MAP[route]];

  return (
    <div style={{ display: "flex", minHeight: "100vh", background: "var(--ink-950)" }}>
      <Sidebar route={route} navigate={navigate} open={navOpen} onClose={() => setNavOpen(false)} />
      {navOpen && <div className="pd-nav-backdrop" onClick={() => setNavOpen(false)}
        style={{ position: "fixed", inset: 0, background: "rgba(16,18,22,0.42)", backdropFilter: "blur(2px)", zIndex: 70, animation: "pdFade 160ms var(--ease-out)" }} />}
      <div style={{ flex: 1, minWidth: 0, display: "flex", flexDirection: "column" }}>
        <Topbar route={route} onOpenCmd={() => setCmdOpen(true)} onOpenNav={() => setNavOpen(true)} />
        <main ref={scrollRef} style={{ flex: 1 }}>
          <div className="pd-main-pad" style={{ maxWidth: 1240, margin: "0 auto", padding: "28px 26px 64px" }} key={route}>
            <div style={{ animation: "viewIn 280ms var(--ease-out)" }}>
              {View ? <View navigate={navigate} /> : null}
            </div>
          </div>
        </main>
      </div>
      <CommandPalette open={cmdOpen} onClose={() => setCmdOpen(false)} navigate={navigate} />
      <NewProjectDialog open={npOpen} onClose={() => setNpOpen(false)} />
      <ToastHost />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("pd-dash-root")).render(<DashApp />);
