(() => {
  const API_BASE = "/api";

  async function api(path, options = {}) {
    const res = await fetch(`${API_BASE}${path}`, {
      credentials: "same-origin",
      headers: {
        "Content-Type": "application/json",
        ...(options.headers || {}),
      },
      ...options,
    });

    let data = {};
    try {
      data = await res.json();
    } catch (_) {}

    if (!res.ok) {
      throw new Error(data.error || `Request failed: ${res.status}`);
    }

    return data;
  }

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

  function replaceText(root, from, to) {
    const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
    const nodes = [];

    while (walker.nextNode()) {
      if (walker.currentNode.nodeValue.includes(from)) {
        nodes.push(walker.currentNode);
      }
    }

    for (const node of nodes) {
      node.nodeValue = node.nodeValue.replaceAll(from, to);
    }
  }

  function buildLoginForm() {
    const form = document.createElement("form");
    form.className = "top-account-form";
    form.action = "#";
    form.method = "post";
    form.setAttribute("aria-label", "Account login or registration");

    let mode = "login";

    function render() {
      form.classList.toggle("is-register", mode === "register");
      form.classList.toggle("is-login", mode !== "register");

      if (mode === "register") {
        form.innerHTML = `
          <label class="sr-only" for="top-username">Username</label>
          <input id="top-username" name="username" type="text" placeholder="username" autocomplete="username">

          <label class="sr-only" for="top-email">Email</label>
          <input id="top-email" name="email" type="email" placeholder="email" autocomplete="email">

          <label class="sr-only" for="top-password">Password</label>
          <input id="top-password" name="password" type="password" placeholder="password" autocomplete="new-password">

          <div class="top-account-actions">
            <button class="button-compact" type="submit" data-action="create-account">Create Account</button>
            <button class="button-compact button-secondary" type="button" data-action="cancel-register">Cancel</button>
          </div>

          <div class="auth-message" role="status"></div>
        `;
        return;
      }

      form.innerHTML = `
        <label class="sr-only" for="top-username">Username</label>
        <input id="top-username" name="username" type="text" placeholder="username" autocomplete="username">

        <label class="sr-only" for="top-password">Password</label>
        <input id="top-password" name="password" type="password" placeholder="password" autocomplete="current-password">

        <button class="button-compact" type="submit" data-action="login">Login</button>
        <button class="button-compact button-secondary" type="button" data-action="show-register">Register</button>

        <div class="auth-message" role="status"></div>
      `;
    }

    function setMessage(text, kind = "error") {
      const message = form.querySelector(".auth-message");
      if (!message) return;

      message.textContent = text || "";
      message.classList.remove("is-error", "is-ok");
      message.classList.add(kind === "ok" ? "is-ok" : "is-error");
    }

    form.addEventListener("click", (event) => {
      const button = event.target.closest("button[data-action]");
      if (!button) return;

      const action = button.dataset.action;

      if (action === "show-register") {
        event.preventDefault();
        mode = "register";
        render();
        form.querySelector('input[name="username"]')?.focus();
        return;
      }

      if (action === "cancel-register") {
        event.preventDefault();
        mode = "login";
        render();
        form.querySelector('input[name="username"]')?.focus();
      }
    });

    form.addEventListener("submit", async (event) => {
      event.preventDefault();

      const submitter = event.submitter;
      const action = submitter?.dataset.action || "login";

      const username = form.querySelector('input[name="username"]')?.value.trim() || "";
      const password = form.querySelector('input[name="password"]')?.value || "";
      const email = form.querySelector('input[name="email"]')?.value.trim() || "";

      setMessage("");

      try {
        if (action === "create-account") {
          await api("/register", {
            method: "POST",
            body: JSON.stringify({ username, email, password }),
          });

          setMessage("Account created. Check your email to verify your account.", "ok");
          window.setTimeout(() => {
            window.location.href = "account-ready.html";
          }, 900);
          return;
        }

        await api("/login", {
          method: "POST",
          body: JSON.stringify({ username, password }),
        });

        window.location.href = "account-ready.html";
      } catch (err) {
        setMessage(err.message);
      }
    });

    render();
    return form;
  }


  function buildSignedInStatus(user) {
    const wrap = document.createElement("div");
    wrap.className = "top-account-status";

    wrap.innerHTML = `
      <span class="status-dot" aria-hidden="true"></span>
      <a href="account-ready.html">Signed in as ${escapeHtml(user.username)}</a>
      <button class="button-compact button-secondary" type="button" data-logout>Logout</button>
    `;

    wrap.querySelector("[data-logout]").addEventListener("click", async () => {
      await api("/logout", { method: "POST" });
      window.location.href = "index.html";
    });

    return wrap;
  }

  function renderHeader(user) {
    const header = document.querySelector(".site-header--accountline");
    if (!header) return;

    header.querySelectorAll(".top-account-form, .top-account-status").forEach((el) => el.remove());

    if (user) {
      header.appendChild(buildSignedInStatus(user));
    } else {
      header.appendChild(buildLoginForm());
    }
  }

  function findCardByHeading(text) {
    const needle = text.toLowerCase();

    for (const heading of document.querySelectorAll("h1, h2, h3, h4")) {
      if (!heading.textContent.toLowerCase().includes(needle)) continue;

      const card = heading.closest(".setup-card, .card, section, article, div");
      if (card) return card;
    }

    return null;
  }

  function findBBCard() {
    return document.querySelector("[data-bb-card], .setup-card--bb") || findCardByHeading("Blue Burst");
  }

  function badge(text, kind = "") {
    const cls = kind ? `badge ${kind}` : "badge";
    return `<span class="${cls}">${escapeHtml(text)}</span>`;
  }

  function updateAccountStatusBadges(accountData) {
    if (!accountData?.bb) return;

    const bb = accountData.bb;
    let label = "BB PASSWORD NEEDED";
    let warn = true;

    if (bb.created && bb.ready) {
      label = "ACCOUNT READY";
      warn = false;
    } else if (bb.created || bb.account_id) {
      label = "BB SYNC PENDING";
      warn = true;
    }

    for (const badge of document.querySelectorAll(".status-badges .badge")) {
      const text = badge.textContent.trim().toUpperCase();

      if (text.includes("BB ")) {
        badge.textContent = label;
        badge.classList.toggle("badge--warn", warn);
      }
    }
  }

  function renderBBCard(accountData) {
    const card = findBBCard();
    if (!card || !accountData?.user) return;

    const user = accountData.user;
    const bb = accountData.bb || {
      created: false,
      ready: false,
      sync_status: "missing",
      username: user.username,
      account_id: null,
    };

    const bbCreated = !!(bb.created || bb.account_id);
    const bbReady = !!bb.ready;
    const bbBadgeLabel = bbReady ? "ACCOUNT READY" : "BB SYNC PENDING";

    if (bbCreated) {
      card.innerHTML = `
        <div class="setup-card-header">
          <div>
            <p class="eyebrow">Blue Burst</p>
            <h2>Blue Burst Account</h2>
          </div>
          ${badge(bbBadgeLabel, bbReady ? "" : "badge--warn")}
        </div>

        <div class="account-kv">
          <div>
            <span>BB username</span>
            <strong>${escapeHtml(bb.username)}</strong>
          </div>
          <div>
            <span>BB account ID</span>
            <strong>${escapeHtml(bb.account_id)}</strong>
          </div>
        </div>

        <form class="bb-account-form" data-bb-action="change-password">
          <p class="muted">Change your Blue Burst login password. This updates the account file, then it needs to sync to the ships.</p>

          <label>
            New BB password
            <input name="password" type="password" autocomplete="new-password" maxlength="16" required>
          </label>

          <label>
            Confirm new BB password
            <input name="confirm_password" type="password" autocomplete="new-password" maxlength="16" required>
          </label>

          <button class="button" type="submit">Change Blue Burst Password</button>
          <div class="bb-message" role="status"></div>
        </form>
      `;
    } else {
      card.innerHTML = `
        <div class="setup-card-header">
          <div>
            <p class="eyebrow">Blue Burst</p>
            <h2>Create Blue Burst Account</h2>
          </div>
          ${badge("BB PASSWORD NEEDED", "badge--warn")}
        </div>

        <div class="account-kv">
          <div>
            <span>BB username</span>
            <strong>${escapeHtml(user.username)}</strong>
          </div>
          <div>
            <span>BB account ID</span>
            <strong>created after setup</strong>
          </div>
        </div>

        <form class="bb-account-form" data-bb-action="create">
          <p class="muted">Your Blue Burst username will match your website account name.</p>

          <label>
            BB password
            <input name="password" type="password" autocomplete="new-password" maxlength="16" required>
          </label>

          <label>
            Confirm BB password
            <input name="confirm_password" type="password" autocomplete="new-password" maxlength="16" required>
          </label>

          <button class="button" type="submit">Create Blue Burst Account</button>
          <div class="bb-message" role="status"></div>
        </form>
      `;
    }

    const form = card.querySelector(".bb-account-form");
    if (!form) return;

    form.addEventListener("submit", async (event) => {
      event.preventDefault();

      const message = form.querySelector(".bb-message");
      const password = form.querySelector('input[name="password"]').value;
      const confirmPassword = form.querySelector('input[name="confirm_password"]').value;
      const action = form.dataset.bbAction;

      message.textContent = "";
      message.classList.remove("is-error", "is-ok");

      const endpoint = action === "change-password" ? "/bb/change-password" : "/bb/create";

      try {
        const result = await api(endpoint, {
          method: "POST",
          body: JSON.stringify({
            password,
            confirm_password: confirmPassword,
          }),
        });

        message.textContent = result?.bb?.ready
          ? "Saved and synced."
          : "Saved. Sync queued; refresh shortly.";
        message.classList.add("is-ok");

        const fresh = await api("/account");
        renderBBCard(fresh);
      } catch (err) {
        message.textContent = err.message;
        message.classList.add("is-error");
      }
    });
  }


  function renderAccountEmail(accountData) {
    const hero = document.querySelector(".account-hero-card");
    const title = document.querySelector("#account-title");
    if (!hero || !title) return;

    for (const p of Array.from(hero.querySelectorAll("p"))) {
      if (
        p.textContent.includes("Manage your Blue Burst login") ||
        p.classList.contains("account-email-line")
      ) {
        p.remove();
      }
    }

    let box = hero.querySelector("#account-email-summary");
    if (!box) {
      box = document.createElement("div");
      box.id = "account-email-summary";
      box.className = "account-email-summary";
      title.insertAdjacentElement("afterend", box);
    }

    const email = accountData?.email || {};
    const emailText = email.email || "No email address set";
    const verified = !!email.verified;

    box.innerHTML = `
      <div class="account-control-line">
        <span class="account-control-label">Email</span>
        <strong>${escapeHtml(emailText)}</strong>
        <span class="account-email-state ${verified ? "is-verified" : "is-pending"}">
          ${verified ? "Verified" : "Verification needed"}
        </span>
        <button class="inline-link account-email-update" type="button">update email address</button>
        <button class="inline-link account-password-update" type="button">change password</button>
      </div>

      <form class="account-inline-form account-email-form" hidden>
        <label class="sr-only" for="account-email-input">New email address</label>
        <input id="account-email-input" name="email" type="email" placeholder="new email address" autocomplete="email">
        <button class="button-compact" type="submit">Send Verification Email</button>
        <button class="button-compact button-secondary" type="button" data-email-cancel>Cancel</button>
      </form>

      <form class="account-inline-form account-password-form" hidden>
        <label class="sr-only" for="account-current-password">Current password</label>
        <input id="account-current-password" name="current_password" type="password" placeholder="current password" autocomplete="current-password">

        <label class="sr-only" for="account-new-password">New password</label>
        <input id="account-new-password" name="password" type="password" placeholder="new password" autocomplete="new-password">

        <label class="sr-only" for="account-confirm-password">Confirm new password</label>
        <input id="account-confirm-password" name="confirm_password" type="password" placeholder="confirm new password" autocomplete="new-password">

        <button class="button-compact" type="submit">Change Password</button>
        <button class="button-compact button-secondary" type="button" data-password-cancel>Cancel</button>
      </form>

      <p class="account-control-message" role="status"></p>
    `;

    const emailButton = box.querySelector(".account-email-update");
    const passwordButton = box.querySelector(".account-password-update");
    const emailForm = box.querySelector(".account-email-form");
    const passwordForm = box.querySelector(".account-password-form");
    const emailCancel = box.querySelector("[data-email-cancel]");
    const passwordCancel = box.querySelector("[data-password-cancel]");
    const message = box.querySelector(".account-control-message");
    const emailInput = box.querySelector("#account-email-input");

    function setMessage(text, kind = "") {
      message.textContent = text || "";
      message.className = "account-control-message";
      if (kind) message.classList.add(kind);
    }

    function hideForms() {
      emailForm.hidden = true;
      passwordForm.hidden = true;
    }

    emailButton.addEventListener("click", () => {
      hideForms();
      emailForm.hidden = false;
      emailInput.value = email.email || "";
      setMessage("");
      emailInput.focus();
    });

    passwordButton.addEventListener("click", () => {
      hideForms();
      passwordForm.hidden = false;
      setMessage("");
      passwordForm.querySelector('input[name="current_password"]')?.focus();
    });

    emailCancel.addEventListener("click", () => {
      emailForm.hidden = true;
      setMessage("");
    });

    passwordCancel.addEventListener("click", () => {
      passwordForm.hidden = true;
      passwordForm.reset();
      setMessage("");
    });

    emailForm.addEventListener("submit", async (event) => {
      event.preventDefault();

      const newEmail = emailInput.value.trim();
      setMessage("");

      try {
        const result = await api("/email/start", {
          method: "POST",
          body: JSON.stringify({ email: newEmail }),
        });

        const sent = result?.verification?.sent;
        const debugLink = result?.verification?.debug_link;

        setMessage(sent ? "Verification email sent. Check your inbox." : "Verification link created.", "is-ok");

        if (debugLink) {
          const a = document.createElement("a");
          a.href = debugLink;
          a.target = "_blank";
          a.rel = "noopener noreferrer";
          a.textContent = " Open verification link";
          message.appendChild(a);
        }

        const updated = await api("/account");
        renderAccountEmail(updated);
      } catch (err) {
        setMessage(err.message || String(err), "is-error");
      }
    });

    passwordForm.addEventListener("submit", async (event) => {
      event.preventDefault();

      const currentPassword = passwordForm.querySelector('input[name="current_password"]').value;
      const newPassword = passwordForm.querySelector('input[name="password"]').value;
      const confirmPassword = passwordForm.querySelector('input[name="confirm_password"]').value;

      setMessage("");

      try {
        await api("/password/change", {
          method: "POST",
          body: JSON.stringify({
            current_password: currentPassword,
            password: newPassword,
            confirm_password: confirmPassword,
          }),
        });

        passwordForm.reset();
        passwordForm.hidden = true;
        setMessage("Password changed.", "is-ok");
      } catch (err) {
        setMessage(err.message || String(err), "is-error");
      }
    });
  }


  function renderAccountPage(user, accountData) {
    const main = document.querySelector(".account-layout");
    if (!main) return;

    if (!user) {
      main.innerHTML = `
        <section class="card account-hero-card" aria-labelledby="account-title">
          <div>
            <p class="eyebrow">Account Dashboard</p>
            <h1 id="account-title">Sign in or register</h1>
            <p>Use the account form at the top right to create or open your PSO Peeps website account.</p>
          </div>
          <div class="status-badges" aria-label="Account setup status">
            <span class="badge badge--warn">Not signed in</span>
          </div>
        </section>
      `;
      return;
    }

    replaceText(document.body, "chuudoku", user.username);

    const title = document.querySelector("#account-title");
    if (title) title.textContent = user.username;

    renderAccountEmail(accountData);
    updateAccountStatusBadges(accountData);

    // Account dashboard BB card is server-rendered.
    // Do not let the generic app bootstrap rewrite it into a stale layout.
    return;
  }

  async function boot() {
    let user = null;
    let accountData = null;

    try {
      const me = await api("/me");
      if (me.authenticated) {
        user = me.user;
      }
    } catch (_) {}

    if (user) {
      try {
        accountData = await api("/account");
      } catch (_) {
        accountData = {
          authenticated: true,
          user,
          bb: {
            ready: false,
            username: user.username,
            account_id: null,
          },
          v2_v3_keys: [],
        };
      }
    }

    renderHeader(user);
    renderAccountPage(user, accountData);
  }

  document.addEventListener("DOMContentLoaded", boot);
})();
