(() => {
  // Tab switching
  document.querySelectorAll('.auth-tab-list').forEach(tabList => {
    const tabs = tabList.querySelectorAll('[data-tab]');
    const panels = tabList.closest('.auth-tabs').querySelectorAll('[data-tab-panel]');
    
    tabs.forEach(tab => {
      tab.addEventListener('click', () => {
        const target = tab.dataset.tab;
        
        tabs.forEach(t => {
          t.classList.remove('is-active');
          t.setAttribute('aria-selected', 'false');
        });
        tab.classList.add('is-active');
        tab.setAttribute('aria-selected', 'true');
        
        panels.forEach(p => {
          if (p.dataset.tabPanel === target) {
            p.classList.add('is-active');
            p.hidden = false;
          } else {
            p.classList.remove('is-active');
            p.hidden = true;
          }
        });
      });
    });
  });

  // Register toggle
  const registerToggle = document.querySelector('[data-register-toggle]');
  const registerPanel = document.querySelector('[data-register-panel]');
  const loginSection = document.querySelector('[data-login-section]');
  const registerCancel = document.querySelector('[data-register-cancel]');

  const authHeading = document.querySelector('[data-auth-heading]');

  if (registerToggle && registerPanel && loginSection) {
    registerToggle.addEventListener('click', () => {
      loginSection.hidden = true;
      registerPanel.hidden = false;
      if (authHeading) authHeading.textContent = 'Create an Account';
      document.title = 'Create an Account';
    });
  }

  if (registerCancel && registerPanel && loginSection) {
    registerCancel.addEventListener('click', () => {
      registerPanel.hidden = true;
      loginSection.hidden = false;
      if (authHeading) authHeading.textContent = 'Log In';
      document.title = 'Sign in';
      // Clear any registration form status messages
      document.querySelector('[data-passkey-register-status]').textContent = '';
      document.querySelector('[data-register-status]').textContent = '';
    });
  }

  const jsonHeaders = { "Content-Type": "application/json" };

  const postJSON = async (url, body, options = {}) => {
    const response = await fetch(url, {
      method: options.method || "POST",
      headers: jsonHeaders,
      credentials: "same-origin",
      body: body === undefined ? undefined : JSON.stringify(body),
    });
    const data = await response.json().catch(() => ({}));
    if (!response.ok) {
      throw new Error(data.error || `Request failed (${response.status})`);
    }
    return data;
  };

  const setStatus = (selector, message, isError = false) => {
    const target = document.querySelector(selector);
    if (!target) return;
    target.textContent = message;
    target.dataset.state = isError ? "error" : "ok";
  };

  const authNext = () => document.querySelector("[data-auth-next]")?.value || "/account";

  const formJSON = (form) => Object.fromEntries(new FormData(form).entries());

  document.querySelector("[data-initial-setup]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    const form = event.currentTarget;
    try {
      await postJSON("/api/setup", {
        email: form.elements.email.value,
        displayName: form.elements.displayName.value,
        password: form.elements.password.value,
        signupsEnabled: form.elements.signupsEnabled.checked,
      });
      window.location.href = "/account";
    } catch (error) {
      setStatus("[data-setup-status]", error.message, true);
    }
  });

  const base64URLToBuffer = (value) => {
    const padded = value.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(value.length / 4) * 4, "=");
    const binary = atob(padded);
    const bytes = new Uint8Array(binary.length);
    for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);
    return bytes.buffer;
  };

  const bufferToBase64URL = (value) => {
    const bytes = new Uint8Array(value);
    let binary = "";
    for (const byte of bytes) binary += String.fromCharCode(byte);
    return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
  };

  const credentialToJSON = (credential) => {
    if (credential instanceof ArrayBuffer) return bufferToBase64URL(credential);
    if (ArrayBuffer.isView(credential)) return bufferToBase64URL(credential.buffer);
    if (Array.isArray(credential)) return credential.map(credentialToJSON);
    if (credential && typeof credential === "object") {
      const next = {};
      for (const [key, value] of Object.entries(credential)) next[key] = credentialToJSON(value);
      return next;
    }
    return credential;
  };

  const normalizeCreateOptions = (options) => {
    const publicKey = { ...options.publicKey };
    publicKey.challenge = base64URLToBuffer(publicKey.challenge);
    publicKey.user = { ...publicKey.user, id: base64URLToBuffer(publicKey.user.id) };
    publicKey.excludeCredentials = (publicKey.excludeCredentials || []).map((credential) => ({
      ...credential,
      id: base64URLToBuffer(credential.id),
    }));
    return { publicKey };
  };

  const normalizeRequestOptions = (options) => {
    const publicKey = { ...options.publicKey };
    publicKey.challenge = base64URLToBuffer(publicKey.challenge);
    publicKey.allowCredentials = (publicKey.allowCredentials || []).map((credential) => ({
      ...credential,
      id: base64URLToBuffer(credential.id),
    }));
    return { publicKey };
  };

  document.querySelector("[data-auth-login]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    try {
      await postJSON("/api/auth/login/password", formJSON(event.currentTarget));
      window.location.href = authNext();
    } catch (error) {
      setStatus("[data-login-status]", error.message, true);
    }
  });

  document.querySelector("[data-dev-login]")?.addEventListener("click", async () => {
    try {
      await postJSON("/api/auth/login/dev", {});
      window.location.href = authNext();
    } catch (error) {
      setStatus("[data-dev-login-status]", error.message, true);
    }
  });

  document.querySelector("[data-auth-register]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    try {
      await postJSON("/api/auth/register/password", formJSON(event.currentTarget));
      setStatus("[data-register-status]", "Account created. Sign in with your password.");
      event.currentTarget.reset();
    } catch (error) {
      setStatus("[data-register-status]", error.message, true);
    }
  });

  const webAuthnErrorMessage = (error) => {
    console.error("WebAuthn error:", error.name, error.message, error);
    switch (error.name) {
      case "NotAllowedError":
        return "Passkey creation was cancelled or no authenticator is available. If you dismissed a prompt, try again. If no prompt appeared, your device may not support passkeys.";
      case "NotSupportedError":
        return "This browser or device does not support passkeys.";
      case "SecurityError":
        return "Passkeys require a secure context. Use https:// or localhost.";
      case "InvalidStateError":
        return "A passkey may already exist for this account.";
      default:
        return error.message || "Passkey failed. Check the console for details.";
    }
  };

  const checkPasskeySupport = async () => {
    if (!window.PublicKeyCredential) {
      return { supported: false, reason: "Passkeys are not available in this browser." };
    }
    try {
      if (PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable) {
        const available = await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();
        if (!available) {
          return { supported: true, reason: "No platform authenticator found (e.g., Touch ID, Windows Hello). You can still use a security key if you have one." };
        }
      }
      return { supported: true };
    } catch {
      return { supported: true };
    }
  };

  document.querySelector("[data-passkey-register]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    const support = await checkPasskeySupport();
    if (!support.supported) {
      setStatus("[data-passkey-register-status]", support.reason, true);
      return;
    }
    if (support.reason) {
      console.warn("Passkey support:", support.reason);
    }
    try {
      const begin = await postJSON("/api/auth/passkeys/register/begin", formJSON(event.currentTarget));
      const credential = await navigator.credentials.create(normalizeCreateOptions(begin.options));
      await postJSON(`/api/auth/passkeys/register/finish?challengeId=${encodeURIComponent(begin.challengeId)}`, credentialToJSON(credential));
      setStatus("[data-passkey-register-status]", "Passkey created. Sign in with your passkey.");
    } catch (error) {
      setStatus("[data-passkey-register-status]", webAuthnErrorMessage(error), true);
    }
  });

  document.querySelector("[data-passkey-login]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    const support = await checkPasskeySupport();
    if (!support.supported) {
      setStatus("[data-passkey-login-status]", support.reason, true);
      return;
    }
    if (support.reason) {
      console.warn("Passkey support:", support.reason);
    }
    try {
      const begin = await postJSON("/api/auth/passkeys/login/begin", formJSON(event.currentTarget));
      const credential = await navigator.credentials.get(normalizeRequestOptions(begin.options));
      await postJSON(`/api/auth/passkeys/login/finish?challengeId=${encodeURIComponent(begin.challengeId)}`, credentialToJSON(credential));
      window.location.href = authNext();
    } catch (error) {
      setStatus("[data-passkey-login-status]", webAuthnErrorMessage(error), true);
    }
  });

  document.querySelector("[data-passkey-add]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    const support = await checkPasskeySupport();
    if (!support.supported) {
      setStatus("[data-passkey-add-status]", support.reason, true);
      return;
    }
    if (support.reason) {
      console.warn("Passkey support:", support.reason);
    }
    try {
      const begin = await postJSON("/api/auth/passkeys/me/register/begin", {});
      const credential = await navigator.credentials.create(normalizeCreateOptions(begin.options));
      await postJSON(`/api/auth/passkeys/me/register/finish?challengeId=${encodeURIComponent(begin.challengeId)}`, credentialToJSON(credential));
      setStatus("[data-passkey-add-status]", "Passkey added. You can use it the next time you sign in.");
    } catch (error) {
      setStatus("[data-passkey-add-status]", webAuthnErrorMessage(error), true);
    }
  });

  document.querySelector("[data-auth-logout]")?.addEventListener("click", async () => {
    try {
      await postJSON("/api/auth/logout", {});
    } catch (error) {
      console.warn("Logout request failed:", error);
    } finally {
      window.location.href = "/login";
    }
  });

  const loadTokens = async () => {
    const list = document.querySelector("[data-token-list]");
    if (!list) return;
    const data = await fetch("/api/tokens", { credentials: "same-origin" }).then((response) => response.json());
    if (!data.tokens?.length) {
      const empty = document.createElement("li");
      empty.className = "token-empty";
      empty.textContent = "No access tokens yet. Create one when you connect the macOS app, CLI, or another trusted client.";
      list.replaceChildren(empty);
      return;
    }
    list.replaceChildren(
      ...data.tokens.map((token) => {
        const item = document.createElement("li");
        item.className = `token-row${token.revokedAt ? " is-revoked" : ""}`;
        const meta = document.createElement("span");
        meta.className = "token-meta";
        const name = document.createElement("strong");
        name.textContent = token.name;
        const details = document.createElement("small");
        details.textContent = `${token.scopes.join(", ")}${token.revokedAt ? " - revoked" : ""}`;
        meta.append(name, details);
        const button = document.createElement("button");
        button.type = "button";
        button.textContent = "Revoke";
        button.disabled = Boolean(token.revokedAt);
        button.addEventListener("click", async () => {
          await fetch(`/api/tokens/${encodeURIComponent(token.id.replace(/^api:/, ""))}`, {
            method: "DELETE",
            credentials: "same-origin",
          });
          await loadTokens();
        });
        item.append(meta, button);
        return item;
      }),
    );
  };

  document.querySelector("[data-token-create]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    const form = event.currentTarget;
    const scopes = [...form.querySelectorAll('input[name="scope"]:checked')].map((input) => input.value);
    try {
      const created = await postJSON("/api/tokens", { name: form.elements.name.value, scopes });
      const output = document.querySelector("[data-token-output]");
      if (output) {
        output.hidden = false;
        output.textContent = created.token;
      }
      setStatus("[data-token-status]", "Token created. Copy it now; it will not be shown again.");
      form.reset();
      await loadTokens();
    } catch (error) {
      setStatus("[data-token-status]", error.message, true);
    }
  });

  document.querySelector("[data-password-change]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    try {
      await postJSON("/api/auth/password/change", formJSON(event.currentTarget));
      setStatus("[data-password-status]", "Password changed.");
      event.currentTarget.reset();
    } catch (error) {
      setStatus("[data-password-status]", error.message, true);
    }
  });

  document.querySelector("[data-password-reset]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    try {
      await postJSON("/api/auth/password/reset", formJSON(event.currentTarget));
      setStatus("[data-password-reset-status]", "Password reset. You can sign in with your new password.");
      event.currentTarget.querySelector('input[name="newPassword"]').value = "";
    } catch (error) {
      setStatus("[data-password-reset-status]", error.message, true);
    }
  });

  document.querySelector("[data-account-delete]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    if (!confirm("Delete this account permanently?")) return;
    try {
      await postJSON("/api/auth/account", formJSON(event.currentTarget), { method: "DELETE" });
      window.location.href = "/login";
    } catch (error) {
      setStatus("[data-delete-status]", error.message, true);
    }
  });

  document.querySelector("[data-device-approve]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    try {
      await postJSON("/api/device/approve", formJSON(event.currentTarget));
      setStatus("[data-device-status]", "Device approved.");
    } catch (error) {
      if (error.message === "authentication required") {
        window.location.href = `/login?next=${encodeURIComponent(window.location.pathname + window.location.search)}`;
        return;
      }
      setStatus("[data-device-status]", error.message, true);
    }
  });

  const loadAdminUsers = async () => {
    const section = document.querySelector("[data-admin-users-section]");
    const list = document.querySelector("[data-admin-user-list]");
    if (!section || !list) return;
    const me = await fetch("/api/auth/me", { credentials: "same-origin" }).then((response) => response.json()).catch(() => null);
    if (me?.principal?.role !== "admin") return;
    section.hidden = false;
    const data = await fetch("/api/admin/auth-users", { credentials: "same-origin" }).then((response) => response.json());
    list.replaceChildren(
      ...(data.users || []).map((user) => {
        const row = document.createElement("div");
        row.className = "user-row";
        row.dataset.userId = user.id;
        const identity = document.createElement("span");
        const name = document.createElement("strong");
        name.textContent = user.displayName;
        const email = document.createElement("small");
        email.textContent = user.email;
        identity.append(name, email);
        const select = document.createElement("select");
        for (const role of ["viewer", "editor", "admin"]) {
          const option = document.createElement("option");
          option.value = role;
          option.textContent = role;
          option.selected = user.role === role;
          select.append(option);
        }
        select.name = "role";
        select.setAttribute("aria-label", `Role for ${user.displayName}`);
        const disabledLabel = document.createElement("label");
        disabledLabel.className = "user-disable-toggle";
        const disabled = document.createElement("input");
        disabled.type = "checkbox";
        disabled.name = "disabled";
        disabled.checked = Boolean(user.disabled);
        const disabledText = document.createElement("span");
        disabledText.textContent = "Disabled";
        disabledLabel.append(disabled, disabledText);
        const reset = document.createElement("button");
        reset.type = "button";
        reset.textContent = "Send password reset";
        reset.addEventListener("click", async () => {
          if (!confirm(`Send a new password reset email to ${user.email}? Any earlier reset link will stop working.`)) return;
          try {
            await postJSON(`/api/admin/auth-users/${encodeURIComponent(user.id)}/password-reset`, {});
            setStatus("[data-admin-users-status]", `Password reset email sent to ${user.email}.`);
          } catch (error) {
            setStatus("[data-admin-users-status]", error.message, true);
          }
        });
        row.append(identity, select, disabledLabel, reset);
        return row;
      }),
    );
  };

  document.querySelector("[data-admin-users]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    const form = event.currentTarget;
    const users = [...form.querySelectorAll("[data-user-id]")].map((row) => ({
      id: row.dataset.userId,
      role: row.querySelector('select[name="role"]').value,
      disabled: row.querySelector('input[name="disabled"]').checked,
    }));
    try {
      await postJSON("/api/admin/auth-users", { users }, { method: "PATCH" });
      setStatus("[data-admin-users-status]", "User access settings saved.");
      await loadAdminUsers();
    } catch (error) {
      setStatus("[data-admin-users-status]", error.message, true);
    }
  });

  const loadAdminSettings = async () => {
    const section = document.querySelector("[data-admin-settings-section]");
    const form = document.querySelector("[data-admin-settings]");
    if (!section || !form) return;
    const me = await fetch("/api/auth/me", { credentials: "same-origin" }).then((response) => response.json()).catch(() => null);
    if (me?.principal?.role !== "admin") return;
    section.hidden = false;
    const data = await fetch("/api/admin/settings", { credentials: "same-origin" }).then((response) => response.json());
    form.elements.signupsEnabled.checked = Boolean(data.settings?.signupsEnabled);
  };

  document.querySelector("[data-admin-settings]")?.addEventListener("submit", async (event) => {
    event.preventDefault();
    try {
      const form = event.currentTarget;
      await postJSON("/api/admin/settings", { signupsEnabled: form.elements.signupsEnabled.checked }, { method: "PATCH" });
      setStatus("[data-admin-settings-status]", "Registration setting saved.");
    } catch (error) {
      setStatus("[data-admin-settings-status]", error.message, true);
    }
  });

  loadTokens().catch(() => {});
  loadAdminUsers().catch(() => {});
  loadAdminSettings().catch(() => {});
})();
