import {
  addEvidence,
  addObject,
  addRepresentation,
  appendContinuationEvent,
  applyReconciliation,
  completeContinuation,
  correctionPlan,
  createContinuation,
  createSeedWorkspace,
  fieldRows,
  getObject,
  queueException,
  resolveException,
  resumeContinuation,
  summarizeObject,
  validateWorkspace,
  verifyReceiptChain,
  verifyWorkspace,
  exportReceiptBundle,
  COMPARISON_POLICIES,
  setComparisonPolicy
} from "./core.js?v=6ecb64a04898";
import { WorkspaceHistory } from "./history.js?v=cb6e26ccaf9c";

const STORAGE_KEY = "cyberelf.coherence.workspace.v1";
const VIEWS = new Set(["reconcile", "attest", "exceptions", "continue"]);
const $ = (selector, root = document) => root.querySelector(selector);
const $$ = (selector, root = document) => Array.from(root.querySelectorAll(selector));

let workspace;
let selectedField = null;
let selectedExceptionId = null;
let selectedContinuationId = null;
let toastTimer = null;
let workspaceHistory;
let mutationBusy = false;
let storageProtected = false;
let recoveryText = null;

const escapeHtml = (value) => String(value ?? "")
  .replaceAll("&", "&amp;")
  .replaceAll("<", "&lt;")
  .replaceAll(">", "&gt;")
  .replaceAll('"', "&quot;")
  .replaceAll("'", "&#039;");

const formatDate = (value) => {
  if (!value) return "Not set";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return String(value);
  return new Intl.DateTimeFormat("en-US", {
    month: "short",
    day: "numeric",
    year: "numeric",
    hour: "numeric",
    minute: "2-digit"
  }).format(date);
};

const shortHash = (value) => value ? `${String(value).slice(0, 18)}…${String(value).slice(-8)}` : "GENESIS";

const activeView = () => {
  const hash = window.location.hash.replace(/^#/, "");
  return VIEWS.has(hash) ? hash : "reconcile";
};

function showToast(message, type = "success") {
  const toast = $("#toast");
  toast.textContent = message;
  toast.classList.toggle("error", type === "error");
  toast.classList.add("show");
  window.clearTimeout(toastTimer);
  toastTimer = window.setTimeout(() => toast.classList.remove("show"), 3400);
}

function persist(message = "Saved locally", recordHistory = true) {
  const state = $("#storage-state");
  if (recordHistory) workspaceHistory?.commit(workspace);
  $("#undo-button").disabled = !workspaceHistory?.canUndo;
  $("#redo-button").disabled = !workspaceHistory?.canRedo;
  if (storageProtected) { state.textContent = "Recovery mode · export to save changes"; return; }
  try {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(workspace));
    state.innerHTML = `<i></i> ${escapeHtml(message)}`;
  } catch (error) {
    state.textContent = "Memory-only; local storage unavailable";
    showToast(error.message || "Local storage is unavailable.", "error");
  }
}

function downloadJson(filename, value, raw = false) {
  const blob = new Blob([raw ? value : JSON.stringify(value, null, 2)], { type: "application/json" });
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement("a");
  anchor.href = url;
  anchor.download = filename;
  document.body.append(anchor);
  anchor.click();
  anchor.remove();
  window.setTimeout(() => URL.revokeObjectURL(url), 0);
}

function renderTabs() {
  const view = activeView();
  $$("[role='tab'][data-view]").forEach((tab) => {
    const selected = tab.dataset.view === view;
    tab.setAttribute("aria-selected", String(selected));
    tab.tabIndex = selected ? 0 : -1;
  });
  $$('[data-panel]').forEach((panel) => {
    panel.hidden = panel.dataset.panel !== view;
  });
}

function renderObjectControl() {
  const select = $("#object-select");
  select.innerHTML = workspace.objects.map((object) =>
    `<option value="${escapeHtml(object.id)}"${object.id === workspace.activeObjectId ? " selected" : ""}>${escapeHtml(object.label)} · ${escapeHtml(object.externalKey)}</option>`
  ).join("");
}

function renderMetrics() {
  const object = getObject(workspace);
  const summary = summarizeObject(object);
  const openExceptions = workspace.exceptions.filter((item) => item.objectId === object.id && item.status === "OPEN").length;
  const liveContinuations = workspace.continuations.filter((item) => item.objectId === object.id && item.status !== "DONE").length;
  $("#workspace-metrics").innerHTML = [
    ["SYSTEM SURFACES", summary.representations, ""],
    ["FIELDS OBSERVED", summary.fields, ""],
    ["DIFFERENT", summary.DIFFERENT, summary.DIFFERENT ? "metric-alert" : ""],
    ["INTENTIONAL", summary.INTENTIONAL, summary.INTENTIONAL ? "metric-intentional" : ""],
    ["OPEN EXCEPTIONS", openExceptions, openExceptions ? "metric-alert" : ""],
    ["LIVE CONTINUATIONS", liveContinuations, ""]
  ].map(([label, value, className]) => `<div class="${className}"><span>${label}</span><strong>${value}</strong></div>`).join("");
}

function renderMatrix() {
  const object = getObject(workspace);
  const rows = fieldRows(object);
  if (!selectedField || !rows.some((row) => row.field === selectedField)) {
    selectedField = rows.find((row) => row.status === "DIFFERENT")?.field || rows[0]?.field || null;
  }

  $("#matrix-head").innerHTML = `<tr>
    <th scope="col">FIELD / STATUS</th>
    ${object.representations.map((representation) => `<th scope="col"><div class="system-head"><strong>${escapeHtml(representation.system)}</strong><small>${escapeHtml(representation.role)} · ${representation.writable ? "writable" : "read only"} · ${escapeHtml(representation.recordKey)}</small></div></th>`).join("")}
  </tr>`;

  $("#matrix-body").innerHTML = rows.length ? rows.map((row) => `<tr${row.field === selectedField ? ' class="selected"' : ""}>
    <td><button class="field-link" type="button" data-field="${escapeHtml(row.field)}">${escapeHtml(row.field)}</button><span class="status-pill ${row.status.toLowerCase()}">${row.status}</span></td>
    ${row.observations.map((observation) => `<td><div class="matrix-value${observation.value ? "" : " empty"}">${escapeHtml(observation.value || "not observed")}${observation.intentionalReason ? `<small>intentional: ${escapeHtml(observation.intentionalReason)}</small>` : ""}</div></td>`).join("")}
  </tr>`).join("") : `<tr><td colspan="${object.representations.length + 1}"><div class="empty-state">Add a system surface to begin comparing representations.</div></td></tr>`;

  renderInspector(rows.find((row) => row.field === selectedField));
}

function planMarkup(plan) {
  return `<ul class="plan-list">${plan.map((item) => `<li class="${item.action.toLowerCase()}"><span>${escapeHtml(item.system)}</span><strong><b>${escapeHtml(item.action)}</b>${escapeHtml(item.note)}</strong></li>`).join("")}</ul>`;
}

function renderCorrectionPlan() {
  const container = $("#correction-plan");
  const target = $("#correction-target")?.value || "";
  if (!container) return;
  try {
    container.innerHTML = planMarkup(correctionPlan(getObject(workspace), selectedField, target, $("#comparison-policy")?.value));
  } catch (error) {
    container.innerHTML = `<div class="empty-state">${escapeHtml(error.message)}</div>`;
  }
}

function renderInspector(row) {
  const inspector = $("#field-inspector");
  if (!row) {
    inspector.innerHTML = '<div class="empty-state">No fields observed yet.</div>';
    return;
  }
  const fallback = row.observations.find((observation) => observation.value)?.value || "";
  const target = row.canonical?.value || fallback;
  const reason = row.canonical?.reason || "Assert the reviewed value and preserve every independent observation.";
  const openForField = workspace.exceptions.filter((item) => item.objectId === getObject(workspace).id && item.field === row.field && item.status === "OPEN").length;

  inspector.innerHTML = `
    <p class="inspector-label">FIELD DECISION / ${escapeHtml(row.status)}</p>
    <h3>${escapeHtml(row.field)}</h3>
    <div class="canonical-card">
      <span>Asserted state</span>
      <strong>${escapeHtml(row.canonical?.value || "No assertion yet")}</strong>
      <small>${row.canonical ? `${escapeHtml(row.canonical.assertedBy)} · ${escapeHtml(formatDate(row.canonical.assertedAt))}` : "Choose evidence before asserting a correction."}</small>
    </div>
    <ul class="observation-list">${row.observations.map((item) => `<li><span>${escapeHtml(item.system)}</span><strong>${escapeHtml(item.value || "not observed")}${item.intentionalReason ? ` · intentional` : ""}</strong></li>`).join("")}</ul>
    <form id="correction-form">
      <input type="hidden" name="field" value="${escapeHtml(row.field)}">
      <label>Compare this field as<select id="comparison-policy" name="comparisonPolicy">${Object.entries(COMPARISON_POLICIES).map(([key,label])=>`<option value="${key}"${key===row.comparisonPolicy?' selected':''}>${escapeHtml(label)}</option>`).join("")}</select></label>
      <p class="form-note">Exact text preserves identifier case and leading zeros. Numeric comparison requires an explicit field policy.</p>
      ${row.comparisonError ? `<p class="form-note" role="status">${escapeHtml(row.comparisonError)} Review the policy and source values.</p>` : ""}
      <label>Asserted value<input id="correction-target" name="targetValue" required value="${escapeHtml(target)}"></label>
      <label>Evidence / reason<textarea name="reason" rows="3" required>${escapeHtml(reason)}</textarea></label>
      <label>Operator<input name="actor" required value="Local operator"></label>
      <div id="correction-plan"></div>
      <div class="form-actions">
        <button class="quiet-button" type="button" data-action="set-policy">Save comparison policy only</button>
        <button class="panel-button" type="submit">Record + apply local correction</button>
        <button class="quiet-button" type="button" data-action="queue-field">Send to exceptions${openForField ? ` (${openForField} open)` : ""}</button>
      </div>
    </form>`;
  renderCorrectionPlan();
}

function renderAttestation() {
  const object = getObject(workspace);
  const evidence = workspace.evidence.filter((item) => item.objectId === object.id);
  const receipts = workspace.receipts.filter((item) => item.objectId === object.id);
  $("#evidence-count").textContent = `${evidence.length} independent item${evidence.length === 1 ? "" : "s"}`;
  $("#evidence-list").innerHTML = evidence.length ? evidence.map((item) => `<article class="evidence-card">
    <header><h4>${escapeHtml(item.label)}</h4><span>${escapeHtml(item.kind)}</span></header>
    <p>${escapeHtml(item.excerpt)}</p>
    <dl><div><dt>SOURCE</dt><dd>${escapeHtml(item.source)}</dd></div><div><dt>CAPTURED</dt><dd>${escapeHtml(formatDate(item.capturedAt))}</dd></div><div><dt>DIGEST</dt><dd title="${escapeHtml(item.digest)}">${escapeHtml(shortHash(item.digest))}</dd></div></dl>
  </article>`).join("") : '<div class="empty-state">No evidence captured for this object.</div>';

  $("#receipt-list").innerHTML = receipts.length ? receipts.map((receipt) => `<li class="receipt-card">
    <header><h4>${escapeHtml(receipt.action.replaceAll("_", " "))}</h4><span>${escapeHtml(formatDate(receipt.at))}</span></header>
    <dl>
      <div><dt>RECEIPT</dt><dd title="${escapeHtml(receipt.hash)}">${escapeHtml(shortHash(receipt.hash))}</dd></div>
      <div><dt>PREVIOUS</dt><dd title="${escapeHtml(receipt.previousHash || "GENESIS")}">${escapeHtml(shortHash(receipt.previousHash))}</dd></div>
      <div><dt>ACTOR</dt><dd>${escapeHtml(receipt.actor)}</dd></div>
      <div><dt>WHY</dt><dd>${escapeHtml(receipt.reason)}</dd></div>
      <div><dt>OPERATIONS</dt><dd>${receipt.operations?.length || 0} observed / planned action${receipt.operations?.length === 1 ? "" : "s"}</dd></div>
    </dl>
  </li>`).join("") : '<li class="empty-state">No receipts for this object.</li>';
}

function renderExceptions() {
  const object = getObject(workspace);
  const filter = $("#exception-filter").value;
  const all = workspace.exceptions.filter((item) => item.objectId === object.id);
  const visible = all.filter((item) => filter === "ALL" || item.status === filter);
  if (!selectedExceptionId || !visible.some((item) => item.id === selectedExceptionId)) selectedExceptionId = visible[0]?.id || null;

  $("#exception-list").innerHTML = visible.length ? visible.map((item) => `<button class="exception-card${item.id === selectedExceptionId ? " selected" : ""}" type="button" data-exception-id="${escapeHtml(item.id)}">
    <header><strong>${escapeHtml(item.field)}</strong><span class="${item.status.toLowerCase()}">${escapeHtml(item.status)}</span></header>
    <p>${escapeHtml(item.reason)}</p>
  </button>`).join("") : '<div class="empty-state">No exceptions match this filter.</div>';

  const exception = all.find((item) => item.id === selectedExceptionId);
  const inspector = $("#exception-inspector");
  if (!exception) {
    inspector.innerHTML = '<div class="empty-state">Select an exception to inspect the failed correspondence.</div>';
  } else {
    inspector.innerHTML = `
      <p class="inspector-label">FAILED CORRESPONDENCE / ${escapeHtml(exception.status)}</p>
      <h3>${escapeHtml(exception.field)}</h3>
      <p>${escapeHtml(exception.reason)}</p>
      <dl class="exception-facts"><div><dt>EXPECTED</dt><dd>${escapeHtml(exception.expected)}</dd></div><div><dt>OBSERVED</dt><dd>${escapeHtml(exception.observed)}</dd></div><div><dt>SYSTEMS</dt><dd>${escapeHtml(exception.systems.join(" · "))}</dd></div><div><dt>OPENED</dt><dd>${escapeHtml(formatDate(exception.openedAt))}</dd></div></dl>
      ${exception.status === "OPEN" ? `<form id="exception-resolution-form">
        <input type="hidden" name="exceptionId" value="${escapeHtml(exception.id)}">
        <label>Human judgment<textarea name="decision" rows="3" required placeholder="What should happen in the world now?"></textarea></label>
        <label>Operator<input name="actor" required value="Local operator"></label>
        <label>Reusable pattern (optional)<textarea name="pattern" rows="3" placeholder="When this shape recurs, what procedure should a future operator see?"></textarea></label>
        <button class="panel-button" type="submit">Resolve + retain judgment</button>
      </form>` : `<div class="canonical-card"><span>Resolution</span><strong>${escapeHtml(exception.resolution?.decision)}</strong><small>${escapeHtml(exception.resolution?.actor)} · ${escapeHtml(formatDate(exception.resolution?.at))}</small></div>`}`;
  }

  const patterns = workspace.patterns.filter((item) => item.objectKind === object.kind);
  $("#pattern-list").innerHTML = patterns.length ? patterns.map((pattern) => `<article class="pattern-card"><span>${escapeHtml(pattern.field)} / ${escapeHtml(pattern.objectKind)}</span>${escapeHtml(pattern.description)}</article>`).join("") : '<div class="empty-state">No resolution pattern has been retained yet.</div>';
}

function renderContinuations() {
  const object = getObject(workspace);
  const continuations = workspace.continuations.filter((item) => item.objectId === object.id);
  if (!selectedContinuationId || !continuations.some((item) => item.id === selectedContinuationId)) selectedContinuationId = continuations[0]?.id || null;
  $("#continuation-list").innerHTML = continuations.length ? continuations.map((item) => `<button class="continuation-card${item.id === selectedContinuationId ? " selected" : ""}" type="button" data-continuation-id="${escapeHtml(item.id)}">
    <header><strong>${escapeHtml(item.title)}</strong><span class="${item.status.toLowerCase()}">${escapeHtml(item.status)}</span></header>
    <p>${escapeHtml(item.counterparty)} · waiting on ${escapeHtml(item.waitingOn)}</p>
  </button>`).join("") : '<div class="empty-state">No continuations for this object.</div>';

  const continuation = continuations.find((item) => item.id === selectedContinuationId);
  const detail = $("#continuation-detail");
  if (!continuation) {
    detail.innerHTML = '<div class="empty-state">Open a continuation to preserve a transaction across control changes.</div>';
    return;
  }
  detail.innerHTML = `
    <p class="inspector-label">TRANSACTION STATE / ${escapeHtml(continuation.status)}</p>
    <h3>${escapeHtml(continuation.title)}</h3>
    <p>${escapeHtml(continuation.purpose)}</p>
    <dl class="continuation-facts"><div><dt>COUNTERPARTY</dt><dd>${escapeHtml(continuation.counterparty)}</dd></div><div><dt>CHANNEL</dt><dd>${escapeHtml(continuation.channel)}</dd></div><div><dt>OWNER</dt><dd>${escapeHtml(continuation.owner)}</dd></div><div><dt>WAITING ON</dt><dd>${escapeHtml(continuation.waitingOn)}</dd></div><div><dt>DUE</dt><dd>${escapeHtml(formatDate(continuation.dueAt))}</dd></div></dl>
    <div class="next-action"><span>RESUME EXACTLY HERE</span><strong>${escapeHtml(continuation.nextAction)}</strong></div>
    <ol class="event-timeline">${continuation.events.slice().reverse().map((event) => `<li><span>${escapeHtml(event.kind)} · ${escapeHtml(formatDate(event.at))}</span><p>${escapeHtml(event.note)}</p><small>${escapeHtml(event.author)}</small></li>`).join("")}</ol>
    ${continuation.status !== "DONE" ? `<form id="continuation-event-form">
      <input type="hidden" name="continuationId" value="${escapeHtml(continuation.id)}">
      <div class="form-grid"><label>Event kind<select name="kind"><option>NOTE</option><option>INBOUND CALL</option><option>OUTBOUND CALL</option><option>EMAIL</option><option>PORTAL MESSAGE</option><option>HANDOFF</option></select></label><label>Operator<input name="author" required value="${escapeHtml(continuation.owner)}"></label></div>
      <label>What happened<textarea name="note" rows="3" required placeholder="Record only the state-changing event."></textarea></label>
      <div class="form-actions"><button class="panel-button" type="submit">Append event</button>${continuation.status === "WAITING" ? '<button class="quiet-button" type="button" data-action="resume-continuation">Resume now</button>' : ""}<button class="quiet-button" type="button" data-action="complete-continuation">Complete</button></div>
    </form>` : `<div class="canonical-card"><span>Closed continuation</span><strong>${escapeHtml(continuation.events.at(-1)?.note)}</strong><small>${escapeHtml(formatDate(continuation.updatedAt))} · resumed ${continuation.resumeCount} time${continuation.resumeCount === 1 ? "" : "s"}</small></div>`}`;
}

function renderAll() {
  renderTabs();
  renderObjectControl();
  renderMetrics();
  renderMatrix();
  renderAttestation();
  renderExceptions();
  renderContinuations();
}

async function loadWorkspace() {
  try {
    const saved = localStorage.getItem(STORAGE_KEY);
    if (saved) {
      recoveryText = saved;
      workspace = await verifyWorkspace(JSON.parse(saved));
      workspaceHistory = new WorkspaceHistory(workspace);
      $("#storage-state").textContent = "Restored and verified from this browser";
      return;
    }
  } catch (error) {
    storageProtected = true;
    $("#recovery-banner").hidden = false;
    $("#recovery-reason").textContent = `${error.message} Your saved data has been preserved. Export recovery data or explicitly reset/import to replace it.`;
    $("#recovery-download").disabled = !recoveryText;
  }
  workspace = await createSeedWorkspace();
  workspaceHistory = new WorkspaceHistory(workspace);
  persist("Sample workspace saved locally");
}

$("#recovery-download").addEventListener("click", () => recoveryText && downloadJson("coherence-recovery.json", recoveryText, true));
for (const action of ["undo", "redo"]) {
  $(`#${action}-button`).addEventListener("click", () => {
    if (mutationBusy) return;
    workspace = workspaceHistory[action]();
    selectedField = selectedExceptionId = selectedContinuationId = null;
    persist(action === "undo" ? "Previous workspace restored" : "Change restored", false);
    renderAll();
  });
}

$("#object-select").addEventListener("change", (event) => {
  if (mutationBusy) { event.target.value = workspace.activeObjectId; return; }
  workspace.activeObjectId = event.target.value;
  workspace.updatedAt = new Date().toISOString();
  selectedField = null;
  selectedExceptionId = null;
  selectedContinuationId = null;
  persist();
  renderAll();
});

$("#exception-filter").addEventListener("change", renderExceptions);

$("#new-object-button").addEventListener("click", () => $("#new-object-dialog").showModal());
$("#add-surface-button").addEventListener("click", () => $("#add-surface-dialog").showModal());
$("#add-evidence-button").addEventListener("click", () => $("#add-evidence-dialog").showModal());
$("#new-continuation-button").addEventListener("click", () => $("#new-continuation-dialog").showModal());

$("#export-button").addEventListener("click", () => {
  downloadJson(`coherence-workspace-${getObject(workspace).externalKey}.json`, workspace);
  showToast("Workspace exported with evidence and receipts.");
});

$("#download-receipts-button").addEventListener("click", async () => {
  try {
    downloadJson("coherence-receipts.json", await exportReceiptBundle(workspace));
    showToast("Complete receipt chain downloaded, including every object's links.");
  } catch (error) { showToast(error.message, "error"); }
});

$("#verify-chain-button").addEventListener("click", async () => {
  const status = $("#chain-status");
  status.className = "chain-status";
  status.textContent = "Recomputing every digest…";
  const result = await verifyReceiptChain(workspace.receipts);
  status.classList.add(result.valid ? "valid" : "invalid");
  status.textContent = result.valid
    ? `VALID · ${result.checked} receipt${result.checked === 1 ? "" : "s"} recomputed · chain reaches genesis`
    : `INVALID · ${result.reason} at ${result.brokenAt}`;
});

$("#import-button").addEventListener("click", () => $("#import-file").click());
$("#import-file").addEventListener("change", async (event) => {
  const [file] = event.target.files;
  if (!file || mutationBusy) return;
  mutationBusy = true;
  try {
    if (file.size > 4 * 1024 * 1024) throw new Error("Workspace import limit is 4 MiB.");
    const candidate = await verifyWorkspace(JSON.parse(await file.text()));
    workspace = candidate;
    storageProtected = false;
    $("#recovery-banner").hidden = true;
    selectedField = null;
    selectedExceptionId = null;
    selectedContinuationId = null;
    persist(`Imported ${file.name}`);
    renderAll();
    showToast("Workspace, evidence, and receipt chain verified. Undo restores the previous workspace.");
  } catch (error) {
    showToast(error.message || "Import failed.", "error");
  } finally {
    mutationBusy = false;
    event.target.value = "";
  }
});

$("#reset-button").addEventListener("click", async () => {
  if (mutationBusy) return;
  if (!window.confirm("Replace this browser's current workspace with the public sample? Export first if you need it.")) return;
  mutationBusy = true;
  try {
  workspace = await createSeedWorkspace();
  storageProtected = false;
  $("#recovery-banner").hidden = true;
  selectedField = null;
  selectedExceptionId = null;
  selectedContinuationId = null;
  persist("Sample workspace restored");
  renderAll();
  showToast("Sample workspace restored.");
  } catch (error) { showToast(error.message, "error"); }
  finally { mutationBusy = false; }
});

document.addEventListener("input", (event) => {
  if (event.target.id === "correction-target") renderCorrectionPlan();
});
document.addEventListener("change", event => { if (event.target.id === "comparison-policy") renderCorrectionPlan(); });

document.addEventListener("click", async (event) => {
  if (mutationBusy) return;
  const tab = event.target.closest("[role='tab'][data-view]");
  if (tab) {
    history.replaceState(null, "", `#${tab.dataset.view}`);
    renderTabs();
    tab.focus();
    return;
  }

  const fieldButton = event.target.closest("[data-field]");
  if (fieldButton) {
    selectedField = fieldButton.dataset.field;
    renderMatrix();
    return;
  }

  const exceptionButton = event.target.closest("[data-exception-id]");
  if (exceptionButton) {
    selectedExceptionId = exceptionButton.dataset.exceptionId;
    renderExceptions();
    return;
  }

  const continuationButton = event.target.closest("[data-continuation-id]");
  if (continuationButton) {
    selectedContinuationId = continuationButton.dataset.continuationId;
    renderContinuations();
    return;
  }

  const close = event.target.closest("[data-close-dialog]");
  if (close) {
    close.closest("dialog")?.close();
    return;
  }

  const action = event.target.closest("[data-action]")?.dataset.action;
  if (action === "set-policy") {
    mutationBusy = true;
    try {
      const values = new FormData($("#correction-form"));
      const result = await setComparisonPolicy(workspace, { objectId: workspace.activeObjectId, field: values.get("field"), policy: values.get("comparisonPolicy"), actor: values.get("actor"), reason: values.get("reason") });
      workspace = result.workspace; persist(); renderAll();
      showToast("Comparison policy recorded. Source values were preserved.");
    } catch(error) { showToast(error.message, "error"); }
    finally { mutationBusy = false; }
    return;
  }
  if (action === "queue-field") {
    try {
      const form = $("#correction-form");
      const values = new FormData(form);
      const result = queueException(workspace, {
        objectId: workspace.activeObjectId,
        field: values.get("field"),
        expected: values.get("targetValue"),
        reason: values.get("reason")
      });
      workspace = result.workspace;
      selectedExceptionId = result.exception.id;
      persist();
      renderAll();
      showToast("Failed correspondence sent to the exception queue.");
    } catch (error) {
      showToast(error.message, "error");
    }
    return;
  }

  if (action === "resume-continuation") {
    try {
      const form = $("#continuation-event-form");
      const values = new FormData(form);
      const result = resumeContinuation(workspace, values.get("continuationId"), { actor: values.get("author") });
      workspace = result.workspace;
      persist();
      renderAll();
      showToast("Continuation resumed at the stored next action.");
    } catch (error) {
      showToast(error.message, "error");
    }
    return;
  }

  if (action === "complete-continuation") {
    try {
      const form = $("#continuation-event-form");
      const values = new FormData(form);
      const result = completeContinuation(workspace, values.get("continuationId"), {
        actor: values.get("author"),
        note: values.get("note")
      });
      workspace = result.workspace;
      persist();
      renderAll();
      showToast("Continuation completed with an explicit closing event.");
    } catch (error) {
      showToast(error.message, "error");
    }
  }
});

document.addEventListener("keydown", (event) => {
  const tab = event.target.closest("[role='tab'][data-view]");
  if (!tab || !["ArrowLeft", "ArrowRight"].includes(event.key)) return;
  event.preventDefault();
  const tabs = $$("[role='tab'][data-view]");
  const current = tabs.indexOf(tab);
  const direction = event.key === "ArrowRight" ? 1 : -1;
  const next = tabs[(current + direction + tabs.length) % tabs.length];
  history.replaceState(null, "", `#${next.dataset.view}`);
  renderTabs();
  next.focus();
});

document.addEventListener("submit", async (event) => {
  const form = event.target;
  event.preventDefault();
  const values = new FormData(form);
  if (mutationBusy) return;
  mutationBusy = true;
  try {
    if (form.id === "correction-form") {
      const result = await applyReconciliation(workspace, {
        objectId: workspace.activeObjectId,
        comparisonPolicy: values.get("comparisonPolicy"),
        field: values.get("field"),
        targetValue: values.get("targetValue"),
        reason: values.get("reason"),
        actor: values.get("actor")
      });
      workspace = result.workspace;
      persist();
      renderAll();
      showToast(`Correction recorded: ${result.plan.filter((item) => item.action === "UPDATE").length} local surface update(s), ${result.plan.filter((item) => item.action === "ATTEST").length} exception(s).`);
    }

    if (form.id === "exception-resolution-form") {
      const result = resolveException(workspace, values.get("exceptionId"), {
        decision: values.get("decision"),
        actor: values.get("actor"),
        pattern: values.get("pattern")
      });
      workspace = result.workspace;
      persist();
      renderAll();
      showToast("Human judgment retained and exception closed.");
    }

    if (form.id === "continuation-event-form") {
      const result = appendContinuationEvent(workspace, values.get("continuationId"), {
        note: values.get("note"),
        author: values.get("author"),
        kind: values.get("kind")
      });
      workspace = result.workspace;
      persist();
      renderAll();
      showToast("Continuation event appended without losing the handoff state.");
    }

    if (form.id === "new-object-form") {
      const result = addObject(workspace, {
        label: values.get("label"),
        kind: values.get("kind"),
        externalKey: values.get("externalKey")
      });
      workspace = result.workspace;
      selectedField = null;
      selectedExceptionId = null;
      selectedContinuationId = null;
      persist();
      form.reset();
      $("#new-object-dialog").close();
      renderAll();
      showToast("Object created. Add its first system surface.");
    }

    if (form.id === "add-surface-form") {
      let fields;
      try {
        fields = JSON.parse(values.get("fields"));
      } catch {
        throw new Error("Fields must be a valid JSON object.");
      }
      const result = addRepresentation(workspace, {
        objectId: workspace.activeObjectId,
        system: values.get("system"),
        recordKey: values.get("recordKey"),
        role: values.get("role"),
        writable: values.get("writable") === "on",
        fields
      });
      workspace = result.workspace;
      selectedField = null;
      persist();
      form.reset();
      $("#add-surface-dialog").close();
      renderAll();
      showToast("System representation observed and added to the matrix.");
    }

    if (form.id === "add-evidence-form") {
      const result = await addEvidence(workspace, {
        objectId: workspace.activeObjectId,
        label: values.get("label"),
        kind: values.get("kind"),
        source: values.get("source"),
        excerpt: values.get("excerpt")
      });
      workspace = result.workspace;
      persist();
      form.reset();
      $("#add-evidence-dialog").close();
      renderAll();
      showToast(`Evidence captured: ${shortHash(result.evidence.digest)}`);
    }

    if (form.id === "new-continuation-form") {
      const dueAt = values.get("dueAt") ? new Date(values.get("dueAt")).toISOString() : null;
      const result = createContinuation(workspace, {
        objectId: workspace.activeObjectId,
        title: values.get("title"),
        counterparty: values.get("counterparty"),
        channel: values.get("channel"),
        owner: values.get("owner"),
        purpose: values.get("purpose"),
        waitingOn: values.get("waitingOn"),
        nextAction: values.get("nextAction"),
        dueAt
      });
      workspace = result.workspace;
      selectedContinuationId = result.continuation.id;
      persist();
      form.reset();
      $("#new-continuation-dialog").close();
      renderAll();
      showToast("Continuation opened with an exact resumption point.");
    }
  } catch (error) {
    showToast(error.message || "Action failed.", "error");
  } finally {
    mutationBusy = false;
  }
});

window.addEventListener("hashchange", renderTabs);

await loadWorkspace();
renderAll();
