/* Stratum Leads — Operations Console. Source Playbooks: per source / county /
   adapter control. Two modes:
   • MOCK (offline): the rich read-only telemetry cards (run health, sparkline).
   • LIVE (?use_live): reads source_playbooks + localities from the DB and does
     full CRUD via the admin_* RPCs (0044) — add / edit / delete / enable, with a
     locality filter + add-locality (#4/#5). Credential values never appear — only
     the vault reference. UNIQUE top-level names (shared global scope — fmtUSD trap). */

const { NavItem, IconButton, Tabs, Button, Field, Card, Metric, StatusChip, Switch, SegmentedControl, EmptyState } = window.StratumLeadsDesignSystem_6367ed;
const { I } = window.OpsShared;

const PB_STATUS_TONE = { healthy: "success", degraded: "warning", blocked: "danger" };
const PB_STATUS_LABEL = { healthy: "Healthy", degraded: "Degraded", blocked: "Blocked" };
const PB_METHOD_TONE = { Playwright: "violet", API: "neutral", "Batch API": "info" };
const PB_CRED_TONE = { valid: "success", expiring: "warning", needs_reauth: "danger", none: "neutral" };
const PB_CRED_LABEL = { valid: "Valid", expiring: "Expiring soon", needs_reauth: "Re-auth required", none: "None" };
const PB_RUN_COLOR = { ok: "var(--success)", warn: "var(--warning)", fail: "var(--danger)" };

const PB_ADAPTER_OPTS = [{ value: "playwright", label: "Playwright" }, { value: "api", label: "API" }, { value: "batch_api", label: "Batch API" }];
const PB_ADAPTER_LABEL = { playwright: "Playwright", api: "API", batch_api: "Batch API" };
const PB_ADAPTER_TONE = { playwright: "violet", api: "neutral", batch_api: "info" };
const localityName = (localities, id) => (localities || []).find((l) => l.id === id)?.display_name || "—";

function PbSparkline({ history }) {
  return (
    <span style={{ display: "inline-flex", alignItems: "flex-end", gap: 3, height: 20 }} title="Last 12 runs">
      {history.map((r, i) => <span key={i} style={{ width: 5, height: r === "ok" ? 10 : r === "warn" ? 15 : 20, borderRadius: 2, background: PB_RUN_COLOR[r] }} />)}
    </span>);

}
function PbField({ label, children }) {
  return (
    <div>
      <span style={{ display: "block", fontSize: 10.5, color: "var(--text-muted)", marginBottom: 2, textTransform: "uppercase", letterSpacing: "0.03em" }}>{label}</span>
      <span style={{ fontSize: 13, fontWeight: 600 }}>{children}</span>
    </div>);

}

/* ---------------- MOCK telemetry card (unchanged) ---------------- */
function PlaybookCard({ s, enabled, onToggle }) {
  return (
    <Card style={{ opacity: enabled ? 1 : 0.62 }}>
      <div style={{ display: "grid", gap: 16 }}>
        <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, minWidth: 0 }}>
            <span style={{ width: 40, height: 40, flexShrink: 0, display: "grid", placeItems: "center", borderRadius: "var(--radius-md)", background: "var(--accent-soft)", color: "var(--accent)" }}>{I(s.method === "Playwright" ? "mouse-pointer-click" : s.method === "API" ? "plug" : "database", { width: 19 })}</span>
            <div style={{ minWidth: 0 }}>
              <strong style={{ fontSize: 15, fontWeight: 800, display: "block" }}>{s.name}</strong>
              <span style={{ fontSize: 12, color: "var(--text-muted)" }}>{s.kind} · {s.county}</span>
            </div>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <StatusChip tone={PB_METHOD_TONE[s.method] || "neutral"}>{s.method}</StatusChip>
            <StatusChip tone={PB_STATUS_TONE[s.status]} dot>{PB_STATUS_LABEL[s.status]}</StatusChip>
            <Switch checked={enabled} onChange={() => onToggle(s)} />
          </div>
        </div>
        {s.issue && <div style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 12px", borderRadius: "var(--radius-sm)", background: "var(--danger-soft)", color: "var(--danger)", fontSize: 12.5 }}>{I("alert-triangle", { width: 14 })} {s.issue}</div>}
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(150px,1fr))", gap: 14 }}>
          <PbField label="Schedule">{s.schedule}</PbField>
          <PbField label="Last run">{s.lastRun}</PbField>
          <PbField label="Next run">{s.nextRun}</PbField>
          <PbField label="Worker">{s.worker}</PbField>
          <PbField label="Backup method">{s.backupMethod}</PbField>
          <PbField label="Yield (last run)">{s.newCount.toLocaleString()} new / {s.discovered.toLocaleString()}</PbField>
        </div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, flexWrap: "wrap", paddingTop: 4, borderTop: "1px solid var(--border-subtle)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            {I("key-round", { width: 15, color: "var(--text-subtle)" })}
            <span style={{ fontSize: 12.5, fontFamily: "var(--font-mono)", color: "var(--text-muted)" }}>{s.credentialRef}</span>
            <StatusChip tone={PB_CRED_TONE[s.credentialStatus]} dot={s.credentialStatus !== "valid"}>{PB_CRED_LABEL[s.credentialStatus]}</StatusChip>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <span style={{ fontSize: 11.5, color: "var(--text-subtle)" }}>Run health</span>
            <PbSparkline history={s.runHistory} />
          </div>
        </div>
        {s.exceptions && s.exceptions.length > 0 &&
        <div style={{ display: "grid", gap: 6 }}>
            {s.exceptions.map((e, i) => <div key={i} style={{ display: "grid", gridTemplateColumns: "auto 1fr auto", gap: 10, alignItems: "center", fontSize: 12 }}><StatusChip tone={e.level === "error" ? "danger" : "warning"}>{e.level}</StatusChip><span style={{ color: "var(--text-muted)" }}>{e.message}</span><span style={{ fontSize: 11, color: "var(--text-subtle)", whiteSpace: "nowrap" }}>{e.at}</span></div>)}
          </div>}
      </div>
    </Card>);

}

/* ---------------- LIVE config card (CRUD) ---------------- */
function LivePlaybookCard({ pb, localities, onToggle, onEdit, onDelete }) {
  return (
    <Card style={{ opacity: pb.enabled ? 1 : 0.6 }}>
      <div style={{ display: "grid", gap: 14 }}>
        <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, minWidth: 0 }}>
            <span style={{ width: 38, height: 38, flexShrink: 0, display: "grid", placeItems: "center", borderRadius: "var(--radius-md)", background: "var(--accent-soft)", color: "var(--accent)" }}>{I(pb.adapter === "playwright" ? "mouse-pointer-click" : pb.adapter === "api" ? "plug" : "database", { width: 18 })}</span>
            <div style={{ minWidth: 0 }}>
              <strong style={{ fontSize: 15, fontWeight: 800, display: "block" }}>{pb.name}</strong>
              <span style={{ fontSize: 12, color: "var(--text-muted)" }}>{pb.kind} · {localityName(localities, pb.locality_id)}</span>
            </div>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <StatusChip tone={PB_ADAPTER_TONE[pb.adapter] || "neutral"}>{PB_ADAPTER_LABEL[pb.adapter] || pb.adapter}</StatusChip>
            <Switch checked={pb.enabled} onChange={() => onToggle(pb.source_key, !pb.enabled)} />
            <IconButton label="Edit" variant="ghost" onClick={() => onEdit(pb)}>{I("pencil", { width: 15 })}</IconButton>
            <IconButton label="Delete" variant="ghost" onClick={() => onDelete(pb)}>{I("trash-2", { width: 15 })}</IconButton>
          </div>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(150px,1fr))", gap: 14 }}>
          <PbField label="Source key"><code style={{ fontFamily: "var(--font-mono)", fontSize: 12 }}>{pb.source_key}</code></PbField>
          <PbField label="Schedule">{pb.schedule || "—"}</PbField>
          <PbField label="Region">{pb.region || "—"}</PbField>
          <PbField label="Backup method">{pb.backup_method || "—"}</PbField>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 10, paddingTop: 4, borderTop: "1px solid var(--border-subtle)" }}>
          {I("key-round", { width: 15, color: "var(--text-subtle)" })}
          <span style={{ fontSize: 12.5, fontFamily: "var(--font-mono)", color: "var(--text-muted)" }}>{pb.credential_ref || "no credential reference"}</span>
        </div>
      </div>
    </Card>);

}

/* ---------------- Edit / add drawer ---------------- */
function PlaybookDrawer({ pb, localities, onClose, onSave, onAddLocality }) {
  const isNew = !pb.source_key;
  const [f, setF] = React.useState(() => ({
    source_key: pb.source_key || "", name: pb.name || "", kind: pb.kind || "", adapter: pb.adapter || "playwright",
    locality_id: pb.locality_id || (localities[0] && localities[0].id) || "", region: pb.region || "", county: pb.county || "",
    credential_ref: pb.credential_ref || "", backup_method: pb.backup_method || "", schedule: pb.schedule || "", enabled: pb.enabled !== false,
  }));
  const [addingLoc, setAddingLoc] = React.useState(false);
  const [locState, setLocState] = React.useState("");
  const [locCounty, setLocCounty] = React.useState("");
  const set = (k) => (e) => setF((p) => ({ ...p, [k]: e.target ? e.target.value : e }));

  const save = () => {
    if (!f.source_key.trim() || !f.name.trim()) return;
    onSave({ ...f, source_key: f.source_key.trim() });
    onClose();
  };

  return (
    <SideDrawer title={isNew ? "New source adapter" : "Edit source adapter"} subtitle="Config only — credential values live in the vault; store just the reference." icon={I("book-open")} onClose={onClose} footer={
    <React.Fragment>
        <Button variant="secondary" onClick={onClose}>Cancel</Button>
        <Button variant="primary" icon={I("check", { width: 15 })} disabled={!f.source_key.trim() || !f.name.trim()} onClick={save}>{isNew ? "Create adapter" : "Save changes"}</Button>
      </React.Fragment>
    }>
      <Field label="Name" value={f.name} onChange={set("name")} placeholder="DC Recorder of Deeds" />
      <Field label="Source key" value={f.source_key} onChange={set("source_key")} placeholder="dc_recorder" disabled={!isNew} />
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
        <Field label="Kind" value={f.kind} onChange={set("kind")} placeholder="County Recorder" />
        <Field label="Adapter" as="select" value={f.adapter} onChange={set("adapter")}>
          {PB_ADAPTER_OPTS.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
        </Field>
      </div>
      <div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 6 }}>
          <span style={{ fontSize: 12.5, fontWeight: 700 }}>Locality</span>
          <button type="button" onClick={() => setAddingLoc((v) => !v)} style={{ border: "none", background: "transparent", color: "var(--accent)", fontSize: 12, fontWeight: 600, cursor: "pointer", fontFamily: "var(--font-sans)" }}>{addingLoc ? "Cancel" : "＋ Add locality"}</button>
        </div>
        {addingLoc ?
        <div style={{ display: "grid", gridTemplateColumns: "80px 1fr auto", gap: 8, alignItems: "end" }}>
            <Field label="State" value={locState} onChange={(e) => setLocState(e.target.value)} placeholder="MD" />
            <Field label="County" value={locCounty} onChange={(e) => setLocCounty(e.target.value)} placeholder="Montgomery County" />
            <Button size="sm" variant="secondary" disabled={!locState.trim() || !locCounty.trim()} onClick={() => {onAddLocality(locState.trim(), locCounty.trim(), "");setAddingLoc(false);setLocState("");setLocCounty("");}}>Add</Button>
          </div> :

        <Field as="select" value={f.locality_id} onChange={set("locality_id")}>
            <option value="">— none —</option>
            {localities.map((l) => <option key={l.id} value={l.id}>{l.display_name}</option>)}
          </Field>}
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
        <Field label="Region" value={f.region} onChange={set("region")} placeholder="Washington, DC" />
        <Field label="Schedule" value={f.schedule} onChange={set("schedule")} placeholder="Every 4h" />
      </div>
      <Field label="Credential reference (not the secret)" value={f.credential_ref} onChange={set("credential_ref")} placeholder="vault://dc/recorder-login" />
      <Field label="Backup method" value={f.backup_method} onChange={set("backup_method")} placeholder="PDF docket export (manual)" />
      <label style={{ display: "flex", alignItems: "center", gap: 10, fontSize: 13, fontWeight: 600 }}>
        <Switch checked={f.enabled} onChange={() => setF((p) => ({ ...p, enabled: !p.enabled }))} /> Enabled
      </label>
    </SideDrawer>);

}

/* ---------------- Page ---------------- */
function SourcePlaybooksPage({ live, sources, playbooks, localities, onNotify, onSave, onToggle, onDelete, onAddLocality }) {
  const [disabled, setDisabled] = React.useState({});
  const [editing, setEditing] = React.useState(null);   // playbook obj or {} for new
  const [locFilter, setLocFilter] = React.useState("all");
  const [confirmDel, setConfirmDel] = React.useState(null);
  React.useEffect(refresh, [disabled, editing, locFilter, confirmDel, playbooks]);

  /* ---- MOCK mode: the original read-only telemetry surface ---- */
  if (!live) {
    const toggle = (s) => {
      setDisabled((d) => ({ ...d, [s.id]: !d[s.id] }));
      onNotify && onNotify(disabled[s.id] ? "success" : "warning", disabled[s.id] ? "Adapter enabled" : "Adapter disabled", s.name);
    };
    const healthy = sources.filter((s) => s.status === "healthy").length;
    const attention = sources.filter((s) => s.status !== "healthy").length;
    const credAttention = sources.filter((s) => s.credentialStatus === "needs_reauth" || s.credentialStatus === "expiring").length;
    return (
      <div style={{ padding: 24, width: "100%", maxWidth: "var(--page-max)" }}>
        <PageHeader eyebrow="Lead Operations" title="Source Playbooks" description="Per source / county / adapter: schedule, credential reference, backup method, run health, and enable/disable. Credential values live in the vault — only their reference and validity show here." />
        <Reveal style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px,1fr))", gap: 14, marginBottom: 22 }}>
          <Metric icon={I("book-open")} value={sources.length} label="Adapters" accent="violet" />
          <Metric icon={I("circle-check")} value={healthy} label="Healthy" accent="green" />
          <Metric icon={I("alert-triangle")} value={attention} label="Need attention" accent="amber" />
          <Metric icon={I("key-round")} value={credAttention} label="Credential alerts" accent="amber" />
        </Reveal>
        <div style={{ display: "grid", gap: 16 }}>
          {sources.map((s, i) => <Reveal key={s.id} delay={i * 40}><PlaybookCard s={s} enabled={!disabled[s.id]} onToggle={toggle} /></Reveal>)}
        </div>
      </div>);

  }

  /* ---- LIVE mode: CRUD over source_playbooks + localities ---- */
  if (playbooks === null) return <div style={{ padding: 24 }}><EmptyState icon="book-open" title="Loading playbooks…" message="Reading the live source registry." /></div>;
  const rows = locFilter === "all" ? playbooks : playbooks.filter((p) => p.locality_id === locFilter);
  const enabled = playbooks.filter((p) => p.enabled).length;
  const pw = playbooks.filter((p) => p.adapter === "playwright").length;

  return (
    <div style={{ padding: 24, width: "100%", maxWidth: "var(--page-max)" }}>
      <PageHeader eyebrow="Lead Operations" title="Source Playbooks"
        description="Per source / county / adapter — add, edit, enable, or remove. Credential values live in the vault; only the reference shows here."
        actions={<Button variant="primary" icon={I("plus", { width: 15 })} onClick={() => setEditing({})}>New adapter</Button>} />

      <Reveal style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px,1fr))", gap: 14, marginBottom: 20 }}>
        <Metric icon={I("book-open")} value={playbooks.length} label="Adapters" accent="violet" />
        <Metric icon={I("power")} value={enabled} label="Enabled" accent="green" />
        <Metric icon={I("mouse-pointer-click")} value={pw} label="Playwright" accent="violet" />
        <Metric icon={I("map-pin")} value={(localities || []).length} label="Localities" accent="cyan" />
      </Reveal>

      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 16, flexWrap: "wrap" }}>
        <span style={{ fontSize: 12.5, fontWeight: 700, color: "var(--text-muted)" }}>Locality</span>
        <div style={{ minWidth: 220 }}>
          <Field as="select" value={locFilter} onChange={(e) => setLocFilter(e.target.value)}>
            <option value="all">All localities ({playbooks.length})</option>
            {(localities || []).map((l) => <option key={l.id} value={l.id}>{l.display_name} ({playbooks.filter((p) => p.locality_id === l.id).length})</option>)}
          </Field>
        </div>
      </div>

      {rows.length === 0 ?
      <EmptyState icon="book-open" title="No adapters here" message={locFilter === "all" ? "Add your first source adapter." : "No adapters in this locality yet."} action={<Button size="sm" variant="secondary" icon={I("plus", { width: 14 })} onClick={() => setEditing({})}>New adapter</Button>} /> :

      <div style={{ display: "grid", gap: 16 }}>
          {rows.map((pb, i) => <Reveal key={pb.source_key} delay={i * 30}><LivePlaybookCard pb={pb} localities={localities} onToggle={onToggle} onEdit={setEditing} onDelete={setConfirmDel} /></Reveal>)}
        </div>}

      {editing && <PlaybookDrawer pb={editing} localities={localities || []} onClose={() => setEditing(null)} onSave={onSave} onAddLocality={onAddLocality} />}

      {confirmDel &&
      <React.Fragment>
          <div onClick={() => setConfirmDel(null)} style={{ position: "fixed", inset: 0, zIndex: 80, background: "rgba(16,22,38,0.42)" }} />
          <div style={{ position: "fixed", top: "50%", left: "50%", transform: "translate(-50%,-50%)", zIndex: 81, width: "min(420px,92vw)", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: "var(--radius-md)", boxShadow: "var(--shadow-lg)", padding: 22, display: "grid", gap: 16 }}>
            <div><strong style={{ fontSize: 16 }}>Remove adapter?</strong><p style={{ margin: "6px 0 0", fontSize: 13, color: "var(--text-muted)" }}>Delete <b>{confirmDel.name}</b> (<code>{confirmDel.source_key}</code>). This can't be undone.</p></div>
            <div style={{ display: "flex", justifyContent: "flex-end", gap: 10 }}>
              <Button variant="secondary" onClick={() => setConfirmDel(null)}>Cancel</Button>
              <Button variant="danger" icon={I("trash-2", { width: 15 })} onClick={() => {onDelete(confirmDel.source_key);setConfirmDel(null);}}>Delete</Button>
            </div>
          </div>
        </React.Fragment>}
    </div>);

}

Object.assign(window, { OpsPlaybooks: { SourcePlaybooksPage } });
