const refreshButton = document.getElementById("refresh-button");
const refreshStatus = document.getElementById("refresh-status");
const tailSelect = document.getElementById("tail-select");

const fields = {
  activeRun: document.getElementById("metric-active-run"),
  phase: document.getElementById("metric-phase"),
  branch: document.getElementById("metric-branch"),
  blockers: document.getElementById("metric-blockers"),
  runCount: document.getElementById("run-count"),
  runsList: document.getElementById("runs-list"),
  generatedAt: document.getElementById("generated-at"),
  nextAction: document.getElementById("next-action"),
  workspace: document.getElementById("workspace"),
  blockersList: document.getElementById("blockers"),
  progressPath: document.getElementById("progress-path"),
  progressTail: document.getElementById("progress-tail"),
};

let refreshTimer = null;

refreshButton.addEventListener("click", () => loadStatus());
tailSelect.addEventListener("change", () => loadStatus());

loadStatus();
refreshTimer = setInterval(loadStatus, 5000);
window.addEventListener("beforeunload", () => clearInterval(refreshTimer));

async function loadStatus() {
  setRefreshState("Loading", "");

  try {
    const response = await fetch(`/api/status?tail=${encodeURIComponent(tailSelect.value)}`);
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    const data = await response.json();
    render(data);
    setRefreshState("Live", "status-ok");
  } catch (error) {
    setRefreshState("Error", "status-dead");
    fields.progressTail.textContent = `Failed to load status: ${error.message}`;
  }
}

function render(data) {
  const summary = data.summary || {};
  const checkpoint = data.checkpoint || {};
  const blockers = Array.isArray(checkpoint.blockers) ? checkpoint.blockers : [];

  fields.activeRun.textContent = summary.active_run_id || "none";
  fields.phase.textContent = summary.current_phase || "unknown";
  fields.branch.textContent = summary.active_branch || "none";
  fields.blockers.textContent = String(blockers.length);
  fields.runCount.textContent = `${data.runs.length} total`;
  fields.generatedAt.textContent = formatTime(data.generated_at);
  fields.nextAction.textContent = summary.next_action || "No next action recorded.";
  fields.workspace.textContent = data.workspace || "-";

  renderBlockers(blockers);
  renderRuns(data.runs, summary.active_run_id);
  renderProgress(data.active_progress);
}

function renderBlockers(blockers) {
  fields.blockersList.innerHTML = "";

  if (blockers.length === 0) {
    fields.blockersList.innerHTML = '<p class="muted">No blockers recorded.</p>';
    return;
  }

  for (const blocker of blockers) {
    const item = document.createElement("div");
    item.className = "blocker";
    item.textContent = blocker;
    fields.blockersList.appendChild(item);
  }
}

function renderRuns(runs, activeRunId) {
  fields.runsList.innerHTML = "";

  if (runs.length === 0) {
    fields.runsList.innerHTML =
      '<div class="empty">No runs yet. Create .agents/runs/&lt;run-id&gt;/ with state.json and agents.json.</div>';
    return;
  }

  for (const run of runs) {
    fields.runsList.appendChild(renderRun(run, run.id === activeRunId));
  }
}

function renderRun(run, active) {
  const state = run.state || {};
  const card = document.createElement("article");
  card.className = "run-card";

  const title = document.createElement("div");
  title.className = "run-title";
  title.innerHTML = `
    <strong>${escapeHtml(run.id)}</strong>
    <span class="chip ${active ? "status-ok" : ""}">${active ? "active" : "recorded"}</span>
  `;
  card.appendChild(title);

  const meta = document.createElement("div");
  meta.className = "run-meta";
  meta.innerHTML = `
    <span>Phase: ${escapeHtml(state.current_phase || state.phase || "unknown")}</span>
    <span>Branch: ${escapeHtml(state.current_branch || state.branch || "none")}</span>
    <span>Expected: ${escapeHtml(state.expected_output_artifact || state.expected_output || "none")}</span>
    <span>Retries: ${escapeHtml(String(state.retry_count ?? 0))}</span>
  `;
  card.appendChild(meta);

  const agents = document.createElement("div");
  agents.className = "agent-list";
  if (!run.agents || run.agents.length === 0) {
    agents.innerHTML = '<small class="muted">No agents recorded.</small>';
  } else {
    for (const agent of run.agents) {
      agents.appendChild(renderAgent(agent));
    }
  }
  card.appendChild(agents);

  return card;
}

function renderAgent(agent) {
  const row = document.createElement("div");
  row.className = "agent-row";
  const statusClass = agent.lease_expired
    ? "status-dead"
    : agent.status === "completed"
      ? "status-ok"
      : "status-warn";
  const id = agent.thread_id || agent.process_id || agent.tool_call_id || "none";

  row.innerHTML = `
    <div>
      <strong>${escapeHtml(agent.role || "unknown-role")}</strong>
      <small>heartbeat ${escapeHtml(agent.heartbeat_at || "none")} / id ${escapeHtml(String(id))}</small>
      ${agent.last_error ? `<small>${escapeHtml(agent.last_error)}</small>` : ""}
    </div>
    <span class="chip ${statusClass}">${escapeHtml(agent.lease_expired ? "expired" : agent.status || "unknown")}</span>
  `;
  return row;
}

function renderProgress(progress) {
  if (!progress || !progress.path) {
    fields.progressPath.textContent = "no progress file";
    fields.progressTail.textContent = "No progress file found for the active run.";
    return;
  }

  fields.progressPath.textContent = progress.path;
  fields.progressTail.textContent = progress.lines.length > 0
    ? progress.lines.join("\n")
    : "Progress file is empty.";
}

function setRefreshState(label, extraClass) {
  refreshStatus.className = `status-pill ${extraClass}`;
  refreshStatus.textContent = label;
}

function formatTime(value) {
  if (!value) return "-";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return date.toLocaleTimeString();
}

function escapeHtml(value) {
  return String(value)
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#039;");
}
