// Agents view — non-technical playbook builder for L1/L2 investigation assistants.
//
// Agents here are declarative specs (trigger, steps, data access, outputs, guardrails) —
// plain-English playbooks an analyst can author without writing code. The AI execution
// layer isn't wired up yet (see the AI Assist chat in the top bar); this is where the
// instructions it will run get authored and managed in the meantime.

const { useState: useAgState, useMemo: useAgMemo, useEffect: useAgEffect } = React;

const AGENT_STORAGE_KEY = "mossad_agents_v1";

const TRIGGER_OPTIONS = [
  { value: "new_alert",  label: "When a new alert is created" },
  { value: "case_open",  label: "When an analyst opens a case" },
  { value: "escalation", label: "When a case is escalated to L2" },
  { value: "scheduled",  label: "On a schedule (e.g. daily)" },
  { value: "on_demand",  label: "On demand — analyst asks" },
];

const DATA_SOURCE_OPTIONS = [
  { key: "transactions", label: "Transaction history" },
  { key: "kyc",           label: "Customer / KYC profile" },
  { key: "priorCases",    label: "Prior alerts & cases" },
  { key: "watchlists",    label: "Watchlists" },
  { key: "riskRatings",   label: "Risk ratings" },
  { key: "network",       label: "Network / entity links" },
  { key: "sarHistory",    label: "SAR history" },
];

const OUTPUT_OPTIONS = [
  { key: "summary",    label: "Draft summary" },
  { key: "riskLevel",  label: "Recommended risk level" },
  { key: "nextAction", label: "Suggested next action" },
  { key: "sarDraft",   label: "Draft SAR narrative" },
  { key: "citations",  label: "Evidence citations" },
];

const GUARDRAIL_OPTIONS = [
  { key: "citeEvidence",    label: "Always cite source records" },
  { key: "noAutoAction",    label: "Never auto-close, auto-escalate, or auto-file — analyst approves every action" },
  { key: "flagUncertainty", label: "Flag uncertainty instead of guessing" },
  { key: "humanSignoff",    label: "Require analyst sign-off before output is used" },
];

const AGENT_STATUS_PILL = { active: "ok", draft: "med", paused: "warn" };

const AGENT_TEMPLATES = {
  l1_triage: {
    name: "L1 Alert Triage Assistant",
    level: "L1",
    status: "active",
    description: "Gives first-line analysts a fast, structured read on a new alert so they can triage in seconds instead of minutes.",
    trigger: "new_alert",
    steps: [
      "Summarize the alert: which rule fired, why, and the transaction(s) involved.",
      "Pull the customer's profile and recent transaction history for context.",
      "Check if the customer or counterparties appear on any watchlist.",
      "Look for prior alerts or cases on this entity in the last 12 months.",
      "Suggest a disposition — escalate to L2, request more info, or close as false positive — with reasoning.",
    ],
    dataSources: ["transactions", "kyc", "priorCases", "watchlists"],
    outputs: ["summary", "riskLevel", "nextAction", "citations"],
    guardrails: ["citeEvidence", "noAutoAction", "flagUncertainty", "humanSignoff"],
  },
  l2_deepdive: {
    name: "L2 Deep-Dive Investigator",
    level: "L2",
    status: "active",
    description: "Helps senior investigators build a full picture of an entity before deciding whether to escalate to a SAR.",
    trigger: "escalation",
    steps: [
      "Build a timeline of the entity's transactions and alerts across the case window.",
      "Identify related entities — shared counterparties, addresses, devices — and map the network.",
      "Compare transaction patterns against known typologies (structuring, layering, rapid movement of funds).",
      "Summarize findings from prior case notes and comments on this entity.",
      "Draft an investigation narrative with supporting evidence for the case file.",
    ],
    dataSources: ["transactions", "kyc", "priorCases", "watchlists", "riskRatings", "network", "sarHistory"],
    outputs: ["summary", "riskLevel", "nextAction", "sarDraft", "citations"],
    guardrails: ["citeEvidence", "noAutoAction", "flagUncertainty", "humanSignoff"],
  },
  sar_drafter: {
    name: "SAR Narrative Drafter",
    level: "L2",
    status: "draft",
    description: "Turns an investigator's case evidence into a structured first-draft SAR narrative for review.",
    trigger: "on_demand",
    steps: [
      "Gather the case's alerts, transactions, and investigator notes.",
      "Organize findings into the standard SAR narrative structure (who / what / when / where / why suspicious).",
      "Cite every factual claim to a specific transaction, alert, or note.",
      "Flag any gaps in evidence the investigator should fill in before filing.",
    ],
    dataSources: ["transactions", "kyc", "priorCases", "sarHistory"],
    outputs: ["sarDraft", "citations"],
    guardrails: ["citeEvidence", "noAutoAction", "humanSignoff"],
  },
  periodic_review: {
    name: "Periodic Review Assistant",
    level: "L1",
    status: "draft",
    description: "Summarizes what's changed for customers due for periodic review, so analysts start with context instead of a blank file.",
    trigger: "scheduled",
    steps: [
      "List customers due for periodic review in the next 7 days.",
      "Summarize changes in risk score, transaction behavior, and KYC data since the last review.",
      "Flag anything that should accelerate the review — new adverse media, watchlist hits, etc.",
    ],
    dataSources: ["kyc", "riskRatings", "watchlists", "transactions"],
    outputs: ["summary", "riskLevel"],
    guardrails: ["citeEvidence", "flagUncertainty", "humanSignoff"],
  },
};

function loadAgents() {
  try {
    const raw = localStorage.getItem(AGENT_STORAGE_KEY);
    if (raw) return JSON.parse(raw);
  } catch (e) {}
  return Object.entries(AGENT_TEMPLATES).map(([id, tpl], i) => ({
    id, ...tpl, updated: new Date(Date.now() - i * 86400000).toISOString(),
  }));
}

function saveAgents(agents) {
  try { localStorage.setItem(AGENT_STORAGE_KEY, JSON.stringify(agents)); } catch (e) {}
}

function triggerLabel(v) {
  return (TRIGGER_OPTIONS.find(t => t.value === v) || {}).label || v;
}

function ChkChip({ label, on, onClick }) {
  return (
    <button type="button" className={`chk-chip ${on ? "on" : ""}`} onClick={onClick}>
      <span className="chk-box">{on && <Icon.Check size={11} />}</span>
      {label}
    </button>
  );
}

function AgentEditor({ agent, onSave, onCancel }) {
  const isNew = !agent;
  const [form, setForm] = useAgState(() => agent ? { ...agent } : {
    name: "", level: "L1", status: "draft", description: "",
    trigger: "new_alert",
    steps: [""],
    dataSources: [], outputs: [], guardrails: ["citeEvidence", "noAutoAction", "humanSignoff"],
  });
  const [error, setError] = useAgState(null);

  const update = (key, value) => setForm(f => ({ ...f, [key]: value }));
  const toggleIn = (key, value) => setForm(f => ({
    ...f,
    [key]: f[key].includes(value) ? f[key].filter(v => v !== value) : [...f[key], value],
  }));

  const updateStep = (i, value) => setForm(f => ({ ...f, steps: f.steps.map((s, idx) => idx === i ? value : s) }));
  const addStep = () => setForm(f => ({ ...f, steps: [...f.steps, ""] }));
  const removeStep = (i) => setForm(f => ({ ...f, steps: f.steps.length > 1 ? f.steps.filter((_, idx) => idx !== i) : f.steps }));
  const moveStep = (i, dir) => setForm(f => {
    const steps = [...f.steps];
    const j = i + dir;
    if (j < 0 || j >= steps.length) return f;
    [steps[i], steps[j]] = [steps[j], steps[i]];
    return { ...f, steps };
  });

  const applyTemplate = (tpl) => setForm(f => ({ ...f, ...tpl, steps: [...tpl.steps] }));

  const submit = (status) => {
    if (!form.name.trim()) { setError("Give the agent a name."); return; }
    if (!form.steps.some(s => s.trim())) { setError("Add at least one step."); return; }
    setError(null);
    onSave({
      ...form,
      status,
      steps: form.steps.map(s => s.trim()).filter(Boolean),
      updated: new Date().toISOString(),
    });
  };

  return (
    <div className="card" style={{ margin: "18px auto", maxWidth: 820, maxHeight: "calc(100vh - 120px)", overflow: "auto", display: "flex", flexDirection: "column" }}>
      <div className="card-hd" style={{ flexShrink: 0 }}>
        <h3>{isNew ? "New agent" : "Edit agent"}</h3>
        <span className="spacer" />
        <button className="btn ghost sm" onClick={onCancel}>Cancel</button>
      </div>
      <div className="card-body" style={{ display: "flex", flexDirection: "column", gap: 22, overflow: "auto", paddingBottom: 24 }}>
        {error && <div style={{ color: "var(--risk-high)", fontSize: 12.5 }}>{error}</div>}

        {isNew && (
          <div>
            <label style={{ display: "block", fontSize: 11.5, color: "var(--fg-3)", marginBottom: 6 }}>Start from a template</label>
            <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
              {Object.values(AGENT_TEMPLATES).map(tpl => (
                <button key={tpl.name} type="button" className="btn sm" onClick={() => applyTemplate(tpl)}>
                  {tpl.name}
                </button>
              ))}
            </div>
          </div>
        )}

        <div>
          <div className="ag-step-hd"><span className="ag-step-badge">1</span> Basics</div>
          <div style={{ display: "grid", gridTemplateColumns: "2fr 1fr", gap: 12, marginBottom: 10 }}>
            <div>
              <label style={{ display: "block", fontSize: 11.5, color: "var(--fg-3)", marginBottom: 4 }}>Agent name</label>
              <input className="field" value={form.name} onChange={e => update("name", e.target.value)} placeholder="e.g. L1 Alert Triage Assistant" />
            </div>
            <div>
              <label style={{ display: "block", fontSize: 11.5, color: "var(--fg-3)", marginBottom: 4 }}>Level</label>
              <select className="field" value={form.level} onChange={e => update("level", e.target.value)}>
                <option value="L1">L1 — First-line triage</option>
                <option value="L2">L2 — Deep investigation</option>
              </select>
            </div>
          </div>
          <label style={{ display: "block", fontSize: 11.5, color: "var(--fg-3)", marginBottom: 4 }}>What does it help with? (one line)</label>
          <input className="field" value={form.description} onChange={e => update("description", e.target.value)} placeholder="e.g. Summarizes a new alert and suggests a disposition" />
        </div>

        <div>
          <div className="ag-step-hd"><span className="ag-step-badge">2</span> When should it run?</div>
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
            {TRIGGER_OPTIONS.map(t => (
              <ChkChip key={t.value} label={t.label} on={form.trigger === t.value} onClick={() => update("trigger", t.value)} />
            ))}
          </div>
        </div>

        <div>
          <div className="ag-step-hd">
            <span className="ag-step-badge">3</span> What should it do?
            <span className="muted" style={{ fontWeight: 400, fontSize: 11.5, marginLeft: 6 }}>— plain-English steps, in order</span>
          </div>
          {form.steps.map((s, i) => (
            <div className="step-row" key={i}>
              <span className="step-num">{i + 1}</span>
              <input className="field" value={s} onChange={e => updateStep(i, e.target.value)} placeholder="e.g. Check if the counterparty appears on any watchlist" />
              <button type="button" className="btn ghost icon sm" disabled={i === 0} onClick={() => moveStep(i, -1)} title="Move up"><Icon.ChevronU size={12} /></button>
              <button type="button" className="btn ghost icon sm" disabled={i === form.steps.length - 1} onClick={() => moveStep(i, 1)} title="Move down"><Icon.ChevronD size={12} /></button>
              <button type="button" className="btn ghost icon sm" onClick={() => removeStep(i)} title="Remove step"><Icon.X size={12} /></button>
            </div>
          ))}
          <button type="button" className="btn sm" onClick={addStep}><Icon.Plus size={11} /> Add step</button>
        </div>

        <div>
          <div className="ag-step-hd">
            <span className="ag-step-badge">4</span> What can it read?
            <span className="muted" style={{ fontWeight: 400, fontSize: 11.5, marginLeft: 6 }}>— read-only access</span>
          </div>
          <div className="chk-grid">
            {DATA_SOURCE_OPTIONS.map(o => (
              <ChkChip key={o.key} label={o.label} on={form.dataSources.includes(o.key)} onClick={() => toggleIn("dataSources", o.key)} />
            ))}
          </div>
        </div>

        <div>
          <div className="ag-step-hd"><span className="ag-step-badge">5</span> What should it produce?</div>
          <div className="chk-grid">
            {OUTPUT_OPTIONS.map(o => (
              <ChkChip key={o.key} label={o.label} on={form.outputs.includes(o.key)} onClick={() => toggleIn("outputs", o.key)} />
            ))}
          </div>
        </div>

        <div>
          <div className="ag-step-hd"><span className="ag-step-badge">6</span> Guardrails</div>
          <div className="chk-grid" style={{ gridTemplateColumns: "1fr" }}>
            {GUARDRAIL_OPTIONS.map(o => (
              <ChkChip key={o.key} label={o.label} on={form.guardrails.includes(o.key)} onClick={() => toggleIn("guardrails", o.key)} />
            ))}
          </div>
        </div>

        <div style={{ display: "flex", gap: 8, justifyContent: "flex-end", borderTop: "1px solid var(--border)", paddingTop: 16 }}>
          <button type="button" className="btn sm" onClick={() => submit("draft")}>Save as draft</button>
          <button type="button" className="btn primary sm" onClick={() => submit("active")}>Save & activate</button>
        </div>
      </div>
    </div>
  );
}

function AgentCard({ agent, onEdit, onDuplicate, onToggleStatus, onDelete }) {
  return (
    <div className="card">
      <div style={{ display: "flex", alignItems: "flex-start", gap: 10, marginBottom: 10 }}>
        <div style={{ flex: 1 }}>
          <div style={{ fontWeight: 600, fontSize: 14 }}>{agent.name}</div>
          <div style={{ fontSize: 11.5, color: "var(--fg-3)", marginTop: 2 }}>{triggerLabel(agent.trigger)}</div>
        </div>
        <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
          <span className={`pill ${agent.level === "L2" ? "outline" : "info"}`}>{agent.level}</span>
          <span className={`pill ${AGENT_STATUS_PILL[agent.status] || agent.status}`}>{agent.status}</span>
        </div>
      </div>

      {agent.description && (
        <div style={{ fontSize: 12, color: "var(--fg-2)", marginBottom: 10 }}>{agent.description}</div>
      )}

      <div style={{ fontSize: 11.5, color: "var(--fg-3)", marginBottom: 8 }}>
        {agent.steps.length} step{agent.steps.length === 1 ? "" : "s"}
      </div>
      <ol style={{ margin: "0 0 10px", paddingLeft: 18, fontSize: 12, color: "var(--fg-2)", lineHeight: 1.6 }}>
        {agent.steps.slice(0, 3).map((s, i) => <li key={i}>{s}</li>)}
        {agent.steps.length > 3 && <li className="muted">+{agent.steps.length - 3} more…</li>}
      </ol>

      {agent.dataSources.length > 0 && (
        <div style={{ display: "flex", flexWrap: "wrap", gap: 4, marginBottom: 10 }}>
          {agent.dataSources.map(k => (
            <span key={k} className="pill outline">{(DATA_SOURCE_OPTIONS.find(o => o.key === k) || {}).label || k}</span>
          ))}
        </div>
      )}

      <div style={{ display: "flex", gap: 8, marginTop: 12, flexWrap: "wrap" }}>
        <button className="btn sm" onClick={() => onEdit(agent)}>Edit</button>
        <button className="btn sm" onClick={() => onDuplicate(agent)}>Duplicate</button>
        <button className="btn sm" onClick={() => onToggleStatus(agent)}>{agent.status === "active" ? "Pause" : "Activate"}</button>
        <button className="btn danger sm" onClick={() => onDelete(agent)}>Delete</button>
      </div>
    </div>
  );
}

function AgentsView() {
  const [agents, setAgents] = useAgState(loadAgents);
  const [editing, setEditing] = useAgState(null);
  const [levelFilter, setLevelFilter] = useAgState("all");

  useAgEffect(() => { saveAgents(agents); }, [agents]);

  const filtered = useAgMemo(() => {
    if (levelFilter === "all") return agents;
    return agents.filter(a => a.level === levelFilter);
  }, [agents, levelFilter]);

  const handleSave = (payload) => {
    setAgents(list => {
      if (editing && editing.id) {
        return list.map(a => a.id === editing.id ? { ...a, ...payload } : a);
      }
      return [...list, { ...payload, id: `agent_${Date.now()}` }];
    });
    setEditing(null);
  };

  const handleDuplicate = (agent) => {
    setAgents(list => [...list, { ...agent, id: `agent_${Date.now()}`, name: `${agent.name} (copy)`, status: "draft" }]);
  };

  const handleToggleStatus = (agent) => {
    setAgents(list => list.map(a => a.id === agent.id ? { ...a, status: a.status === "active" ? "paused" : "active" } : a));
  };

  const handleDelete = (agent) => {
    if (!confirm(`Delete agent "${agent.name}"?`)) return;
    setAgents(list => list.filter(a => a.id !== agent.id));
  };

  if (editing) {
    return (
      <div style={{ padding: 18, overflow: "auto", flex: 1 }}>
        <AgentEditor agent={editing === "new" ? null : editing} onSave={handleSave} onCancel={() => setEditing(null)} />
      </div>
    );
  }

  return (
    <div style={{ padding: 18, overflow: "auto", flex: 1 }}>
      <div style={{ display: "flex", alignItems: "center", marginBottom: 6, gap: 10 }}>
        <h1 style={{ margin: 0, fontSize: 22, fontWeight: 600 }}>Agents</h1>
        <span style={{ flex: 1 }} />
        <select className="field" value={levelFilter} onChange={e => setLevelFilter(e.target.value)} style={{ width: 150 }}>
          <option value="all">All levels</option>
          <option value="L1">L1 — Triage</option>
          <option value="L2">L2 — Investigation</option>
        </select>
        <button className="btn primary sm" onClick={() => setEditing("new")}>
          <Icon.Plus size={11} /> New agent
        </button>
      </div>
      <div style={{ fontSize: 12.5, color: "var(--fg-3)", marginBottom: 16, maxWidth: 720 }}>
        Build step-by-step playbooks that help L1 analysts triage alerts faster and L2 investigators dig deeper — no code required.
        The AI execution layer isn't connected yet (see <b>AI Assist</b> in the top bar) — for now this is where each agent's instructions get defined for when it is.
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(340px, 1fr))", gap: 12 }}>
        {filtered.map(a => (
          <AgentCard key={a.id} agent={a} onEdit={setEditing} onDuplicate={handleDuplicate} onToggleStatus={handleToggleStatus} onDelete={handleDelete} />
        ))}
      </div>

      {filtered.length === 0 && (
        <div className="card" style={{ padding: 24, textAlign: "center", color: "var(--fg-3)" }}>
          No agents match this filter.
        </div>
      )}
    </div>
  );
}

Object.assign(window, { AgentsView });
