(() => {
  const ACCESS_TOKEN_KEY = 'tiku_platform_access_token';
  const REFRESH_TOKEN_KEY = 'tiku_platform_refresh_token';
  const ACCESS_EXPIRES_KEY = 'tiku_platform_access_expires_at';
  const USER_KEY = 'tiku_platform_user';
  const runtime = window.GONGXUE_PLATFORM_RUNTIME_CONFIG || {};
  let challengeToken = '';
  let pendingResolve;

  function apiUrl(path) {
    return `${String(runtime.apiBaseUrl || '').replace(/\/+$/, '')}${path}`;
  }

  async function post(path, body) {
    const response = await fetch(apiUrl(path), {
      method: 'POST',
      headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
      credentials: 'omit',
      body: JSON.stringify(body),
    });
    const text = await response.text();
    let payload = {};
    if (text) {
      try { payload = JSON.parse(text); } catch { payload = { detail: text.slice(0, 500) }; }
    }
    if (!response.ok) throw new Error(payload.detail || payload.title || payload.message || `请求失败（HTTP ${response.status}）`);
    return payload;
  }

  function gate() { return document.querySelector('#platformAuthGate'); }

  function shell(title, description, content) {
    gate().innerHTML = `<section class="platform-auth-card" role="dialog" aria-modal="true"><header><img src="./assets/logo.png" alt="" /><div><h1>${title}</h1><p>${description}</p></div></header>${content}<p class="platform-auth-error" id="platformAuthError" role="alert"></p></section>`;
    gate().hidden = false;
    document.querySelector('.platform-app')?.setAttribute('inert', '');
  }

  function showError(error) {
    const target = document.querySelector('#platformAuthError');
    if (target) target.textContent = error?.message || '操作失败，请重试';
  }

  function setBusy(form, busy) {
    form.querySelectorAll('button,input').forEach(control => { control.disabled = busy; });
  }

  function storeAuthenticated(result) {
    const user = result?.user;
    const tokens = user?.tokens;
    if (!tokens?.accessToken || !tokens?.refreshToken) throw new Error('登录响应缺少令牌');
    sessionStorage.setItem(ACCESS_TOKEN_KEY, tokens.accessToken);
    sessionStorage.setItem(REFRESH_TOKEN_KEY, tokens.refreshToken);
    sessionStorage.setItem(ACCESS_EXPIRES_KEY, tokens.accessTokenExpiresAt || '');
    sessionStorage.setItem(USER_KEY, JSON.stringify({ userId: user.userId, email: user.email, name: user.name }));
  }

  function completeGate() {
    gate().hidden = true;
    gate().innerHTML = '';
    document.querySelector('.platform-app')?.removeAttribute('inert');
    pendingResolve?.(true);
    pendingResolve = null;
  }

  function finishAuthentication(result) {
    storeAuthenticated(result);
    completeGate();
  }

  async function handleAuthenticationResult(result) {
    challengeToken = result.challengeToken || '';
    if (result.status === 'authenticated') { finishAuthentication(result); return; }
    if (result.status === 'password_change_required') { renderPasswordChange(); return; }
    throw new Error(`不支持的认证状态：${result.status || 'unknown'}`);
  }

  function renderLogin() {
    shell('平台管理员登录', '连接真实 PostgreSQL 与 ASP.NET Core API。', `<form id="platformLoginForm"><label>平台账号<input name="identifier" type="email" autocomplete="username" required /></label><label>密码<input name="password" type="password" autocomplete="current-password" minlength="8" required /></label><button type="submit">登录</button></form>`);
    document.querySelector('#platformLoginForm').addEventListener('submit', async event => {
      event.preventDefault();
      const form = event.currentTarget;
      setBusy(form, true);
      try {
        const result = await post('/api/auth/login/password', { realm: 'platform', identifier: form.elements.identifier.value.trim(), password: form.elements.password.value });
        await handleAuthenticationResult(result);
      } catch (error) { showError(error); setBusy(form, false); }
    });
  }

  function renderPasswordChange() {
    shell('设置正式密码', '至少 8 位，且必须同时包含字母和数字。', `<form id="platformPasswordForm"><label>新密码<input name="newPassword" type="password" autocomplete="new-password" minlength="8" required /></label><label>确认新密码<input name="confirmPassword" type="password" autocomplete="new-password" minlength="8" required /></label><button type="submit">更新密码并继续</button></form>`);
    document.querySelector('#platformPasswordForm').addEventListener('submit', async event => {
      event.preventDefault();
      const form = event.currentTarget;
      if (form.elements.newPassword.value !== form.elements.confirmPassword.value) { showError(new Error('两次输入的密码不一致')); return; }
      setBusy(form, true);
      try { await handleAuthenticationResult(await post('/api/auth/password/change-required', { challengeToken, newPassword: form.elements.newPassword.value })); }
      catch (error) { showError(error); setBusy(form, false); }
    });
  }

  function clearSession() {
    [ACCESS_TOKEN_KEY, REFRESH_TOKEN_KEY, ACCESS_EXPIRES_KEY, USER_KEY].forEach(key => sessionStorage.removeItem(key));
  }

  function hasSession() {
    const token = sessionStorage.getItem(ACCESS_TOKEN_KEY);
    const expiresAt = Date.parse(sessionStorage.getItem(ACCESS_EXPIRES_KEY) || '');
    return Boolean(token) && Number.isFinite(expiresAt) && expiresAt > Date.now() + 15_000;
  }

  async function requireSession() {
    if (hasSession()) return true;
    clearSession();
    renderLogin();
    return new Promise(resolve => { pendingResolve = resolve; });
  }

  async function logout() {
    const refreshToken = sessionStorage.getItem(REFRESH_TOKEN_KEY);
    try { if (refreshToken) await post('/api/auth/logout', { refreshToken }); } catch { /* Clear the browser session even when revocation cannot be reached. */ }
    clearSession();
    location.reload();
  }

  window.GongxuePlatformAuth = Object.freeze({
    getAccessToken: () => sessionStorage.getItem(ACCESS_TOKEN_KEY) || '',
    getUser: () => {
      try { return JSON.parse(sessionStorage.getItem(USER_KEY) || 'null'); } catch { return null; }
    },
    logout,
    requireSession,
  });
})();
