// public/assets/login.js
/* English comments: login + MFA flow */

const qs = (id) => document.getElementById(id);
const i18n = window.I18N || {};
const t = (key, fallback) => {
  if (key && Object.prototype.hasOwnProperty.call(i18n, key)) {
    const val = i18n[key];
    return val !== '' ? val : fallback;
  }
  return fallback;
};

const errorKeyByMessage = {
  'Email and password required': 'auth.error.email_password_required',
  'Invalid credentials': 'auth.error.invalid_credentials',
  'Email required': 'auth.error.email_required',
  'Request failed': 'auth.error.request_failed',
  'Code required': 'auth.error.code_required',
  'Invalid code': 'auth.error.invalid_code',
};

function normalizeErrorMessage(message, fallbackKey, fallbackText) {
  if (message && Object.prototype.hasOwnProperty.call(errorKeyByMessage, message)) {
    return t(errorKeyByMessage[message], message);
  }
  return message || t(fallbackKey, fallbackText);
}

function showError(msg) {
  const el = qs('loginError');
  if (!el) return;
  el.textContent = msg;
  el.classList.remove('is-hidden');
}

function clearError() {
  if (retryTimer) {
    clearInterval(retryTimer);
    retryTimer = null;
  }
  const el = qs('loginError');
  if (!el) return;
  el.textContent = '';
  el.classList.add('is-hidden');
}

let retryTimer = null;
let retryUntilTs = 0;
let retryShown = null;

function formatRetryMessage(secondsLeft) {
  return t('auth.error.too_many_attempts', 'Too many attempts. Try again in {seconds}s.')
    .replace('{seconds}', String(secondsLeft));
}

function showRetryError(seconds) {
  const el = qs('loginError');
  if (!el) return;
  const now = Date.now();
  retryUntilTs = now + Math.max(0, seconds) * 1000;
  retryShown = null;
  el.textContent = formatRetryMessage(Math.max(0, Math.ceil((retryUntilTs - now) / 1000)));
  el.classList.remove('is-hidden');
  if (retryTimer) {
    clearInterval(retryTimer);
  }
  retryTimer = setInterval(() => {
    const remaining = Math.max(0, Math.ceil((retryUntilTs - Date.now()) / 1000));
    if (retryShown === null) {
      retryShown = remaining;
    } else if (retryShown > remaining) {
      // Smoothly converge if timer drifts or tab throttles.
      retryShown = Math.max(remaining, retryShown - 1);
    } else {
      retryShown = remaining;
    }
    el.textContent = formatRetryMessage(retryShown);
    if (remaining <= 0) {
      clearInterval(retryTimer);
      retryTimer = null;
    }
  }, 250);
}

async function login() {
  clearError();
  const email = qs('loginEmail')?.value || '';
  const password = qs('loginPassword')?.value || '';
  const remember = !!qs('loginRemember')?.checked;
  if (!email || !password) {
    showError(t('auth.error.email_password_required', 'Email and password required'));
    return;
  }
  const res = await fetch('/api/auth/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password, client_type: 'web' }),
  });
  const data = await res.json();
  if (!data?.ok) {
    const retry = data?.error?.retry_after;
    if (retry) {
      showRetryError(retry);
    } else {
      const msg = normalizeErrorMessage(data?.error?.message || '', 'auth.error.login_failed', 'Login failed');
      showError(msg);
    }
    return;
  }
  if (data?.data?.mfa_required) {
    window.__mfaChallenge = data?.data?.challenge_token || '';
    window.__rememberSession = remember;
    qs('loginForm')?.classList.add('is-hidden');
    qs('mfaForm')?.classList.remove('is-hidden');
    return;
  }
  window.Auth.setTokens(data?.data || {}, 'web', remember);
  window.location.href = '/';
}

function showForgot() {
  qs('loginForm')?.classList.add('is-hidden');
  qs('mfaForm')?.classList.add('is-hidden');
  qs('forgotForm')?.classList.remove('is-hidden');
}

function showLoginForm() {
  qs('forgotForm')?.classList.add('is-hidden');
  qs('mfaForm')?.classList.add('is-hidden');
  qs('loginForm')?.classList.remove('is-hidden');
}

async function sendForgot() {
  clearError();
  const email = qs('forgotEmail')?.value || '';
  if (!email) {
    showError(t('auth.error.email_required', 'Email required'));
    return;
  }
  const res = await fetch('/api/auth/password/forgot', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email }),
  });
  const data = await res.json().catch(() => null);
  if (!data?.ok) {
    showError(normalizeErrorMessage(data?.error?.message || '', 'auth.error.request_failed', 'Request failed'));
    return;
  }
  showError(t('auth.error.reset_sent', 'If this email exists, a reset link will be sent.'));
}

async function verifyMfa() {
  clearError();
  const code = qs('mfaCode')?.value || '';
  const challenge = window.__mfaChallenge || '';
  const remember = window.__rememberSession !== false;
  if (!code || !challenge) {
    showError(t('auth.error.code_required', 'Code required'));
    return;
  }
  const res = await fetch('/api/auth/2fa/verify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ challenge_token: challenge, code, client_type: 'web' }),
  });
  const data = await res.json();
  if (!data?.ok) {
    const retry = data?.error?.retry_after;
    if (retry) {
      showRetryError(retry);
    } else {
      const msg = normalizeErrorMessage(data?.error?.message || '', 'auth.error.invalid_code', 'Invalid code');
      showError(msg);
    }
    return;
  }
  window.Auth.setTokens(data?.data || {}, 'web', remember);
  window.location.href = '/';
}

function init() {
  const access = window.Auth?.getAccessToken?.() || '';
  const refresh = window.Auth?.getRefreshToken?.() || '';
  if (access && refresh && window.Auth?.refreshTokens) {
    window.Auth.refreshTokens().then((ok) => {
      if (ok) {
        window.location.href = '/';
      } else if (window.Auth?.clearTokens) {
        window.Auth.clearTokens();
      }
    });
    return;
  }
  if (access && window.Auth?.clearTokens) {
    window.Auth.clearTokens();
  }
  const loginBtn = qs('btnLogin');
  if (loginBtn) loginBtn.addEventListener('click', login);
  const forgotBtn = qs('btnForgot');
  if (forgotBtn) forgotBtn.addEventListener('click', showForgot);
  const forgotSend = qs('btnForgotSend');
  if (forgotSend) forgotSend.addEventListener('click', sendForgot);
  const forgotBack = qs('btnForgotBack');
  if (forgotBack) forgotBack.addEventListener('click', showLoginForm);
  const verifyBtn = qs('btnMfaVerify');
  if (verifyBtn) verifyBtn.addEventListener('click', verifyMfa);
}

init();
