const managerElements = {
  banner: document.querySelector("#manager-status"),
  greeting: document.querySelector("#manager-greeting"),
  subtitle: document.querySelector("#manager-subtitle"),
  jobs: document.querySelector("#job-stats"),
  workers: document.querySelector("#worker-stats"),
  totals: document.querySelector("#manager-totals"),
  partnerBalances: document.querySelector("#partner-balances"),
  recentJobs: document.querySelector("#recent-jobs"),
  recentEvents: document.querySelector("#recent-events"),
  workerHealth: document.querySelector("#worker-health"),
  recoveryGenerate: document.querySelector("#recovery-generate-button"),
  recoveryOutput: document.querySelector("#recovery-codes-output"),
  auditLog: document.querySelector("#audit-log"),
  logout: document.querySelector("#logout-button"),
};

function setBanner(message, tone = "") {
  managerElements.banner.textContent = message;
  managerElements.banner.className = `status-banner ${tone}`.trim();
}

// Dashboard rows include worker and audit strings sourced from API data, so
// build DOM nodes directly instead of interpolating HTML.
function clearContainer(container) {
  container.replaceChildren();
}

function appendEmptyState(container, message) {
  const empty = document.createElement("div");
  empty.className = "muted";
  empty.textContent = message;
  container.appendChild(empty);
}

function createTextCell(text, className = "") {
  const cell = document.createElement("div");
  if (className) {
    cell.className = className;
  }
  cell.textContent = text;
  return cell;
}

function createPrimaryCell(title, subtitle) {
  const cell = document.createElement("div");
  const strong = document.createElement("strong");
  strong.textContent = title;
  cell.appendChild(strong);
  cell.appendChild(document.createElement("br"));
  cell.appendChild(createTextCell(subtitle, "muted"));
  return cell;
}

function appendTableRow(container, ...cells) {
  const row = document.createElement("div");
  row.className = "table-row";
  for (const cell of cells) {
    row.appendChild(cell);
  }
  container.appendChild(row);
}

function renderMap(container, entries) {
  clearContainer(container);
  if (entries.length === 0) {
    appendEmptyState(container, "Nothing to show yet.");
    return;
  }

  for (const [label, value] of entries) {
    appendTableRow(
      container,
      createTextCell(label),
      createTextCell(String(value), "pill"),
      createTextCell("current", "muted"),
    );
  }
}

function renderRows(container, rows, kind) {
  clearContainer(container);
  if (!rows.length) {
    appendEmptyState(container, "No activity yet.");
    return;
  }

  for (const row of rows) {
    if (kind === "jobs") {
      appendTableRow(
        container,
        createPrimaryCell(row.jobId, row.createdAt),
        createTextCell(row.status, "pill"),
        createTextCell(`p${row.priority}`, "muted"),
      );
    } else if (kind === "audit") {
      const actor = row.admin ? row.admin.username : "system";
      appendTableRow(
        container,
        createPrimaryCell(row.action, row.detail || ""),
        createTextCell(actor, "pill"),
        createTextCell(row.createdAt, "muted"),
      );
    } else if (kind === "workers") {
      const secondaryDetail = row.last_job_failure_detail
        ? `Last job failure: ${row.last_job_failure_detail}`
        : row.last_auth_failure_detail
          ? `Last auth failure: ${row.last_auth_failure_detail}`
          : row.observed_state_reason || "No recent worker detail";
      const activity = row.last_seen_at || row.registered_at || "never";
      appendTableRow(
        container,
        createPrimaryCell(row.worker_id, secondaryDetail),
        createTextCell(row.observed_state, "pill"),
        createTextCell(activity, "muted"),
      );
    } else if (kind === "partners") {
      appendTableRow(
        container,
        createPrimaryCell(row.name, row.partnerId),
        createTextCell(`$${row.creditsUsd.toFixed(2)}`, "pill"),
        createTextCell("prepaid", "muted"),
      );
    } else {
      appendTableRow(
        container,
        createPrimaryCell(row.eventType, row.detail || "No detail recorded"),
        createTextCell(row.actor || "system", "pill"),
        createTextCell(row.createdAt, "muted"),
      );
    }
  }
}

function countWorkerStates(workers) {
  const counts = {};
  for (const worker of workers) {
    const state = worker.observed_state || worker.status || "unknown";
    counts[state] = (counts[state] || 0) + 1;
  }
  return counts;
}

async function loadManager() {
  const [sessionResponse, overviewResponse, workersResponse] = await Promise.all([
    fetch("/manager/api/session"),
    fetch("/manager/api/overview"),
    fetch("/api/v1/workers"),
  ]);

  if (sessionResponse.status === 401 || overviewResponse.status === 401 || workersResponse.status === 401) {
    window.location.assign("/manager/login");
    return;
  }

  const session = await sessionResponse.json();
  const overview = await overviewResponse.json();
  const workerList = await workersResponse.json();

  managerElements.greeting.textContent = `Manager access: ${session.admin.displayName}`;
  managerElements.subtitle.textContent = `${session.admin.role} account using passkeys`;

  renderMap(managerElements.jobs, Object.entries(overview.jobs));
  renderMap(managerElements.workers, Object.entries(countWorkerStates(workerList.workers || [])));
  renderMap(managerElements.totals, Object.entries(overview.totals));
  renderRows(managerElements.partnerBalances, overview.partnerBalances || [], "partners");
  renderRows(managerElements.recentJobs, overview.recentJobs, "jobs");
  renderRows(managerElements.recentEvents, overview.recentEvents, "events");
  renderRows(managerElements.workerHealth, (workerList.workers || []).slice(0, 8), "workers");

  // Audit log is non-critical — don't block dashboard on failure
  try {
    const auditResponse = await fetch("/manager/api/audit-log");
    if (auditResponse.ok) {
      const audit = await auditResponse.json();
      if (audit.entries && managerElements.auditLog) {
        renderRows(managerElements.auditLog, audit.entries, "audit");
      }
    }
  } catch (_) { /* audit log unavailable — dashboard still works */ }

  setBanner("Manager session active. Coordinator telemetry is live.", "success");
}

async function logout() {
  await fetch("/manager/api/logout", { method: "POST" });
  window.location.assign("/manager/login");
}

async function generateRecoveryCodes() {
  setBanner("Generating new recovery codes...", "success");
  const response = await fetch("/manager/api/recovery-codes/regenerate", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ count: 8 }),
  });
  const payload = await response.json();
  if (!response.ok) {
    throw new Error(payload.detail || payload.error || "Unable to generate recovery codes");
  }

  managerElements.recoveryOutput.textContent = `${payload.message}\n\n${payload.codes.join("\n")}`;
  setBanner("Recovery codes regenerated. Store them offline now.", "success");
}

window.addEventListener("DOMContentLoaded", () => {
  managerElements.logout.addEventListener("click", () => {
    logout().catch((error) => setBanner(error.message || "Logout failed.", "error"));
  });
  managerElements.recoveryGenerate.addEventListener("click", () => {
    generateRecoveryCodes().catch((error) => setBanner(error.message || "Recovery code generation failed.", "error"));
  });

  loadManager().catch((error) => {
    setBanner(error.message || "Unable to load the hosted manager.", "error");
  });
});
