// Минимальный клиент wizard'а: рендерит страницы, ловит события из SSE,
// отправляет POST'ы на backend для перехода между стадиями.

let state = {
  stage: "welcome",
  precheck: [],
  config: {},
  steps: [],
  errorMsg: "",
};

const STAGE_ORDER = ["welcome", "precheck", "config", "installing", "done"];
const STEP_ICONS = {
  pending: "○",
  running: "◐",
  done:    "✓",
  skipped: "—",
  failed:  "✗",
};

function $(sel) { return document.querySelector(sel); }
function $$(sel) { return [...document.querySelectorAll(sel)]; }

function render() {
  // stepper
  $$("#stepper span").forEach(el => {
    el.classList.remove("active", "done");
    const stage = el.dataset.stage;
    if (stage === state.stage) el.classList.add("active");
    if (STAGE_ORDER.indexOf(stage) < STAGE_ORDER.indexOf(state.stage)) el.classList.add("done");
  });
  // pages
  $$(".page").forEach(p => p.classList.toggle("active", p.dataset.stage === state.stage));

  if (state.stage === "precheck") renderPrecheck();
  if (state.stage === "installing" || state.stage === "done") renderSteps();
  if (state.stage === "error")     $("#error-message").textContent = state.errorMsg || "(нет деталей)";
  if (state.stage === "done") {
    // подставляем хост машины в админскую ссылку
    const adminURL = window.location.protocol + "//" + window.location.hostname + ":8080/admin/setup";
    $("#adminLink").href = adminURL;
    $("#adminLink").textContent = "Перейти в " + adminURL + " →";
  }
}

function renderPrecheck() {
  const root = $("#precheck-results");
  root.innerHTML = "";
  let allOK = true;
  for (const r of state.precheck || []) {
    const div = document.createElement("div");
    div.className = "check " + (r.ok ? "ok" : "bad");
    div.innerHTML = `
      <span class="check-icon">${r.ok ? "✓" : "✗"}</span>
      <div>
        <div class="check-title">${escapeHTML(r.title)}</div>
        ${r.message ? `<div class="check-msg">${escapeHTML(r.message)}</div>` : ""}
      </div>`;
    root.appendChild(div);
    if (!r.ok) allOK = false;
  }
  $("#goConfigBtn").disabled = !allOK;
}

function renderSteps() {
  const root = $("#step-list");
  root.innerHTML = "";
  let done = 0;
  for (const s of state.steps || []) {
    const li = document.createElement("li");
    li.className = "step-" + s.status;
    li.innerHTML = `
      <span class="step-icon">${STEP_ICONS[s.status] || "○"}</span>
      <div>
        <div class="step-title">${escapeHTML(s.title)}</div>
        ${s.message ? `<div class="step-msg">${escapeHTML(s.message)}</div>` : ""}
      </div>`;
    root.appendChild(li);
    if (s.status === "done" || s.status === "skipped") done++;
  }
  const total = state.steps.length;
  const pct = total ? Math.round(100 * done / total) : 0;
  $("#progress-bar").style.width = pct + "%";
}

function escapeHTML(s) {
  return String(s).replace(/[&<>"']/g, c => ({
    "&": "&amp;", "<": "&lt;", ">": "&gt;", "\"": "&quot;", "'": "&#39;"
  }[c]));
}

// ------------- transitions -------------

async function startPrecheck() {
  await fetch("/api/precheck", { method: "POST" });
}

function goWelcome() {
  state.stage = "welcome";
  render();
}

function goPrecheck() {
  state.stage = "precheck";
  render();
}

async function goConfig() {
  state.stage = "config";
  render();
}

async function startInstall() {
  const form = $("#config-form");
  const data = Object.fromEntries(new FormData(form).entries());
  await fetch("/api/config", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
  });
  await fetch("/api/install", { method: "POST" });
}

async function resetWizard() {
  await fetch("/api/reset", { method: "POST" });
}

// ------------- SSE -------------

function connectSSE() {
  const es = new EventSource("/api/events");
  es.addEventListener("snapshot", e => {
    const snap = JSON.parse(e.data);
    state.stage = snap.stage;
    state.precheck = snap.precheck || [];
    state.config = snap.config || {};
    state.steps = snap.steps || [];
    state.errorMsg = snap.errorMsg || "";
    render();
  });
  es.addEventListener("stage", e => {
    state.stage = JSON.parse(e.data).stage;
    render();
  });
  es.addEventListener("precheck", e => {
    state.precheck = JSON.parse(e.data);
    render();
  });
  es.addEventListener("step", e => {
    const s = JSON.parse(e.data);
    const idx = state.steps.findIndex(x => x.id === s.id);
    if (idx >= 0) state.steps[idx] = s;
    render();
  });
  es.addEventListener("error", e => {
    state.errorMsg = JSON.parse(e.data).message;
    state.stage = "error";
    render();
  });
  es.addEventListener("reset", () => {
    location.reload();
  });
  es.onerror = () => {
    // авто-реконнект делает EventSource сам, ничего не делаем
  };
}

connectSSE();
