// App shell — nav, header, routing, context menu, drill flow

const { useState: useStateA, useEffect: useEffectA, useMemo: useMemoA, useRef: useRefA, useCallback: useCallbackA } = React;

function Sidebar({ route, onNav }) {
  const items = [
    { id:"overview", label:"Overview", icon:"dashboard" },
    { id:"accounts", label:"Accounts", icon:"accounts" },
    { id:"changes", label:"Changes feed", icon:"feed" },
    { id:"alerts", label:"Alerts", icon:"alerts", badge: window.FABCOM_DATA.alerts.filter(a=>a.severity==="red").length },
  ];
  return (
    <aside className="w-[208px] shrink-0 bg-raised border-r border-soft flex flex-col">
      <div className="px-4 h-14 flex items-center gap-2 border-b border-soft">
        <Icon name="logo" size={22}/>
        <div className="flex flex-col leading-tight">
          <span className="font-semibold text-[13px] tracking-tight">Fabcom</span>
          <span className="text-3 text-[10.5px] tracking-wide uppercase">Ad Settings</span>
        </div>
      </div>
      <nav className="flex flex-col gap-0.5 p-2">
        {items.map(it => (
          <button key={it.id} onClick={() => onNav(it.id)}
            className={`flex items-center gap-2.5 h-8 px-2 rounded-md text-[12.5px] ${route === it.id ? "bg-[var(--surface-2)] text-1" : "text-2 hover:bg-[var(--surface-2)]"}`}>
            <Icon name={it.icon} size={14} className={route === it.id ? "accent-text" : "text-3"}/>
            <span>{it.label}</span>
            {it.badge > 0 && (
              <span className="ml-auto text-[10px] tnum font-medium px-1.5 h-4 rounded flex items-center"
                style={{background:"color-mix(in oklab, var(--red-500) 22%, transparent)", color:"var(--red-400)"}}>{it.badge}</span>
            )}
          </button>
        ))}
      </nav>
      <div className="mt-2 px-3 text-3 text-[10.5px] uppercase tracking-wide">Workspaces</div>
      <div className="flex flex-col gap-0.5 p-2">
        {["HKT Group","Swire Properties","Cathay Pacific","HSBC","Lane Crawford"].map((w,i) => (
          <button key={w} className="flex items-center gap-2.5 h-7 px-2 rounded-md text-[12px] text-2 hover:bg-[var(--surface-2)]">
            <span className="w-4 h-4 rounded flex items-center justify-center text-[9px] font-semibold"
              style={{background:`color-mix(in oklab, var(--accent-500) ${10+i*4}%, var(--surface-3))`, color:"var(--accent-400)"}}>
              {w.split(" ").map(x=>x[0]).slice(0,2).join("")}
            </span>
            {w}
          </button>
        ))}
      </div>

      <div className="mt-auto p-3 border-t border-soft">
        <div className="flex items-center gap-2">
          <div className="w-7 h-7 rounded-full flex items-center justify-center text-[10px] font-semibold"
            style={{background:"color-mix(in oklab, var(--accent-500) 28%, transparent)", color:"var(--accent-400)"}}>VT</div>
          <div className="flex-1 min-w-0">
            <div className="text-[12px] text-1 truncate">Vincent Tam</div>
            <div className="text-3 text-[10.5px] truncate">Media Ops Lead</div>
          </div>
          <Icon name="chevron-right" size={12} className="text-4"/>
        </div>
      </div>
    </aside>
  );
}

function TopBar({ onToggleTheme, theme }) {
  return (
    <header className="h-14 border-b border-soft px-4 flex items-center gap-3 bg-raised">
      <div className="text-[12px] text-3 flex items-center gap-1.5">
        <span className="mono">dash.fabcom.app</span>
        <Icon name="chevron-right" size={11} className="text-4"/>
        <span className="text-2">Meta Ads</span>
      </div>
      <div className="ml-auto flex items-center gap-2">
        <div className="px-2.5 h-8 rounded-md border border-soft flex items-center gap-2 text-[11.5px] text-2">
          <span className="live-dot" style={{width:6,height:6,borderRadius:6,background:"var(--accent-500)",display:"inline-block"}}/>
          <span>Last sync <span className="text-1 tnum">{window.timeAgo(window.FABCOM_DATA.meta.last_refreshed)}</span></span>
          <span className="text-4">·</span>
          <span className="mono text-3">BQ fabcom-etl-core.meta_ads_settings</span>
        </div>
        <Button icon="refresh" size="sm">Refresh</Button>
        <Button icon="settings" size="sm" onClick={onToggleTheme}>{theme === "dark" ? "Light" : "Dark"}</Button>
      </div>
    </header>
  );
}

// Alerts standalone page
function AlertsPage({ onInvestigate }) {
  const data = window.FABCOM_DATA;
  const red = data.alerts.filter(a => a.severity === "red");
  const amber = data.alerts.filter(a => a.severity === "amber");
  const Section = ({title, items, tone}) => (
    <div className="surface rounded-xl overflow-hidden">
      <div className="px-4 py-3 border-b border-soft flex items-center gap-2">
        <SevDot level={tone}/>
        <div className="text-1 font-medium text-[13px]">{title}</div>
        <span className="text-3 text-[11.5px] tnum ml-auto">{items.length}</span>
      </div>
      <div>
        {items.map(al => {
          const acc = data.accounts.find(a => a.id === al.account_id);
          return (
            <div key={al.id} className="px-4 py-3 border-b border-soft last:border-0 flex items-start gap-3">
              <SevDot level={al.severity}/>
              <div className="flex-1 min-w-0">
                <div className="flex items-center gap-2">
                  <div className="text-1 text-[12.5px] font-medium truncate">{al.title}</div>
                  <Chip tone="default">{al.kind.replace("_"," ")}</Chip>
                </div>
                <div className="text-3 text-[11.5px] mt-0.5">{al.detail}</div>
                <div className="mt-2 mono text-[11px] tnum flex items-center gap-3">
                  {al.kind === "big_edit"
                    ? <Diff oldV={al.baseline} newV={al.value} money ccy={acc?.ccy || "HKD"}/>
                    : (<><span className="text-2">Current {window.fmtHKD(window.toHKD(al.value, acc.ccy))}</span><span className="text-4">·</span><span className="text-3">Baseline {window.fmtHKD(window.toHKD(al.baseline, acc.ccy))}</span></>)}
                </div>
              </div>
              <div className="flex items-center gap-1">
                <Button kind="subtle" size="xs" onClick={() => onInvestigate(al)}>Investigate</Button>
                <Button kind="ghost" size="xs">Snooze</Button>
              </div>
            </div>
          );
        })}
        {items.length === 0 && <div className="px-4 py-10 text-center text-3 text-[12px]">No {tone} alerts.</div>}
      </div>
    </div>
  );
  return (
    <div className="h-full flex flex-col gap-4">
      <div>
        <div className="text-3 text-[12px] mb-1">Alerts · thresholds configured in ops/budget_rules.yaml</div>
        <h1 className="text-[22px] font-semibold tracking-tight">Budget misconfig alerts</h1>
      </div>
      <div className="grid grid-cols-1 gap-4">
        <Section title="Critical — daily budget > 3× account 30d baseline" items={red} tone="red"/>
        <Section title="Watch — budget changed > 2× in one edit" items={amber} tone="amber"/>
      </div>
    </div>
  );
}

function BQModal({ account, onClose }) {
  const sql = `-- Daily settings for account ${account.id} (${account.name})
SELECT a.account_id, a.account_name, a.currency, a.balance, a.spend_cap,
       c.campaign_id, c.name AS campaign, c.status, c.objective, c.daily_budget,
       s.adset_id, s.name AS adset, s.daily_budget AS adset_daily, s.bid_strategy, s.optimization_goal
FROM \`fabcom-etl-core.meta_ads_settings.accounts\`  a
JOIN \`fabcom-etl-core.meta_ads_settings.campaigns\` c USING (account_id)
JOIN \`fabcom-etl-core.meta_ads_settings.adsets\`    s USING (campaign_id)
WHERE a.account_id = '${account.id}'
  AND c.status = 'ACTIVE'
ORDER BY c.daily_budget DESC;`;
  return (
    <div className="fixed inset-0 z-40 flex items-center justify-center" style={{background:"var(--scrim)"}} onClick={onClose}>
      <div className="surface rounded-xl w-[620px] max-w-[92vw]" onClick={e=>e.stopPropagation()} style={{boxShadow:"var(--shadow-lg)"}}>
        <div className="flex items-center px-4 py-3 border-b border-soft">
          <Icon name="copy" size={14} className="accent-text mr-2"/>
          <span className="text-[13px] font-medium">BigQuery snippet · {account.name}</span>
          <button onClick={onClose} className="ml-auto text-3"><Icon name="x" size={14}/></button>
        </div>
        <div className="p-4">
          <pre className="code">{sql}</pre>
        </div>
        <div className="px-4 py-3 border-t border-soft flex items-center gap-2">
          <Button icon="copy" kind="primary" onClick={() => { navigator.clipboard && navigator.clipboard.writeText(sql); onClose(); }}>Copy</Button>
          <Button icon="external">Open in BigQuery</Button>
          <span className="ml-auto text-3 text-[11px]">⌘C also copies</span>
        </div>
      </div>
    </div>
  );
}

function App(){
  // Read route from hash
  const readHash = () => {
    const h = (location.hash || "#overview").replace(/^#/,"");
    const [p, qs] = h.split("?");
    const params = new URLSearchParams(qs || "");
    return { page: p || "overview", params };
  };
  const [route, setRoute] = useStateA(readHash());
  useEffectA(() => {
    const onHash = () => setRoute(readHash());
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);
  const go = (page, params = {}) => {
    const p = new URLSearchParams(params).toString();
    location.hash = "#" + page + (p ? "?" + p : "");
  };

  const [filters, setFilters] = useStateA(() => ({
    query: route.params.get("q") || "",
    business: route.params.get("biz") || "",
    currency: route.params.get("ccy") || "",
    status: route.params.get("s") || "",
  }));
  // keep URL in sync for filters on overview
  useEffectA(() => {
    if (route.page !== "overview" && route.page !== "accounts") return;
    const p = new URLSearchParams();
    if (filters.query) p.set("q", filters.query);
    if (filters.business) p.set("biz", filters.business);
    if (filters.currency) p.set("ccy", filters.currency);
    if (filters.status) p.set("s", filters.status);
    if (route.params.get("acc")) p.set("acc", route.params.get("acc"));
    const nh = "#" + route.page + (p.toString() ? "?"+p.toString() : "");
    if (location.hash !== nh) history.replaceState(null, "", nh);
  }, [filters, route.page]);

  // Drill stack in right pane: [{kind: 'account'|'campaign'|'adset', id}, ...]
  const [stack, setStack] = useStateA(() => {
    const acc = route.params.get("acc");
    return acc ? [{kind:"account", id: acc}] : [];
  });
  const current = stack[stack.length - 1];
  const openAccount = (id) => setStack([{kind:"account", id}]);
  const openCampaign = (id) => setStack(s => [...s, {kind:"campaign", id}]);
  const openAdset = (id) => setStack(s => [...s, {kind:"adset", id}]);
  const popDetail = () => setStack([]);
  const back = (targetKind, id) => {
    if (!targetKind) { setStack(s => s.slice(0, -1)); return; }
    setStack(s => {
      const i = s.findIndex(x => x.kind === targetKind && x.id === id);
      return i >= 0 ? s.slice(0, i+1) : s;
    });
  };

  useEffectA(() => {
    // persist selected account in URL
    if ((route.page === "overview" || route.page === "accounts") && stack[0]?.kind === "account") {
      const p = new URLSearchParams(location.hash.split("?")[1] || "");
      p.set("acc", stack[0].id);
      history.replaceState(null, "", "#" + route.page + "?" + p.toString());
    }
  }, [stack, route.page]);

  // Context menu
  const [ctx, setCtx] = useStateA(null); // {x,y,account}
  const [toast, setToast] = useStateA(null);
  const [bqModal, setBqModal] = useStateA(null);

  const onContextMenu = (e, account) => {
    setCtx({x: e.clientX, y: e.clientY, account});
  };

  // Cmd-K to focus search (simplified: just shows a toast)
  useEffectA(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key === "k") {
        e.preventDefault();
        const el = document.querySelector('input[placeholder="Search accounts…"]');
        if (el) el.focus();
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  // Theme toggle (via Tweaks protocol)
  const toggleTheme = () => {
    const cur = document.documentElement.classList.contains("dark") ? "dark" : "light";
    const nxt = cur === "dark" ? "light" : "dark";
    document.documentElement.classList.remove("dark","light");
    document.documentElement.classList.add(nxt);
    try { window.parent.postMessage({ type:"__edit_mode_set_keys", edits: { theme: nxt } }, "*"); } catch(e){}
  };

  const theme = document.documentElement.classList.contains("dark") ? "dark" : "light";

  // Main layout: sidebar | workarea
  const showRightPane = stack.length > 0 && (route.page === "overview" || route.page === "accounts");

  return (
    <div className="h-full flex">
      <Sidebar route={route.page} onNav={(p) => { setStack([]); go(p); }}/>
      <div className="flex-1 flex flex-col min-w-0">
        <TopBar onToggleTheme={toggleTheme} theme={theme}/>
        <main className="flex-1 min-h-0 p-4 overflow-hidden">
          {(route.page === "overview" || route.page === "accounts") && (
            <div className="h-full flex gap-4 min-h-0">
              <div className={`${showRightPane ? "w-[52%] min-w-0" : "flex-1"} min-h-0`}>
                <Overview
                  filters={filters} setFilters={setFilters}
                  selectedId={stack[0]?.kind === "account" ? stack[0].id : null}
                  onSelect={openAccount}
                  onContextMenu={onContextMenu}
                  onInvestigate={(al) => openAccount(al.account_id)}
                />
              </div>
              {showRightPane && (
                <div className="flex-1 min-w-0 min-h-0">
                  {current.kind === "account" && (
                    <AccountDetail accountId={current.id} onClose={popDetail}
                      onOpenCampaign={openCampaign} onOpenAdset={openAdset}/>
                  )}
                  {current.kind === "campaign" && (
                    <CampaignDetail campaignId={current.id} onClose={popDetail} onBack={back}
                      onOpenAdset={openAdset}/>
                  )}
                  {current.kind === "adset" && (
                    <AdsetDetail adsetId={current.id} onClose={popDetail} onBack={back}/>
                  )}
                </div>
              )}
            </div>
          )}
          {route.page === "changes" && <ChangesFeed onOpenAccount={(id) => { go("overview"); openAccount(id); }}/>}
          {route.page === "alerts" && <AlertsPage onInvestigate={(al) => { go("overview"); openAccount(al.account_id); }}/>}
        </main>
      </div>

      {ctx && (
        <ContextMenu x={ctx.x} y={ctx.y} onClose={() => setCtx(null)} items={[
          { icon:"arrow-right", label:"Open account detail", onClick: () => openAccount(ctx.account.id), hint:"Enter" },
          { sep:true },
          { icon:"copy", label:"Copy BQ query for this account", onClick: () => setBqModal(ctx.account), hint:"⌘⇧C" },
          { icon:"copy", label:"Copy account ID", onClick: () => { navigator.clipboard && navigator.clipboard.writeText(ctx.account.id); setToast("Copied " + ctx.account.id); } },
          { icon:"link", label:"Copy shareable URL", onClick: () => { navigator.clipboard && navigator.clipboard.writeText(location.origin + location.pathname + "#overview?acc=" + ctx.account.id); setToast("URL copied"); } },
          { sep:true },
          { icon:"sheet", label:"Export this account to Sheets", onClick: () => setToast("Exporting " + ctx.account.name + "…") },
          { icon:"external", label:"Open in Meta Ads Manager", onClick: () => setToast("Opening Ads Manager…") },
        ]}/>
      )}
      {bqModal && <BQModal account={bqModal} onClose={() => setBqModal(null)}/>}
      {toast && <Toast text={toast} onDone={() => setToast(null)}/>}
      <Tweaks/>
    </div>
  );
}

// Mount only after data is loaded (handled by data_loader.jsx)
const __mount = () => ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
if (window.FABCOM_DATA) __mount(); else window.__fabcomMount = __mount;
