/* Tract Console v2 — root app: auth → shell (sidebar + topbar) → deals list / deal workspace.
   The deal workspace holds the stage stepper (state machine) and the feature tabs. */
const { Icon: I2, Avatar: Av2, Popover: Pop2, useStore: useStore2, useDeal: useDeal2, Store: Store2, useState: uS2, useEffect: uE2, useRef: uR2, Toast: Toast2 } = window;
const Dd = window.V2DATA;
const Pn = window.Panels;

const PERSONAS = [{ id: "buyer", label: "Buyer" }, { id: "advisor", label: "Advisor" }, { id: "attorney", label: "Attorney" }, { id: "admin", label: "Admin" }];
const TABS = [
  { id: "chat", label: "Chat", icon: "message-square" },
  { id: "documents", label: "Documents", icon: "folder" },
  { id: "dd", label: "Due diligence", icon: "list-checks" },
  { id: "ai", label: "Advisor AI", icon: "sparkles", advisorOnly: true },
  { id: "funds", label: "Funds", icon: "wallet" },
  { id: "activity", label: "Activity", icon: "history" },
];
const THEMES = {
  forest: { "--green": "#1f8a5b", "--green-700": "#176a46", "--green-soft": "#e9f3ed", "--green-line": "#bfe0cd" },
  indigo: { "--green": "#4351c9", "--green-700": "#333ea0", "--green-soft": "#ecedfb", "--green-line": "#c8ccf0" },
  ocean:  { "--green": "#2d6cb8", "--green-700": "#224f88", "--green-soft": "#e9f1fb", "--green-line": "#c2d8f0" },
  clay:   { "--green": "#b5572f", "--green-700": "#8c3f20", "--green-soft": "#f8ece6", "--green-line": "#ecc9b8" },
};
function applyTheme(name) { const t = THEMES[name] || THEMES.forest; Object.entries(t).forEach(([k, v]) => document.documentElement.style.setProperty(k, v)); }
const STATE_META = { done: { node: "done", st: "Done", stCls: "done" }, active: { node: "active", st: "Active", stCls: "active" }, preparing: { node: "preparing", st: "Preparing", stCls: "preparing" } };

/* ---------------- stage stepper ---------------- */
function Stepper({ role, selected, onSelect }) {
  const dl = useDeal2();
  const isAdvisor = role === "advisor";
  const steps = Dd.STAGES.map((s) => ({ ...s, state: dl.stageState[s.id] }));
  const display = [...steps];
  if (dl.postClosing) display.push({ id: "post", n: 6, label: "Post-closing checklist", short: "Post-closing", state: "active", post: true });
  return (
    <div className="stepper">
      {display.map((s, i) => {
        const meta = STATE_META[s.state] || STATE_META.preparing;
        return <StepCol key={s.id} s={s} meta={meta} isFirst={i === 0} isLast={i === display.length - 1}
          leftDone={i > 0 && display[i - 1].state === "done"} rightDone={s.state === "done"}
          selected={selected === s.id} isAdvisor={isAdvisor && !s.post} frozen={dl.frozen} onSelect={() => onSelect(s.post ? "close" : s.id)} />;
      })}
    </div>
  );
}
function StepCol({ s, meta, isFirst, isLast, leftDone, rightDone, selected, isAdvisor, frozen, onSelect }) {
  const [menu, setMenu] = uS2(false);
  const kebab = uR2(null);
  const nodeContent = s.post ? <I2 name="clipboard-check" size={16} /> : meta.node === "done" ? <I2 name="check" size={17} /> : s.n;
  return (
    <button className={"step" + (selected ? " step--sel" : "")} onClick={onSelect}>
      {!isFirst && <span className="step__line" style={{ left: 0, width: "50%", background: leftDone ? "var(--green)" : "var(--line-2)" }} />}
      {!isLast && <span className="step__line" style={{ left: "50%", width: "50%", background: rightDone ? "var(--green)" : "var(--line-2)" }} />}
      <span ref={kebab} style={{ position: "relative", zIndex: 1, display: "inline-block" }}
        onClick={isAdvisor && !frozen ? (e) => { e.stopPropagation(); setMenu((v) => !v); } : undefined}>
        <span className={"step__node step__node--" + meta.node} style={isAdvisor && !frozen ? { cursor: "pointer" } : null}>{nodeContent}</span>
        {isAdvisor && !frozen && (
          <span title="Set stage status"
            style={{ position: "absolute", top: -5, right: -8, width: 19, height: 19, borderRadius: "50%", background: "var(--card)", border: "1px solid var(--line-2)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--ink-2)", boxShadow: "var(--sh-1)", pointerEvents: "none" }}><I2 name="pencil" size={11} /></span>
        )}
      </span>
      <span className="step__lbl">{s.label}</span>
      <span className={"step__st step__st--" + meta.stCls}>{s.post ? "New" : meta.st}</span>
      {menu && <StageMenu kebab={kebab} id={s.id} state={s.state} frozen={frozen} onClose={() => setMenu(false)} />}
    </button>
  );
}
function StageMenu({ kebab, id, state, frozen, onClose }) {
  const dl = useDeal2();
  const meta = Dd.STAGES.find((s) => s.id === id);
  const canAct = Store2.canActivate(dl, id);
  const canDone = Store2.canMarkDone(dl, id);
  const prereqLabels = Store2.prereqs(id).filter((p) => dl.stageState[p] !== "done").map((p) => Dd.STAGES.find((s) => s.id === p).short);
  const isClose = id === "close";
  const doAct = (type) => { Store2.dispatch({ type, id }); onClose(); };
  return (
    <Pop2 anchorRef={kebab} onClose={onClose} width={236} align="left">
      <div className="pop__sec">Set "{meta.short}" status</div>
      <button className="pop__item" disabled={frozen || state === "active" || !canAct} onClick={() => doAct("STAGE_ACTIVE")}>
        <span className="step__node step__node--active" style={{ width: 22, height: 22, fontSize: 11 }}>{meta.n}</span><span style={{ flex: 1 }}>Mark active</span>{state === "active" && <I2 name="check" size={14} color="var(--green)" />}
      </button>
      <button className="pop__item" disabled={frozen || state === "done" || !canDone} onClick={() => doAct("STAGE_DONE")}>
        <span className="step__node step__node--done" style={{ width: 22, height: 22 }}><I2 name="check" size={13} /></span><span style={{ flex: 1 }}>Mark done</span>{state === "done" && <I2 name="check" size={14} color="var(--green)" />}
      </button>
      <button className="pop__item" disabled={frozen || state === "preparing"} onClick={() => doAct("STAGE_PREPARING")}>
        <span className="step__node step__node--preparing" style={{ width: 22, height: 22, fontSize: 11 }}>{meta.n}</span><span style={{ flex: 1 }}>Set to preparing</span>{state === "preparing" && <I2 name="check" size={14} color="var(--green)" />}
      </button>
      {!canAct && state !== "active" && prereqLabels.length > 0 && <div style={{ padding: "6px 10px 4px", fontSize: 11.5, color: "var(--ink-3)", lineHeight: 1.4 }}>To activate, finish {prereqLabels.join(" & ")} first.</div>}
      {isClose && !Store2.closeEnabled(dl) && <div style={{ padding: "6px 10px 4px", fontSize: 11.5, color: "var(--ink-3)", lineHeight: 1.4 }}>Closing unlocks once the PSA is done.</div>}
      {isClose && Store2.closeEnabled(dl) && state !== "done" && <div style={{ padding: "6px 10px 4px", fontSize: 11.5, color: "var(--amber)", lineHeight: 1.4, display: "flex", gap: 6 }}><I2 name="alert-triangle" size={13} />Marking closing done freezes the deal — this can't be undone.</div>}
    </Pop2>
  );
}

/* ---------------- deal hero ---------------- */
function Hero({ role, selected, onSelect }) {
  const dl = useDeal2();
  return (
    <div className="hero">
      <div className="wrap">
        <div className="hero__top">
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
              <h1>{dl.name}</h1>
              {dl.frozen && <span className="pill pill--dark"><I2 name="lock" size={13} />Closed · frozen</span>}
            </div>
            <div className="hero__meta">
              <span>{dl.address}</span><span className="sep">·</span>
              <span><b className="num">{Dd.money(dl.price)}</b></span><span className="sep">·</span>
              <span><b>{dl.cap}</b> cap</span><span className="sep">·</span>
              <span>DD ends <b className="num">{dl.ddEnds}</b></span><span className="sep">·</span>
              <span className="faint num">{dl.id}</span>
            </div>
          </div>
          <div style={{ display: "flex", alignItems: "center" }}>
            {["advisor", "buyer", "attorney"].map((r, i) => <span key={r} style={{ marginLeft: i ? -8 : 0, borderRadius: "50%", boxShadow: "0 0 0 2px var(--bg)" }} title={Dd.PEOPLE[r].name}><Av2 who={r} size={32} /></span>)}
          </div>
        </div>
        <Stepper role={role} selected={selected} onSelect={onSelect} />
      </div>
    </div>
  );
}

/* ---------------- focus (full-screen) bar ---------------- */
function FocusBar({ role, tab, setTab, onExit }) {
  const dl = useDeal2();
  const active = Dd.STAGES.find((s) => dl.stageState[s.id] === "active");
  const fillTabs = [{ id: "chat", label: "Chat", icon: "message-square" }];
  if (role === "advisor") fillTabs.push({ id: "ai", label: "Advisor AI", icon: "sparkles" });
  return (
    <div className="focusbar">
      <button className="btn btn--quiet btn--sm" onClick={onExit} style={{ marginLeft: -6 }}><I2 name="minimize-2" size={15} />Exit full screen</button>
      <span style={{ width: 1, height: 22, background: "var(--line-2)" }} />
      <span className="focusbar__name">{dl.name}</span>
      {active && <span className="pill pill--acc">{active.short}</span>}
      {dl.frozen && <span className="pill pill--dark"><I2 name="lock" size={12} />Closed</span>}
      <span className="gap" />
      {fillTabs.length > 1 && <div className="tw-seg">{fillTabs.map((t) => <button key={t.id} className={tab === t.id ? "on" : ""} onClick={() => setTab(t.id)} style={{ padding: "0 12px", display: "flex", alignItems: "center", gap: 6 }}><I2 name={t.icon} size={14} />{t.label}</button>)}</div>}
    </div>
  );
}

/* ---------------- deal workspace ---------------- */
function DealWorkspace({ role, focus, setFocus }) {
  const dl = useDeal2();
  const [tab, setTab] = uS2("chat");
  const [selected, setSelected] = uS2(null);
  const tabs = TABS.filter((t) => !t.advisorOnly || role === "advisor");
  const activeTab = tabs.find((t) => t.id === tab) ? tab : "chat";
  uE2(() => { if (tab === "ai" && role !== "advisor") setTab("chat"); }, [role]);
  const fillTab = activeTab === "chat" || activeTab === "ai";
  // focus only applies on the full-screen-able tabs; drop it when leaving them
  uE2(() => { if (focus && !fillTab) setFocus(false); }, [activeTab]);
  const cm = Pn.costModel(dl);
  const ddNeeded = cm.needed;

  // clicking a stage chip filters the chat's documents panel (and the Documents tab)
  const onStage = (id) => { setSelected(id); if (activeTab !== "documents" && activeTab !== "chat") setTab("chat"); };

  let body;
  if (activeTab === "chat") body = <Pn.ChatTab role={role} stageId={selected} onClearStage={() => setSelected(null)} focus={focus} />;
  else if (activeTab === "documents") body = <Pn.DocumentsTab role={role} stageId={selected} setStageFilter={setSelected} />;
  else if (activeTab === "dd") body = <Pn.DueDiligenceTab role={role} />;
  else if (activeTab === "ai") body = <window.AITab role={role} />;
  else if (activeTab === "funds") body = <Pn.FundsTab role={role} />;
  else if (activeTab === "activity") body = <Pn.Activity role={role} />;

  const focused = focus && fillTab;
  return (
    <div style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column" }}>
      {focused ? (
        <FocusBar role={role} tab={activeTab} setTab={setTab} onExit={() => setFocus(false)} />
      ) : (
        <>
          <Hero role={role} selected={selected} onSelect={onStage} />
          <div className="tabs">
            <div className="tabs__row">
              {tabs.map((t) => {
                const count = t.id === "documents" ? dl.documents.length : t.id === "dd" && ddNeeded ? ddNeeded : null;
                return <button key={t.id} className={"tab" + (activeTab === t.id ? " tab--on" : "")} onClick={() => setTab(t.id)}>
                  <I2 name={t.icon} size={16} />{t.label}{count ? <span className="tab__c" style={t.id === "dd" ? { background: "var(--amber)" } : null}>{count}</span> : null}
                </button>;
              })}
              {fillTab && <><span className="gap" /><button className="btn btn--ghost btn--sm" style={{ alignSelf: "center" }} onClick={() => setFocus(true)}><I2 name="maximize-2" size={14} />Full screen</button></>}
            </div>
          </div>
        </>
      )}
      <div style={{ flex: 1, minHeight: 0, overflowY: fillTab ? "hidden" : "auto", display: "flex", flexDirection: "column" }}>{body}</div>
    </div>
  );
}

/* ---------------- topbar ---------------- */
function Topbar({ role, onSwitchRole, theme, setTheme, crumb, onBack }) {
  const [disp, setDisp] = uS2(false);
  const dispRef = uR2(null);
  return (
    <div className="topbar">
      {onBack ? (
        <button className="btn btn--quiet btn--sm" onClick={onBack} style={{ marginLeft: -6 }}><I2 name="arrow-left" size={16} />Deals</button>
      ) : null}
      <div style={{ display: "flex", alignItems: "center", gap: 8, minWidth: 0 }}>
        {onBack && <span className="faint">/</span>}
        <span style={{ fontWeight: 700, fontSize: 15, letterSpacing: "-.01em", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{crumb}</span>
      </div>
      <span className="gap" />
      <span className="faint" style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".06em", marginRight: 2 }}>View as</span>
      <div className="tw-seg">{PERSONAS.map((p) => <button key={p.id} className={role === p.id ? "on" : ""} onClick={() => onSwitchRole(p.id)} style={{ padding: "0 11px" }}>{p.label}</button>)}</div>
      <button ref={dispRef} className="btn btn--ghost btn--sm" onClick={() => setDisp((v) => !v)} title="Display"><I2 name="sliders-horizontal" size={15} /></button>
      {disp && (
        <Pop2 anchorRef={dispRef} onClose={() => setDisp(false)} align="right" width={216}>
          <div className="pop__sec">Accent</div>
          <div style={{ display: "flex", gap: 8, padding: "4px 10px 10px" }}>
            {Object.keys(THEMES).map((k) => <button key={k} onClick={() => setTheme(k)} title={k} style={{ width: 26, height: 26, borderRadius: "50%", border: "2px solid " + (theme === k ? "var(--ink)" : "transparent"), background: THEMES[k]["--green"], cursor: "pointer", boxShadow: theme === k ? "0 0 0 2px var(--card),0 0 0 4px var(--ink)" : "none" }} />)}
          </div>
          <div style={{ borderTop: "1px solid var(--line)", marginTop: 2 }} />
          <button className="pop__item" onClick={() => { Store2.dispatch({ type: "RESET" }); setDisp(false); location.reload(); }}><I2 name="rotate-ccw" size={15} color="var(--ink-2)" />Reset demo</button>
        </Pop2>
      )}
    </div>
  );
}

/* ---------------- shell ---------------- */
const TITLES = { deals: "Deals", notifs: "Notifications", account: "Account", team: "Team", funds: "Funds" };
function Shell({ role, onSignOut, onSwitchRole }) {
  const st = useStore2();
  const [view, setView] = uS2("deals");
  const [theme, setTheme] = uS2("forest");
  const [creating, setCreating] = uS2(false);
  const [toast, setToast] = uS2(null);
  const [focus, setFocus] = uS2(false);
  uE2(() => { applyTheme(theme); }, [theme]);

  const inDeal = view === "deal" && st.activeId && st.deals[st.activeId];
  const openDeal = (id) => { Store2.dispatch({ type: "SET_ACTIVE_DEAL", id }); setView("deal"); };
  const exitDeal = () => { setFocus(false); setView("deals"); };
  const crumb = inDeal ? st.deals[st.activeId].name : TITLES[view] || "Deals";

  let content;
  if (inDeal) content = <DealWorkspace role={role} focus={focus} setFocus={setFocus} />;
  else if (view === "deals") content = <window.DealsList role={role} onOpen={openDeal} onNew={() => setCreating(true)} />;
  else if (view === "notifs") content = <window.NotificationsView role={role} onOpenDeal={openDeal} />;
  else if (view === "funds") content = <window.FundsView role={role} onOpenDeal={openDeal} />;
  else if (view === "account") content = <window.AccountView role={role} />;
  else if (view === "team") content = <window.TeamView />;
  else content = <window.DealsList role={role} onOpen={openDeal} onNew={() => setCreating(true)} />;

  return (
    <div className={"shell" + (inDeal && focus ? " shell--focus" : "")}>
      {!(inDeal && focus) && <window.Sidebar role={role} view={view} onView={(v) => setView(v)} onSignOut={onSignOut} inDeal={!!inDeal} onExitDeal={() => { /* stay in deal */ }} />}
      <div className="shell-main">
        <Topbar role={role} onSwitchRole={onSwitchRole} theme={theme} setTheme={setTheme} crumb={crumb} onBack={inDeal ? exitDeal : null} />
        <div style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column", overflowY: inDeal ? "hidden" : "auto" }}>{content}</div>
      </div>
      {creating && <window.CreateDeal role={role} onClose={() => setCreating(false)} onDone={(id) => { setCreating(false); setView("deal"); setToast("Deal created"); }} />}
      {toast && <Toast2 msg={toast} onDone={() => setToast(null)} />}
    </div>
  );
}

/* ---------------- root ---------------- */
function App() {
  const [auth, setAuth] = uS2(null);
  if (!auth) return <window.Login onLogin={(role) => setAuth({ role })} />;
  return <Shell role={auth.role} onSignOut={() => { window.location.href = "Tract Landing - Showcase.html"; }} onSwitchRole={(r) => setAuth({ role: r })} />;
}
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
