// ===== TOTP RECOVERY FLOW =====
// Public, unauthenticated recovery path for users who can't log in.
// Designed for the "encryption key rotated and lost my authenticator" case.
// The flow is:
//
//  1. On TOTP overlay show, call /api/v1/totp/recovery-info (public).
//     If status === 'unreadable', show the "Lost access?" link on the overlay.
//  2. User clicks link → opens recovery panel.
//  3. User pastes Base32 secret → POST /api/v1/totp/setup with {secret: ...}.
//     Backend stores as totp.pending_secret (encrypted with current key).
//  4. Panel switches to "verify" mode. User enters a code from the
//     newly-added authenticator entry. POST /api/v1/totp/verify-setup
//     promotes pending → active and starts a session.
//  5. hideTotpOverlay() and initializeDashboard() — same as normal login.
//
// The recovery flow never requires the user to be logged in. It does require
// them to have their Base32 secret saved (e.g. password manager, screenshot,
// the "Download backup file" we offer at setup time — see totp-settings.js).

(function() {
  'use strict';

  // ── Helpers ──
  async function fetchRecoveryInfo() {
    try {
      const r = await fetch('/api/v1/totp/recovery-info', { cache: 'no-store' });
      return await r.json();
    } catch (e) {
      return { success: false, status: 'unknown', hint: 'Could not contact server' };
    }
  }

  function showRecoveryLink(show) {
    const link = document.getElementById('totp-recovery-link');
    if (link) link.style.display = show ? '' : 'none';
  }

  function openRecoveryPanel() {
    const panel = document.getElementById('totp-recovery-panel');
    if (panel) panel.style.display = '';
    const statusEl = document.getElementById('totp-recovery-status');
    const importEl = document.getElementById('totp-recovery-import');
    const verifyEl = document.getElementById('totp-recovery-verify');
    if (importEl) importEl.style.display = '';
    if (verifyEl) verifyEl.style.display = 'none';
    // Reset state
    document.getElementById('totp-recovery-error').textContent = '';
    document.getElementById('totp-recovery-confirm-error').textContent = '';
    document.getElementById('totp-recovery-secret').value = '';
    document.getElementById('totp-recovery-code').value = '';
    // Show current status
    fetchRecoveryInfo().then(info => {
      statusEl.textContent = info.hint || '';
      // Color-code the status banner
      if (info.status === 'healthy') {
        statusEl.style.borderColor = 'var(--ok-fg, #7ef2ff)';
      } else if (info.status === 'unreadable') {
        statusEl.style.borderColor = 'var(--bad-fg, #ff9aa3)';
        statusEl.style.background = 'color-mix(in srgb, var(--bad-fg) 6%, transparent)';
      } else if (info.status === 'not_configured') {
        statusEl.style.borderColor = 'var(--muted)';
      } else {
        statusEl.style.borderColor = 'var(--border)';
      }
    });
    setTimeout(() => {
      document.getElementById('totp-recovery-secret')?.focus();
    }, 100);
  }

  function closeRecoveryPanel() {
    const panel = document.getElementById('totp-recovery-panel');
    if (panel) panel.style.display = 'none';
  }

  async function submitRecoverySecret() {
    const secret = document.getElementById('totp-recovery-secret').value.trim();
    const errorEl = document.getElementById('totp-recovery-error');
    errorEl.textContent = '';

    if (!secret) {
      errorEl.textContent = 'Paste your Base32 key first';
      return;
    }
    if (!/^[A-Za-z2-7\s]+=*$/.test(secret)) {
      errorEl.textContent = 'Invalid Base32 format — should be letters A-Z and digits 2-7 only';
      return;
    }

    // POST /api/v1/totp/setup with {secret} — backend stores as pending
    try {
      const r = await fetch('/api/v1/totp/setup', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ secret })
      });
      const data = await r.json();
      if (!r.ok || !data.success) {
        errorEl.textContent = data.error || data.message || 'Restore failed';
        return;
      }
      // Switch panel to verify mode
      document.getElementById('totp-recovery-import').style.display = 'none';
      document.getElementById('totp-recovery-verify').style.display = '';
      setTimeout(() => document.getElementById('totp-recovery-code')?.focus(), 100);
    } catch (e) {
      errorEl.textContent = 'Network error — try again';
    }
  }

  async function submitRecoveryCode() {
    const code = document.getElementById('totp-recovery-code').value.trim();
    const errorEl = document.getElementById('totp-recovery-confirm-error');
    errorEl.textContent = '';

    if (!/^\d{6}$/.test(code)) {
      errorEl.textContent = 'Enter a 6-digit code';
      return;
    }

    // POST /api/v1/totp/verify-setup — promotes pending → active + starts session
    try {
      const r = await fetch('/api/v1/totp/verify-setup', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ code })
      });
      const data = await r.json();
      if (!r.ok || !data.success) {
        errorEl.textContent = data.error || data.message || 'Invalid code';
        document.getElementById('totp-recovery-code').value = '';
        document.getElementById('totp-recovery-code')?.focus();
        return;
      }
      // Success — hide everything and initialize dashboard
      closeRecoveryPanel();
      const overlay = document.getElementById('totp-overlay');
      if (overlay) overlay.classList.remove('show');
      if (typeof window.initializeDashboard === 'function') {
        window.initializeDashboard();
      }
    } catch (e) {
      errorEl.textContent = 'Network error — try again';
    }
  }

  // ── Wire up handlers ──
  document.getElementById('totp-show-recovery')?.addEventListener('click', (e) => {
    e.preventDefault();
    openRecoveryPanel();
  });
  document.getElementById('totp-recovery-close')?.addEventListener('click', closeRecoveryPanel);
  document.getElementById('totp-recovery-submit')?.addEventListener('click', submitRecoverySecret);
  document.getElementById('totp-recovery-confirm')?.addEventListener('click', submitRecoveryCode);

  // Enter key submits in secret field
  document.getElementById('totp-recovery-secret')?.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') { e.preventDefault(); submitRecoverySecret(); }
  });
  // Enter key submits in code field
  document.getElementById('totp-recovery-code')?.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') { e.preventDefault(); submitRecoveryCode(); }
  });

  // ── Public API ──
  // Called by totp-auth.js after showing the overlay, so we can decide whether
  // to show the recovery link. We do this with a public endpoint that doesn't
  // require auth — perfect for the locked-out state.
  window._refreshRecoveryLink = async function() {
    const info = await fetchRecoveryInfo();
    // Show the link in any non-healthy state (unreadable / corrupt / unknown).
    // The hint inside the panel tells the user what the actual issue is.
    if (info && info.success && info.status && info.status !== 'healthy') {
      showRecoveryLink(true);
    } else {
      showRecoveryLink(false);
    }
    return info;
  };
})();
