/* Compliance dashboard — Priya's home.
   Spec: 05-screen-specs.md §2 (EU AI Act Article 12).
   Adapted to HIPAA scenario. */

const COMPLIANCE_FRAMEWORKS = [
  { id: "hipaa", title: "HIPAA · Article 12 equivalent", active: true,
    sub: "Every PHI-touching AI call · tamper-evident · 6-year retention",
    metric: "100%", metricLabel: "logged", status: "compliant" },
  { id: "euai", title: "EU AI Act · Article 12", active: true,
    sub: "Tamper-evident logging for high-risk AI · effective Aug 2026",
    metric: "100%", metricLabel: "logged", status: "compliant" },
  { id: "fda", title: "FDA 21 CFR Part 11", active: true,
    sub: "Electronic records · e-signatures",
    metric: "6", metricLabel: "e-sigs this Q", status: "active" },
  { id: "soc2", title: "SOC 2 Type II", active: false,
    sub: "Q1 2027 — pending controls review",
    metric: "—", metricLabel: "not started", status: "inactive" },
];

const TOP_CONTRADICTED = [
  { idx: 1, text: "Initiate beta-blockers at maximum tolerated dose immediately on admission for HFrEF.", app: "Encounter Summary", count: 7, source: "AHA/ACC HF 2024 §7.3.3" },
  { idx: 2, text: "Metformin can be continued at standard doses with eGFR 25–30 mL/min/1.73m².", app: "Encounter Summary", count: 4, source: "FDA Metformin §5.1" },
  { idx: 3, text: "ICD-10 J45.40 covers severe persistent asthma without status asthmaticus.", app: "Discharge Plan", count: 3, source: "ICD-10-CM 2025 J45" },
  { idx: 4, text: "Routine post-discharge follow-up is recommended within 14 days for high-risk patients.", app: "Discharge Plan", count: 2, source: "Meridian Protocols §3.4" },
];

// Drift chart data — 90 days, four series. Bump in contradicted around day 60-72.
const DRIFT_DATA = (() => {
  const days = 90;
  const arr = [];
  for (let i = 0; i < days; i++) {
    const base = 280 + Math.sin(i / 5) * 20 + (i / 3);
    const v = base;
    const p = 14 + Math.sin(i / 4) * 4;
    const u = 5 + Math.cos(i / 6) * 2;
    let c = 4 + Math.cos(i / 7) * 1.5;
    if (i >= 58 && i <= 72) c += 8 + Math.sin((i - 58) / 2) * 3;  // anomaly spike
    arr.push([Math.round(v), Math.round(Math.max(8, p)), Math.round(Math.max(2, u)), Math.round(Math.max(0, c))]);
  }
  return arr;
})();

const verdictCol = {
  verified: "#2f6e47",
  partial: "#9a6418",
  unverif: "#71717a",
  contradicted: "#9b2c2c",
};

const ComplianceDashboard = ({ onOpenTrace, pushToast }) => {
  const [framework, setFramework] = React.useState("hipaa");
  const [showGenerate, setShowGenerate] = React.useState(false);

  return (
    <>
      <header className="page-header">
        <div className="page-header__inner">
          <div className="page-header__eyebrow">Workspace · Compliance</div>
          <h1>Compliance posture</h1>
          <p className="page-header__sub">
            Pre-built regulator views. Every wrapped call is tamper-evident, multi-judge verified, and anchored to a public bulletin.
          </p>
        </div>
        <div className="page-actions">
          <Button variant="secondary" size="sm" iconRight={window.Icon.chevronDown({ size: 12 })}>Last quarter</Button>
          <Button variant="primary" size="sm" icon={window.Icon.fileCheck({ size: 14 })} onClick={() => setShowGenerate(true)}>
            Generate evidence pack
          </Button>
        </div>
      </header>

      {/* Framework switcher */}
      <div className="framework-strip">
        {COMPLIANCE_FRAMEWORKS.map((f) => (
          <button
            key={f.id}
            className={`framework-tile ${framework === f.id ? "framework-tile--active" : ""} ${!f.active ? "framework-tile--inactive" : ""}`}
            onClick={() => f.active && setFramework(f.id)}
          >
            <div className="framework-tile__head">
              <span className="framework-tile__title">{f.title}</span>
              {f.active
                ? <Badge tone="sealed" icon={window.Icon.checkSimple({ size: 11 })}>Ready</Badge>
                : <Badge tone="neutral">Inactive</Badge>}
            </div>
            <div className="framework-tile__sub">{f.sub}</div>
            <div className="framework-tile__metric">
              <span className="framework-tile__num">{f.metric}</span>
              <span className="framework-tile__label">{f.metricLabel}</span>
            </div>
          </button>
        ))}
      </div>

      {/* Filter rail */}
      <div className="filter-rail">
        <div className="filter-rail__title">
          <span className="muted">Filters</span>
        </div>
        <FilterChip
          label="Time"
          options={[{ v: "q", label: "This quarter" }, { v: "30d", label: "Last 30 days" }, { v: "90d", label: "Last 90 days" }]}
          value="q" onChange={() => {}}
        />
        <FilterChip
          label="App"
          options={[{ v: "all", label: "All apps" }].concat(SCENARIO.apps.map((a) => ({ v: a.name, label: a.name })))}
          value="all" onChange={() => {}}
        />
        <FilterChip
          label="Verdict"
          options={[{ v: "all", label: "All" }, { v: "contra", label: "Contradicted only" }]}
          value="all" onChange={() => {}}
        />
        <FilterChip
          label="Risk tier"
          options={[{ v: "all", label: "High + Medium" }, { v: "high", label: "High only" }]}
          value="all" onChange={() => {}}
        />
        <div className="spacer" />
        <Button variant="ghost" size="sm" iconRight={window.Icon.chevronDown({ size: 12 })}>
          Saved view · <strong>Q3 audit prep</strong>
        </Button>
        <Button variant="ghost" size="sm" icon={window.Icon.plus({ size: 12 })}>Save</Button>
      </div>

      {/* Metric strip */}
      <div className="metric-grid">
        <ComplianceMetric label="Total calls" value="24,891" sub={<span className="delta-up">+18% vs last quarter</span>} />
        <ComplianceMetric label="Article 12 logged" value="100%" sub={<Badge tone="sealed" icon={window.Icon.checkSimple({ size: 10 })}>Compliant</Badge>} />
        <ComplianceMetric label="Open risks" value="5" sub={<span className="delta-up">↓ 11 from Q1</span>} />
        <ComplianceMetric label="Last bulletin" value={<span className="mono" style={{ fontSize: 24 }}>2026-10-24</span>} sub={<Badge tone="verified" icon={window.Icon.checkSimple({ size: 10 })}>Root verified</Badge>} />
      </div>

      {/* Verdict by app */}
      <div className="card" style={{ marginBottom: "var(--space-6)" }}>
        <div className="card__header">
          <h3>Verdict distribution by app</h3>
          <span className="meta">Last 90 days · drill in to investigate</span>
          <div className="spacer" />
          <Button variant="link" size="sm">View as table →</Button>
          <Button variant="link" size="sm">Export CSV</Button>
        </div>
        <div style={{ padding: "var(--space-4) var(--pad-card)" }}>
          {SCENARIO.apps.map((a, i) => {
            const pct = [96, 87, 61][i];
            const partial = [3, 8, 18][i];
            const unverif = [0.5, 3, 10][i];
            const contra = [0.5, 2, 11][i];
            const calls = [12410, 8190, 4291][i];
            const flag = pct < 80;
            return (
              <div key={a.name} className="app-row">
                <div className="app-row__head">
                  <span className="app-row__title">{a.name}</span>
                  <span className="muted text-xs mono">{calls.toLocaleString()} calls</span>
                  <div className="spacer" />
                  <span className="tabular fw-600" style={{ color: flag ? "var(--partial)" : "var(--ink-1)" }}>{pct}% verified</span>
                  {flag && <Badge tone="partial" icon={window.Icon.warning({ size: 10 })}>Watch</Badge>}
                </div>
                <div className="app-bar">
                  <div style={{ width: `${pct}%`, background: verdictCol.verified }} title={`Verified ${pct}%`} />
                  <div style={{ width: `${partial}%`, background: verdictCol.partial }} title={`Partial ${partial}%`} />
                  <div style={{ width: `${unverif}%`, background: verdictCol.unverif }} title={`Unverifiable ${unverif}%`} />
                  <div style={{ width: `${contra}%`, background: verdictCol.contradicted }} title={`Contradicted ${contra}%`} />
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {/* Drift chart */}
      <div className="card" style={{ marginBottom: "var(--space-6)" }}>
        <div className="card__header">
          <h3>Verdict drift over time</h3>
          <span className="meta">90 days · all apps</span>
          <div className="spacer" />
          <div className="legend" style={{ padding: 0, gap: "var(--space-3)" }}>
            <span className="legend__item"><span className="legend__swatch" style={{ background: verdictCol.verified }} /> Verified</span>
            <span className="legend__item"><span className="legend__swatch" style={{ background: verdictCol.partial }} /> Partial</span>
            <span className="legend__item"><span className="legend__swatch" style={{ background: verdictCol.unverif }} /> Unverif.</span>
            <span className="legend__item"><span className="legend__swatch" style={{ background: verdictCol.contradicted }} /> Contradicted</span>
          </div>
        </div>
        <div className="chart-area" style={{ height: 220 }}>
          <DriftArea data={DRIFT_DATA} w={1100} h={220} />
        </div>
        <div className="card__footer" style={{ background: "var(--partial-soft)", borderTop: "1px solid rgba(154, 100, 24, 0.2)" }}>
          <div className="row gap-2" style={{ flex: 1 }}>
            <span style={{ color: "var(--partial)" }}>{window.Icon.alertTriangle({ size: 13 })}</span>
            <span className="text-sm" style={{ color: "var(--ink-2)" }}>
              <strong>Anomaly detected:</strong> Encounter Summary contradiction rate rose <strong>3.1×</strong> Oct 14–18. Coincides with AHA HF guideline v2.2 publication.
            </span>
          </div>
          <Button variant="secondary" size="sm" iconRight={window.Icon.arrowRight({ size: 12 })}>Investigate</Button>
        </div>
      </div>

      {/* Top contradicted claims */}
      <Card title="Top contradicted claims" meta="Last 90 days · grouped by claim text"
        padded={false}
        action={<Button variant="link" size="sm" iconRight={window.Icon.arrowRight({ size: 12 })}>View all 47</Button>}
      >
        <table className="table">
          <thead>
            <tr>
              <th style={{ width: 36 }}>#</th>
              <th>Claim</th>
              <th>App</th>
              <th>Contradicted by</th>
              <th style={{ width: 90, textAlign: "right" }}>Count</th>
              <th style={{ width: 50 }} />
            </tr>
          </thead>
          <tbody>
            {TOP_CONTRADICTED.map((c) => (
              <tr key={c.idx} className="clickable" onClick={() => onOpenTrace && onOpenTrace()}>
                <td className="mono text-sm muted">{String(c.idx).padStart(2, "0")}</td>
                <td style={{ fontWeight: 500, maxWidth: 480 }}>
                  <div className="truncate" style={{ maxWidth: 480 }}>{c.text}</div>
                </td>
                <td>{c.app}</td>
                <td><span className="mono text-xs muted">{c.source}</span></td>
                <td className="mono tabular" style={{ textAlign: "right" }}>{c.count}</td>
                <td style={{ color: "var(--ink-4)" }}>{window.Icon.chevronRight({ size: 14 })}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </Card>

      <GenerateEvidenceModal open={showGenerate} onClose={() => setShowGenerate(false)} pushToast={pushToast} />
    </>
  );
};

const ComplianceMetric = ({ label, value, sub }) => (
  <div className="metric">
    <div className="metric__label">{label}</div>
    <div className="metric__value">{value}</div>
    <div className="metric__sub">{sub}</div>
  </div>
);

const DriftArea = ({ data, w, h }) => {
  const total = data.length;
  const innerW = w - 30;
  const innerH = h - 30;
  const dx = innerW / (total - 1);
  const maxT = Math.max(...data.map((r) => r.reduce((a, b) => a + b, 0)));
  const cols = [verdictCol.verified, verdictCol.partial, verdictCol.unverif, verdictCol.contradicted];

  const paths = cols.map((_, s) => {
    let p = "";
    data.forEach((row, i) => {
      const top = row.slice(0, s + 1).reduce((a, b) => a + b, 0);
      const y = innerH - (top / maxT) * innerH;
      p += `${i === 0 ? "M" : "L"} ${15 + i * dx} ${10 + y} `;
    });
    for (let i = total - 1; i >= 0; i--) {
      const bot = s === 0 ? 0 : data[i].slice(0, s).reduce((a, b) => a + b, 0);
      const y = innerH - (bot / maxT) * innerH;
      p += `L ${15 + i * dx} ${10 + y} `;
    }
    p += "Z";
    return <path key={s} d={p} fill={cols[s]} fillOpacity={s === 0 ? 0.18 : 0.7} stroke={cols[s]} strokeWidth={s === 0 ? 1 : 0} />;
  });

  // Anomaly marker — vertical band around days 58-72
  const x1 = 15 + 58 * dx;
  const x2 = 15 + 72 * dx;
  return (
    <svg viewBox={`0 0 ${w} ${h}`} width="100%" height={h} className="stacked-area">
      <rect x={x1} y="10" width={x2 - x1} height={innerH} fill="rgba(154, 100, 24, 0.08)" />
      <line x1={(x1 + x2) / 2} y1="10" x2={(x1 + x2) / 2} y2={10 + innerH} stroke="rgba(154, 100, 24, 0.4)" strokeDasharray="3 3" />
      {[0.25, 0.5, 0.75, 1].map((t) => (
        <line key={t} x1="15" y1={10 + innerH * (1 - t)} x2={w - 15} y2={10 + innerH * (1 - t)} stroke="var(--rule)" strokeDasharray="2 4" />
      ))}
      {paths}
      <text x={(x1 + x2) / 2} y="20" fontFamily="Geist Mono, monospace" fontSize="9" fill="var(--partial)" textAnchor="middle" letterSpacing="1">ANOMALY · OCT 14–18</text>
      {[0, 30, 60, 89].map((i) => (
        <text key={i} x={15 + i * dx} y={h - 6} fontSize="10" fill="var(--ink-4)" textAnchor="middle" fontFamily="Geist Mono, monospace">
          Day {i + 1}
        </text>
      ))}
    </svg>
  );
};

/* Generate evidence pack — multi-stage modal */
const GenerateEvidenceModal = ({ open, onClose, pushToast }) => {
  const [stage, setStage] = React.useState("scope");
  const [scope, setScope] = React.useState({ range: "q3", apps: "all", includePartial: true });
  const [progress, setProgress] = React.useState({ step: 0, pct: 0 });

  React.useEffect(() => {
    if (stage !== "generating") return;
    const steps = ["Extracting verdicts", "Packaging artifacts", "Signing chain", "Building PDF"];
    let s = 0; let p = 0;
    const tick = setInterval(() => {
      p += 6 + Math.random() * 10;
      if (p >= 100 && s < steps.length - 1) { s++; p = 0; }
      else if (p >= 100 && s === steps.length - 1) {
        clearInterval(tick);
        setStage("ready");
        return;
      }
      setProgress({ step: s, pct: Math.min(100, p) });
    }, 250);
    return () => clearInterval(tick);
  }, [stage]);

  React.useEffect(() => {
    if (open) { setStage("scope"); setProgress({ step: 0, pct: 0 }); }
  }, [open]);

  const steps = ["Extracting verdicts", "Packaging artifacts", "Signing chain", "Building PDF"];

  return (
    <Modal
      open={open}
      onClose={onClose}
      title={stage === "scope" ? "Generate evidence pack" : stage === "generating" ? "Generating…" : "Evidence pack ready"}
      sub={stage === "scope" ? "Bundle of verified calls + signed chain + auditor-readable PDF." : stage === "generating" ? "Tamper-evident. Ed25519 + daily bulletin anchor." : "Hash sealed. Sharable with auditor or downloadable as .zip."}
      wide
      footer={stage === "scope" ? (
        <>
          <Button variant="ghost" onClick={onClose}>Cancel</Button>
          <Button variant="primary" onClick={() => setStage("generating")} icon={window.Icon.fileCheck({ size: 14 })}>
            Generate pack
          </Button>
        </>
      ) : stage === "ready" ? (
        <>
          <Button variant="ghost" onClick={onClose}>Done</Button>
          <Button variant="primary" icon={window.Icon.download({ size: 14 })}
            onClick={() => { onClose(); pushToast({ kind: "success", title: "Evidence pack downloaded", sub: "Q3 2026 HIPAA audit pack · 8,247 calls · 47 pages." }); }}>
            Download .zip bundle
          </Button>
        </>
      ) : null}
    >
      {stage === "scope" && (
        <div className="col gap-4">
          <Field label="Time range">
            <div className="radio-row">
              <RadioCard selected={scope.range === "q3"} title="Q3 2026" sub="Jul 1 – Sep 30 · 8,247 calls" onClick={() => setScope({ ...scope, range: "q3" })} />
              <RadioCard selected={scope.range === "30d"} title="Last 30 days" sub="2,418 calls" onClick={() => setScope({ ...scope, range: "30d" })} />
              <RadioCard selected={scope.range === "custom"} title="Custom range" sub="Pick start + end dates" onClick={() => setScope({ ...scope, range: "custom" })} />
            </div>
          </Field>
          <Field label="Apps">
            <div className="radio-row">
              <RadioCard selected={scope.apps === "all"} title="All apps" sub="3 active" onClick={() => setScope({ ...scope, apps: "all" })} />
              <RadioCard selected={scope.apps === "select"} title="Select" sub="Choose specific apps" onClick={() => setScope({ ...scope, apps: "select" })} />
            </div>
          </Field>
          <Field label="Coverage">
            <label className="row gap-2" style={{ padding: 10, border: "1px solid var(--rule)", borderRadius: "var(--radius-md)", cursor: "pointer" }}>
              <input type="checkbox" checked={scope.includePartial} onChange={(e) => setScope({ ...scope, includePartial: e.target.checked })} />
              <div>
                <div className="fw-600 text-sm">Include partially-verified calls</div>
                <div className="text-xs muted">Recommended. Auditors prefer complete coverage with verdict breakdown.</div>
              </div>
            </label>
          </Field>
          <div className="onb-note">
            <span>{window.Icon.shield({ size: 14 })}</span>
            <div className="text-sm">
              Generated pack includes: PDF summary (≈47 pages), signed JSON manifest, replay-bundle.zip with offline-verify CLI.
              Output hash is added to today's bulletin.
            </div>
          </div>
        </div>
      )}

      {stage === "generating" && (
        <div className="col gap-4">
          <div className="indexing-stages">
            {steps.map((label, i) => (
              <IndexStageX key={i} label={label} done={i < progress.step} active={i === progress.step} />
            ))}
          </div>
          <div className="progress">
            <div className="progress__bar" style={{ width: `${(progress.step * 25) + progress.pct * 0.25}%` }} />
          </div>
          <div className="text-xs muted mono" style={{ textAlign: "center" }}>
            {steps[progress.step]} · {Math.round(progress.pct)}% · ETA {Math.max(1, Math.round((100 - progress.pct) / 12) + (steps.length - 1 - progress.step) * 4)}s
          </div>
        </div>
      )}

      {stage === "ready" && (
        <div className="col gap-4">
          <div className="share-success" style={{ background: "var(--verified-soft)" }}>
            <div className="share-success__icon">{window.Icon.lock({ size: 22 })}</div>
            <div>
              <div className="share-success__title"><em style={{ fontStyle: "italic", fontFamily: "var(--font-display)", fontSize: 22 }}>Pack sealed.</em></div>
              <div className="share-success__sub">
                Q3 2026 HIPAA audit pack · 8,247 calls · 47 pages.
                Pack hash <span className="mono">5e8f9c…b21a</span> · anchored to bulletin 2026-10-24.
              </div>
            </div>
          </div>
          <div className="share-meta">
            <div className="share-meta__row"><span>Verdict mix</span>
              <span>
                <Verdict kind="verified" /> 92.3% · <Verdict kind="partial" /> 4.7% · <Verdict kind="unverif" /> 1.6% · <Verdict kind="contra" /> 1.4%
              </span>
            </div>
            <div className="share-meta__row"><span>Pack hash</span><HashChip value="5e8f9c…b21a" short="5e8f9c…b21a" /></div>
            <div className="share-meta__row"><span>Generated</span><span>{new Date().toLocaleString("en-US", { dateStyle: "medium", timeStyle: "short" })}</span></div>
          </div>
        </div>
      )}
    </Modal>
  );
};

// Local IndexStage (reused name avoidance — source-upload defines window-scope IndexStage already)
const IndexStageX = ({ label, done, active }) => (
  <div className={`index-stage ${done ? "index-stage--done" : ""} ${active ? "index-stage--active" : ""}`}>
    <div className="index-stage__icon">
      {done ? window.Icon.checkSimple({ size: 11 }) : active ? <span className="pulse-dot" /> : null}
    </div>
    <div className="index-stage__label">{label}</div>
  </div>
);

// Filter chip used here — TracesList has its own; copy minimal version.
const FilterChip = ({ label, options, value, onChange }) => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const onClick = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onClick);
    return () => document.removeEventListener("mousedown", onClick);
  }, []);
  const current = options.find((o) => o.v === value);
  return (
    <div ref={ref} style={{ position: "relative" }}>
      <button className={`filter-chip ${(value !== "all" && value !== "q") ? "filter-chip--active" : ""}`} onClick={() => setOpen((o) => !o)}>
        <span className="muted">{label}:</span>
        <span>{current?.label}</span>
        {window.Icon.chevronDown({ size: 12 })}
      </button>
      {open && (
        <div style={{ position: "absolute", top: "calc(100% + 4px)", left: 0, zIndex: 200, background: "var(--paper)", border: "1px solid var(--rule)", borderRadius: "var(--radius-md)", padding: 4, minWidth: 180, boxShadow: "var(--shadow-md)" }}>
          {options.map((o) => (
            <button key={o.v} onClick={() => { onChange(o.v); setOpen(false); }}
              style={{ width: "100%", padding: "8px 10px", fontSize: 13, background: value === o.v ? "var(--paper-alt)" : "transparent", border: "none", borderRadius: 4, textAlign: "left", color: "var(--ink-1)", fontWeight: value === o.v ? 600 : 400 }}>
              {o.label}
            </button>
          ))}
        </div>
      )}
    </div>
  );
};

window.ComplianceDashboard = ComplianceDashboard;
window.GenerateEvidenceModal = GenerateEvidenceModal;
