/* Case workspace — header, stepper nav, and core stage screens.
 * Exposes window.CaseWorkspace (and stage screens via window).
 */

function CaseHeader({ c, onDataroom, onExport }) {
  const { STAGES, ROUTES } = window.VVE;
  return (
    <div className="card pad" style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 24 }}>
      <div style={{ minWidth: 0 }}>
        <div className="row gap8" style={{ marginBottom: 8 }}>
          <span className="mono tiny muted" style={{ whiteSpace: "nowrap" }}>{c.id}</span>
          <Badge tone="neutral" sm>{STAGES[c.stage]}</Badge>
          {c.blockers > 0 && <Badge tone="err" sm dot>{c.blockers} blocker</Badge>}
          {c.reviews > 0 && <Badge tone="warn" sm>{c.reviews} open review</Badge>}
        </div>
        <h1 className="page-title" style={{ fontSize: 26 }}>{c.vve}</h1>
        <div className="metaline" style={{ marginTop: 10 }}>
          <span><Icon name="mapPin" size={14} />{c.gemeente}, {c.provincie}</span>
          <span><Icon name="building" size={14} />{c.units} appartementsrechten</span>
          <span><Icon name="layers" size={14} />{c.type}</span>
        </div>
      </div>
      <div className="row gap8" style={{ flex: "0 0 auto" }}>
        <button className="btn outline sm" onClick={onDataroom}><Icon name="folder" size={15} />Dataroom</button>
        <button className="btn outline sm" onClick={onExport}><Icon name="lock" size={14} />Export</button>
      </div>
    </div>
  );
}

function Stepper({ stage, active, view, onPick, onOverview }) {
  const { STAGES } = window.VVE;
  return (
    <div className="row gap8" style={{ margin: "18px 0 20px", alignItems: "stretch" }}>
      <button className={"step-ov" + (view === "overzicht" ? " on" : "")} onClick={onOverview}>
        <Icon name="dashboard" size={16} /><span>Overzicht</span>
      </button>
      <div className="stepper" style={{ flex: 1 }}>
        {STAGES.map((s, i) => {
          const cls = i < stage ? "done" : i === stage ? "current" : "";
          const isActive = view === "stage" && i === active;
          const stat = i < stage ? "Afgerond" : i === stage ? "Huidige fase" : "Te doen";
          return (
            <div key={i} className={"step " + cls + (isActive ? " active" : "")} onClick={() => onPick(i)}>
              <div className="si">
                <span className="sdot">{i < stage ? "✓" : i + 1}</span>
                <span className="sname">{s}</span>
              </div>
              <div className="sstat">{stat}</div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ── Dossierstatus — readiness ring + gate-tracker (FR-09 completeness) ── */
const CASE_GATES = [
  { id: "G2", label: "Intake", state: "done" },
  { id: "G3", label: "Bronregels", state: "done" },
  { id: "G4", label: "Documenten", state: "open" },
  { id: "G5", label: "Scenario", state: "open" },
  { id: "G6", label: "ALV-pack", state: "blocked" },
  { id: "G7", label: "Formulieren", state: "blocked" },
  { id: "G8", label: "Export", state: "todo" },
];
const GATE_WEIGHT = { done: 1, open: 0.5, blocked: 0, todo: 0 };

function DossierStatus({ onGoto }) {
  const done = CASE_GATES.filter((g) => g.state === "done").length;
  const pct = Math.round(CASE_GATES.reduce((s, g) => s + GATE_WEIGHT[g.state], 0) / CASE_GATES.length * 100);
  const gico = { done: "check", open: "flag", blocked: "lock", todo: "dot" };
  const gtone = { done: "ok", open: "warn", blocked: "err", todo: "neutral" };
  return (
    <div className="card pad statusrow">
      <div className="sr-ring">
        <Ring pct={pct} tone={pct < 50 ? "warn" : "emerald"} />
        <div className="sr-ringlbl">
          <div className="sr-rl-t">Indieningsgereed</div>
          <div className="sr-rl-s">{done}/{CASE_GATES.length} gates voldaan</div>
        </div>
      </div>
      <div className="sr-divider"></div>
      <div className="sr-gates">
        <div className="sr-gates-head">
          <span>Goedkeuringsgates</span>
          <span className="tiny" style={{ color: "var(--st-err-fg)", fontWeight: 700, display: "inline-flex", alignItems: "center", gap: 6 }}>
            <span className="gpdot"></span>ALV en formulieren blokkeren export
          </span>
        </div>
        <div className="gatetrack">
          {CASE_GATES.map((g, i) => (
            <div key={g.id} className={"gate " + g.state} onClick={() => onGoto(g.state === "blocked" ? 3 : Math.min(i, 6))} title={g.id + " · " + g.label}>
              <span className={"gdisc " + gtone[g.state]}><Icon name={gico[g.state]} size={13} fill={g.state === "todo"} /></span>
              <span className="glabel">{g.label}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ── Overzicht ─────────────────────────────────────────────── */
function Overzicht({ c, onGoto }) {
  const { FACTS, FOCUS_ROUTES, REVIEW, AUDIT, ROUTES, DOCS } = window.VVE;
  const docTotals = DOCS.flatMap((g) => g.items);
  const okDocs = docTotals.filter((d) => d.status === "ok").length;
  const missingDocs = docTotals.filter((d) => d.status === "missing").length;
  const reviewDocs = docTotals.filter((d) => d.status === "review" || d.status === "expired").length;
  const topActions = REVIEW.slice(0, 3);

  return (
    <div>
      <DossierStatus onGoto={onGoto} />
      <div className="grid-2" style={{ marginTop: 18 }}>
      <div className="stack">
        <div className="banner ink">
          <Icon name="shield" size={20} style={{ flex: "0 0 auto", marginTop: 1, color: "var(--tge-emerald)" }} />
          <div>
            <div className="bt">Human checks, system creates</div>
            <div className="bd">Het systeem heeft de Warmtefonds route, checklist, ALV-concepten en exportstructuur voorbereid. Jeroen accordeert de laatste gates voordat het pakket handmatig kan worden ingediend.</div>
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <h3><Icon name="inbox" size={16} />Volgende acties</h3>
            <button className="btn ghost sm" onClick={() => onGoto(3)}>Naar review center<Icon name="arrowRight" size={14} /></button>
          </div>
          {topActions.map((r) => (
            <div className="lrow click" key={r.id} onClick={() => onGoto(3)}>
              <div className={"sdisc " + r.sev}>
                <Icon name={r.sev === "err" ? "alert" : r.sev === "warn" ? "flag" : "fileText"} size={16} />
              </div>
              <div className="lr-main">
                <div className="lr-title">{r.title}</div>
                <div className="lr-sub">{r.body}</div>
                <div className="metaline">
                  <span><Icon name="user" size={12} />{r.owner}</span>
                  <span className="mono">Gate {r.gate}</span>
                  {r.deadline && <span><Icon name="clock" size={12} />{new Date(r.deadline + "T00:00:00").toLocaleDateString("nl-NL", { day: "numeric", month: "short" })}</span>}
                </div>
              </div>
              <div className="lr-side"><Badge tone={r.sev} sm>{r.cat}</Badge></div>
            </div>
          ))}
        </div>

        <div className="card">
          <div className="card-head">
            <h3><Icon name="database" size={16} />Kerngegevens</h3>
            <span className="meta">Beweeg over een waarde voor bron & confidence</span>
          </div>
          <div className="facts">
            {FACTS.map((f) => (
              <div className="fact" key={f.k}>
                <div className="fk">{f.k}{f.conf == null && <Badge tone="err" sm>ontbreekt</Badge>}</div>
                <div className="fv">{f.v}</div>
                <div className="ev">
                  <span className="src">{f.src}</span>
                  {f.conf != null && <Conf value={f.conf} />}
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      <div className="stack">
        <div className="card">
          <div className="card-head">
            <h3><Icon name="route" size={16} />Routes</h3>
            <button className="btn ghost sm" onClick={() => onGoto(1)}>Routekaart<Icon name="arrowRight" size={14} /></button>
          </div>
          {FOCUS_ROUTES.slice(0, 4).map((r) => {
            const st = window.ROUTE_STATUS[r.status === "niet" ? "niet" : r.status];
            const def = ROUTES[r.key];
            return (
              <div className="lrow click" key={r.key} onClick={() => onGoto(1)} style={{ padding: "13px 18px" }}>
                <span className="sq" style={{ width: 10, height: 10, borderRadius: 2, background: def.color, marginTop: 5, flex: "0 0 auto" }}></span>
                <div className="lr-main">
                  <div className="lr-title" style={{ fontSize: 13.5 }}>{def.short}</div>
                  <div className="lr-sub tiny">{def.kind}</div>
                </div>
                <Badge tone={st.tone} sm dot>{st.label}</Badge>
              </div>
            );
          })}
        </div>

        <div className="card pad">
          <div className="row between" style={{ marginBottom: 12 }}>
            <h3 style={{ font: "700 14px var(--font-body)", margin: 0 }}>Dataroom</h3>
            <span className="tiny muted mono">{okDocs}/{docTotals.length} akkoord</span>
          </div>
          <div style={{ height: 8, background: "var(--tge-slate-100)", borderRadius: 2, overflow: "hidden" }}>
            <div style={{ width: (okDocs / docTotals.length * 100) + "%", height: "100%", background: "var(--tge-emerald)" }}></div>
          </div>
          <div className="row gap12 wrap" style={{ marginTop: 12 }}>
            <span className="tiny row gap6"><span className="sq" style={{ width: 8, height: 8, borderRadius: 2, background: "var(--st-err-fg)" }}></span>{missingDocs} ontbreken</span>
            <span className="tiny row gap6"><span className="sq" style={{ width: 8, height: 8, borderRadius: 2, background: "var(--st-warn-fg)" }}></span>{reviewDocs} onduidelijk / verlopen</span>
          </div>
        </div>

        <div className="card">
          <div className="card-head"><h3><Icon name="history" size={16} />Auditlog</h3></div>
          <div className="card-body" style={{ paddingTop: 6, paddingBottom: 6 }}>
            <div className="audit">
              {AUDIT.map((a, i) => (
                <div className="ai" key={i}>
                  <span className={"adot" + (a.em ? " em" : "")}></span>
                  <div><div className="atxt">{a.txt}</div><div className="atime">{a.time}</div></div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
    </div>
  );
}

/* ── Intake ────────────────────────────────────────────────── */
function IntakeScreen({ onGoto }) {
  const { FACTS } = window.VVE;
  return (
    <div className="stack">
      <div className="banner info">
        <Icon name="user" size={18} style={{ flex: "0 0 auto", marginTop: 1 }} />
        <div><div className="bt">Canonieke VvE-intake</div>
          <div className="bd">Route-onafhankelijke kernvelden. Vragen passen zich aan op antwoorden. Elke waarde krijgt een bron; routekritische gaten worden gemarkeerd.</div></div>
      </div>
      <div className="card">
        <div className="card-head"><h3><Icon name="database" size={16} />Kernvelden</h3><span className="meta">Bron per waarde · hover voor confidence</span></div>
        <div className="facts">
          {FACTS.map((f) => (
            <div className="fact" key={f.k}>
              <div className="fk">{f.k}{f.conf == null && <Badge tone="err" sm>routekritisch</Badge>}</div>
              <div className="fv" style={{ color: f.conf == null ? "var(--st-err-fg)" : "var(--fg1)" }}>{f.v}</div>
              <div className="ev"><span className="src">{f.src}</span>{f.conf != null && <Conf value={f.conf} />}</div>
            </div>
          ))}
        </div>
      </div>
      <div className="row between">
        <span className="tiny muted">Gate G2 · intake-bevestiging door adviseur vereist</span>
        <button className="btn primary" onClick={() => onGoto(1)}>Bevestig intake & bekijk routekaart<Icon name="arrowRight" size={15} /></button>
      </div>
    </div>
  );
}

/* ── Routekaart ────────────────────────────────────────────── */
function Routekaart() {
  const { FOCUS_ROUTES, ROUTES } = window.VVE;
  const [accepted, setAccepted] = React.useState({});
  const [inspected, setInspected] = React.useState(null);
  const [evaluating, setEvaluating] = React.useState(() => {
    try { return sessionStorage.getItem("vve_routes_eval_C020") !== "1"; } catch (e) { return true; }
  });
  React.useEffect(() => {
    if (!evaluating) return;
    const reduced = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const t = setTimeout(() => {
      setEvaluating(false);
      try { sessionStorage.setItem("vve_routes_eval_C020", "1"); } catch (e) {}
    }, reduced ? 0 : 1400);
    return () => clearTimeout(t);
  }, [evaluating]);

  if (evaluating) {
    return (
      <div className="stack">
        <div className="card">
          <div className="evaluating">
            <div className="spin"></div>
            <div className="et">Warmtefonds bronregels evalueren…</div>
            <div className="es">ruleset warmtefonds.vve_energiebespaarlening · 17 regels · NWF1/NWF2</div>
            <div className="elog">
              <span>✓ PDOK · gemeente Rotterdam, Zuid-Holland</span>
              <span>✓ KvK · actieve VvE, 12 appartementsrechten</span>
              <span>✓ Warmtefonds NWF1 · checklist en exportroute gematcht</span>
            </div>
          </div>
        </div>
      </div>
    );
  }
  return (
    <div className="stack">
      <div className="banner warn">
        <Icon name="route" size={18} style={{ flex: "0 0 auto", marginTop: 1 }} />
        <div><div className="bt">Objectieve route-kandidaten — geen advies</div>
          <div className="bd">Warmtefonds wordt hier behandeld als financieringsroute. De status komt uit versioned bronregels en blijft voor review tot Jeroen accordeert.</div></div>
      </div>
      {inspected && (
        <div className="banner info">
          <Icon name="database" size={18} style={{ flex: "0 0 auto", marginTop: 1 }} />
          <div><div className="bt">Onderzoek geopend: {inspected.title}</div>
            <div className="bd">Bron {inspected.bron} is gekoppeld aan deze route. Gebruik Bronnen & regels voor volledige rule-versie en refresh-log.</div></div>
        </div>
      )}
      <div className="card">
        {FOCUS_ROUTES.map((r, i) => {
          const st = window.ROUTE_STATUS[r.status];
          const def = ROUTES[r.key];
          const disc = st.tone;
          return (
            <div className="lrow route-reveal" key={r.key} style={{ animationDelay: (i * 70) + "ms" }}>
              <div className={"sdisc " + disc}>
                <Icon name={r.status === "mogelijk" ? "checkCircle" : r.status === "controle" ? "alert" : r.status === "niet" ? "xCircle" : r.status === "lokaal" ? "mapPin" : "lock"} size={17} />
              </div>
              <div className="lr-main">
                <div className="lr-title">
                  <span className="sq" style={{ width: 9, height: 9, borderRadius: 2, background: def.color }}></span>
                  {r.title}<Badge tone={st.tone} sm dot>{st.label}</Badge>
                </div>
                <div className="lr-sub" style={{ maxWidth: "62ch" }}>{r.reden}</div>
                <div className="metaline">
                  <span><Icon name="link" size={12} /><span className="mono">{r.bron}</span></span>
                  <span><Icon name="calendar" size={12} />gecontroleerd {r.checked}</span>
                  <span className={"fresh " + (r.fresh === "ok" ? "ok" : "stale")}>
                    <span className="fd"></span>{r.fresh === "ok" ? "bron actueel" : "bron verouderd"}
                  </span>
                </div>
                {r.missing.length > 0 && (
                  <div className="row gap6 wrap" style={{ marginTop: 9 }}>
                    <span className="tiny muted">Ontbreekt:</span>
                    {r.missing.map((m) => <Badge tone="neutral" sm key={m}>{m}</Badge>)}
                  </div>
                )}
              </div>
              <div className="lr-side">
                {r.confidence != null && <Conf value={r.confidence} />}
                {accepted[r.key] ? <Badge tone="ok" sm dot>Geaccepteerd</Badge> : r.approval === "needs"
                  ? <div className="row gap6">
                      <button className="btn outline sm" onClick={() => setInspected(r)}>Onderzoeken</button>
                      <button className="btn primary sm" onClick={() => setAccepted({ ...accepted, [r.key]: true })}>Accepteer</button>
                    </div>
                  : <span className="tiny muted">Systeembesluit</span>}
              </div>
            </div>
          );
        })}
      </div>
      <span className="tiny muted row gap6"><Icon name="shield" size={13} />Gate G5 · Jeroen bevestigt Warmtefonds NWF1, bronversie en open reviewpunten.</span>
    </div>
  );
}

/* ── Dataroom ──────────────────────────────────────────────── */
function Dataroom() {
  const { DOCS, ACTIVE_UPLOADS = [] } = window.VVE;
  const linkedUploadFor = (d) => ACTIVE_UPLOADS.find((u) => u.file === d.file || u.type === d.name);
  const previewDoc = (d) => {
    const upload = linkedUploadFor(d);
    window.openNotice && window.openNotice({
      eyebrow: "Documentpreview",
      title: d.name,
      body: upload
        ? "Dit is het werkelijk gekoppelde bestand uit deze sessie. De preview toont de bron, parser en extracties die de canonieke velden hebben bijgewerkt."
        : d.file ? "Statische demobron. Upload een echt bestand om PDF/XLSX preview en extractie-highlights te zien." : "Geen bestand gekoppeld.",
      items: [
        { icon: d.status === "ok" ? "fileCheck" : "flag", title: d.file || "Nog geen bestand", sub: d.req },
        { icon: "shield", title: "Status", sub: window.DOC_STATUS[d.status].label + (d.conf != null ? " · " + Math.round(d.conf * 100) + "% confidence" : "") },
        ...(upload ? [
          { icon: "database", title: "Parser", sub: upload.parser + " · " + (upload.rawChars || 0) + " tekens gelezen" },
          { icon: "fileText", title: "Checklist type", sub: upload.type + " → " + upload.target },
        ] : []),
      ],
      fields: upload && upload.fields,
      preview: upload && upload.preview,
    });
  };
  return (
    <div className="stack">
      <div className="row between wrap gap12">
        <div className="row gap8">
          <button className="btn outline sm" onClick={() => window.openUpload && window.openUpload()}><Icon name="upload" size={15} />Upload</button>
        </div>
        <span className="tiny muted">Statussen: ontbreekt · onduidelijk · verlopen · akkoord — adviseur kan overrulen met reden</span>
      </div>
      {ACTIVE_UPLOADS.length > 0 && (
        <div className="banner ink">
          <Icon name="fileCheck" size={18} style={{ flex: "0 0 auto", marginTop: 1, color: "var(--tge-emerald)" }} />
          <div>
            <div className="bt">{ACTIVE_UPLOADS.length} bestand(en) deze sessie gekoppeld</div>
            <div className="bd">{ACTIVE_UPLOADS.map((d) => d.file).join(" · ")}</div>
          </div>
        </div>
      )}
      <div className="card">
        {DOCS.map((g) => (
          <div key={g.group}>
            <div className="ghead"><span className="sq" style={{ background: g.color }}></span>{g.group}</div>
            {g.items.map((d) => {
              const ds = window.DOC_STATUS[d.status];
              return (
                <div className="doc" key={d.name}>
                  <div className={"sdisc " + ds.tone}><Icon name={ds.icon} size={16} /></div>
                  <div className="dn">
                    <b>{d.name}</b> <span className="req">· {d.req}</span>
                    <div className="df">{d.file || "— geen bestand —"}</div>
                  </div>
                  {d.conf != null && <Conf value={d.conf} />}
                  <Badge tone={ds.tone} sm dot>{ds.label}</Badge>
                  {d.status === "missing"
                    ? <button className="btn outline sm" onClick={() => window.openUpload && window.openUpload()}><Icon name="upload" size={13} />Uitvragen</button>
                    : <button className="btn ghost sm" onClick={() => previewDoc(d)}><Icon name="eye" size={14} />Bekijk</button>}
                </div>
              );
            })}
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { CaseHeader, Stepper, Overzicht, IntakeScreen, Routekaart, Dataroom });
