const ADMIN_KEY = "weavy_admin_password";

let adminPass = "";

const $ = (id) => document.getElementById(id);
const els = {
  loginScreen: $("login-screen"),
  adminScreen: $("admin-screen"),
  password: $("admin-password"),
  loginBtn: $("login-btn"),
  loginStatus: $("login-status"),

  refreshBtn: $("refresh-btn"),
  logoutBtn: $("logout-btn"),
  stats: $("stats"),
  accountList: $("account-list"),
  poolSize: $("pool-size"),

  addToken: $("add-token"),
  addRecipe: $("add-recipe"),
  addLabel: $("add-label"),
  addBtn: $("add-btn"),

  bulkText: $("bulk-text"),
  bulkBtn: $("bulk-btn"),

  editForm: $("edit-form"),
  editId: $("edit-id"),
  editToken: $("edit-token"),
  editRecipe: $("edit-recipe"),
  editLabel: $("edit-label"),
  saveEditBtn: $("save-edit-btn"),
  cancelEditBtn: $("cancel-edit-btn"),
};

function setLoginStatus(text, type = "") {
  if (!text) { els.loginStatus.hidden = true; return; }
  els.loginStatus.hidden = false;
  els.loginStatus.textContent = text;
  els.loginStatus.className = `status ${type}`;
}

async function api(path, opts = {}) {
  const headers = { "Content-Type": "application/json", "x-admin-password": adminPass, ...(opts.headers || {}) };
  const res = await fetch(path, { ...opts, headers });
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(data.error || `HTTP ${res.status}`);
  return data;
}

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

function formatTimeLeft(exp) {
  if (!exp) return "no exp";
  const sec = exp - Date.now() / 1000;
  if (sec <= 0) return "expired";
  if (sec < 60) return `${Math.floor(sec)}s left`;
  if (sec < 3600) return `${Math.floor(sec / 60)}m left`;
  return `${Math.floor(sec / 3600)}h ${Math.floor((sec % 3600) / 60)}m left`;
}

// ─── Login ──────────────────────────────────────────────────────────────────

async function tryLogin(password) {
  try {
    const res = await fetch("/api/admin/login", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ password }),
    });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) throw new Error(data.error || "Login failed");
    adminPass = password;
    sessionStorage.setItem(ADMIN_KEY, password);
    showAdmin();
    return true;
  } catch (err) {
    setLoginStatus(err.message, "error");
    return false;
  }
}

els.loginBtn.addEventListener("click", () => {
  const pass = els.password.value.trim();
  if (!pass) return;
  setLoginStatus("Logging in...");
  tryLogin(pass);
});

els.password.addEventListener("keydown", (e) => {
  if (e.key === "Enter") els.loginBtn.click();
});

els.logoutBtn.addEventListener("click", () => {
  adminPass = "";
  sessionStorage.removeItem(ADMIN_KEY);
  els.adminScreen.hidden = true;
  els.loginScreen.hidden = false;
  els.password.value = "";
  setLoginStatus("");
});

function showAdmin() {
  els.loginScreen.hidden = true;
  els.adminScreen.hidden = false;
  setLoginStatus("");
  refresh();
}

// ─── Render account list ────────────────────────────────────────────────────

async function refresh() {
  try {
    const { accounts } = await api("/api/admin/accounts");
    renderStats(accounts);
    renderList(accounts);
    els.poolSize.textContent = `${accounts.length} (${accounts.filter((a) => !a.expired).length} aktif)`;
  } catch (err) {
    if (err.message === "Unauthorized") {
      els.logoutBtn.click();
      setLoginStatus("Session expired, login lagi", "warn");
    } else {
      console.error(err);
    }
  }
}

function renderStats(accounts) {
  const total = accounts.length;
  const active = accounts.filter((a) => !a.expired).length;
  const expired = total - active;
  const totalRuns = accounts.reduce((s, a) => s + (a.runs || 0), 0);
  els.stats.innerHTML = `
    <div class="stat"><div class="stat-num">${total}</div><div class="stat-label">Total Akun</div></div>
    <div class="stat"><div class="stat-num good">${active}</div><div class="stat-label">Aktif</div></div>
    <div class="stat"><div class="stat-num bad">${expired}</div><div class="stat-label">Expired</div></div>
    <div class="stat"><div class="stat-num">${totalRuns}</div><div class="stat-label">Total Runs</div></div>
  `;
}

function renderList(accounts) {
  if (!accounts.length) {
    els.accountList.innerHTML = `<div class="empty-accounts">Belum ada akun. Tambahkan di bawah.</div>`;
    return;
  }
  els.accountList.innerHTML = "";
  for (const a of accounts) {
    const row = document.createElement("div");
    row.className = `account-row ${a.expired ? "expired" : ""}`;
    row.innerHTML = `
      <div class="acc-info">
        <div class="acc-label">${escapeHtml(a.label)}</div>
        <div class="acc-meta">
          <span>${escapeHtml(a.email || "?")}</span>
          <span class="dot">·</span>
          <span class="${a.expired ? "exp-bad" : "exp-ok"}">${formatTimeLeft(a.exp)}</span>
          <span class="dot">·</span>
          <span>runs: ${a.runs || 0}</span>
          <span class="dot">·</span>
          <span>recipe: <code>${escapeHtml(a.recipeId || "default")}</code></span>
        </div>
        <div class="acc-meta">
          <span class="muted-inline">${escapeHtml(a.tokenPreview)}</span>
        </div>
      </div>
      <div class="acc-actions">
        <button type="button" class="ghost small" data-act="edit" data-id="${a.id}">✏️</button>
        <button type="button" class="ghost small danger" data-act="del" data-id="${a.id}">🗑️</button>
      </div>
    `;
    els.accountList.appendChild(row);
  }

  els.accountList.querySelectorAll("button[data-act=del]").forEach((b) => {
    b.addEventListener("click", async () => {
      if (!confirm("Hapus akun ini?")) return;
      try {
        await api(`/api/admin/accounts/${b.dataset.id}`, { method: "DELETE" });
        refresh();
      } catch (err) { alert(err.message); }
    });
  });
  els.accountList.querySelectorAll("button[data-act=edit]").forEach((b) => {
    b.addEventListener("click", async () => {
      const a = accounts.find((x) => x.id === b.dataset.id);
      if (!a) return;
      els.editId.value = a.id;
      els.editToken.value = "";  // intentionally empty — user provides fresh token
      els.editToken.placeholder = `(token tersembunyi: ${a.tokenPreview}) — kosongkan jika tidak diubah`;
      els.editRecipe.value = a.recipeId || "";
      els.editLabel.value = a.label || "";
      els.editForm.hidden = false;
      els.editForm.scrollIntoView({ behavior: "smooth" });
    });
  });
}

// ─── Add / edit / bulk ──────────────────────────────────────────────────────

els.refreshBtn.addEventListener("click", refresh);

els.addBtn.addEventListener("click", async () => {
  const token = els.addToken.value.trim();
  if (!token) return alert("Token wajib diisi");
  try {
    await api("/api/admin/accounts", {
      method: "POST",
      body: JSON.stringify({
        token,
        recipeId: els.addRecipe.value.trim(),
        label: els.addLabel.value.trim(),
      }),
    });
    els.addToken.value = ""; els.addRecipe.value = ""; els.addLabel.value = "";
    refresh();
  } catch (err) { alert(err.message); }
});

els.bulkBtn.addEventListener("click", async () => {
  const lines = els.bulkText.value.split("\n").map((s) => s.trim()).filter(Boolean);
  if (!lines.length) return alert("Tidak ada baris");
  try {
    const result = await api("/api/admin/accounts/bulk", {
      method: "POST",
      body: JSON.stringify({ lines }),
    });
    let msg = `${result.added} akun berhasil ditambahkan`;
    if (result.errors?.length) {
      msg += `\n\n${result.errors.length} error:\n` + result.errors.map((e) => `- ${e.line}: ${e.error}`).join("\n");
    }
    alert(msg);
    els.bulkText.value = "";
    refresh();
  } catch (err) { alert(err.message); }
});

els.cancelEditBtn.addEventListener("click", () => {
  els.editForm.hidden = true;
});

els.saveEditBtn.addEventListener("click", async () => {
  const id = els.editId.value;
  const patch = {
    recipeId: els.editRecipe.value.trim(),
    label: els.editLabel.value.trim(),
  };
  const newToken = els.editToken.value.trim();
  if (newToken) patch.token = newToken;
  try {
    await api(`/api/admin/accounts/${id}`, { method: "PUT", body: JSON.stringify(patch) });
    els.editForm.hidden = true;
    refresh();
  } catch (err) { alert(err.message); }
});

// ─── Bootstrap ──────────────────────────────────────────────────────────────

(async function init() {
  const saved = sessionStorage.getItem(ADMIN_KEY);
  if (saved) {
    const ok = await tryLogin(saved);
    if (!ok) {
      sessionStorage.removeItem(ADMIN_KEY);
    }
  }
  setInterval(() => { if (!els.adminScreen.hidden) refresh(); }, 30_000);
})();
