// Email verification + password reset pages.
//
// Backend contract — see apps/frontend/public/api-client.js:
//   forgotPassword({ email })            → POST /v1/auth/password-reset         → 204
//   resetPassword({ token, newPassword }) → POST /v1/auth/password-reset/confirm → 204
//   verifyEmail({ token })               → POST /v1/auth/email/verify           → 204
//
// Token comes from the email link's `?token=` query string. main.jsx
// reads `?route=` on initial load so the email link can route directly
// to auth:reset or auth:verify.

const _AuthShell = ({ eyebrow, title, subtitle, children }) => (
  <div className="page">
    <div style={{ maxWidth: 480, margin: '0 auto', padding: '64px 24px' }}>
      {eyebrow && <div className="eyebrow">{eyebrow}</div>}
      <h1 className="display" style={{ fontSize: 32, marginBottom: 12 }}>{title}</h1>
      {subtitle && (
        <p style={{ color: 'var(--t-ink-muted)', fontSize: 15, marginBottom: 32 }}>{subtitle}</p>
      )}
      {children}
    </div>
  </div>
);

const _StatusBox = ({ tone, children }) => {
  const palette = {
    info:    { bg: 'var(--coral-bg)',                 fg: 'var(--t-ink)',     border: 'var(--t-line)' },
    error:   { bg: '#FBE9E9',                         fg: '#7A2A2A',          border: '#D64545' },
    success: { bg: 'var(--mint-light)',               fg: 'var(--mint-dark)', border: 'var(--mint)' },
  }[tone] || { bg: '#F6EDDF', fg: 'var(--t-ink-muted)', border: '#D9CABA' };
  return (
    <div style={{
      background: palette.bg, color: palette.fg, border: `1px solid ${palette.border}`,
      borderRadius: 'var(--t-radius-sm)', padding: '12px 16px', fontSize: 14, lineHeight: 1.5,
      marginBottom: 16,
    }}>{children}</div>
  );
};

// Tokens arrive via the email link as `?token=...`. Reset / verify pages
// read it once on mount. Returns null if absent or empty.
const _readUrlToken = () => {
  try {
    return new URLSearchParams(window.location.search).get('token') || null;
  } catch (e) {
    return null;
  }
};

// ============================ ForgotPasswordPage ============================
const ForgotPasswordPage = ({ go }) => {
  const { t } = window.useI18n();
  const [email, setEmail] = useState('');
  const [phase, setPhase] = useState('form'); // form | submitting | sent
  const [error, setError] = useState('');

  const submit = async (e) => {
    if (e?.preventDefault) e.preventDefault();
    if (!email || phase === 'submitting') return;
    setError('');
    setPhase('submitting');
    try {
      // API always returns 204 to avoid enumeration — we show the confirmation
      // regardless of whether the email is registered.
      await window.HelperMatchApi.forgotPassword({ email });
      setPhase('sent');
    } catch (err) {
      // Only surface a real error (network down, 5xx) — never indicate
      // whether the email was found.
      setError(err?.message || 'Unable to send reset link. Please try again.');
      setPhase('form');
    }
  };

  if (phase === 'sent') {
    return (
      <_AuthShell
        eyebrow={t('auth.forgot.eyebrow')}
        title={t('auth.forgot.sentTitle')}
        subtitle={t('auth.forgot.sentSub').replace('{email}', email)}
      >
        <button className="btn btn-outline btn-block" onClick={() => go && go('auth:login')}>
          {t('auth.backToLogin')}
        </button>
      </_AuthShell>
    );
  }

  return (
    <_AuthShell
      eyebrow={t('auth.forgot.eyebrow')}
      title={t('auth.forgot.title')}
      subtitle={t('auth.forgot.sub')}
    >
      {error && <_StatusBox tone="error">{error}</_StatusBox>}
      <form onSubmit={submit}>
        <div style={{ marginBottom: 16 }}>
          <label className="label">{t('auth.email')}</label>
          <input
            className="input"
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            placeholder="you@example.com"
            required
          />
        </div>
        <button
          className="btn btn-primary btn-lg btn-block"
          type="submit"
          disabled={!email || phase === 'submitting'}
          style={{ marginBottom: 12, opacity: phase === 'submitting' ? 0.72 : 1 }}
        >
          {phase === 'submitting' ? t('common.sending') : t('auth.forgot.cta')}
        </button>
      </form>
      <div style={{ textAlign: 'center', fontSize: 14, color: 'var(--t-ink-muted)' }}>
        <a style={{ color: 'var(--t-accent)', cursor: 'pointer' }} onClick={() => go && go('auth:login')}>
          {t('auth.backToLogin')}
        </a>
      </div>
    </_AuthShell>
  );
};

// ============================ ResetPasswordPage =============================
const ResetPasswordPage = ({ go }) => {
  const { t } = window.useI18n();
  const [token] = useState(_readUrlToken);
  const [pw, setPw] = useState('');
  const [pw2, setPw2] = useState('');
  const [phase, setPhase] = useState('form'); // form | submitting | done
  const [error, setError] = useState('');
  const tooShort = pw.length > 0 && pw.length < 8;
  const mismatch = pw2.length > 0 && pw !== pw2;
  const canSubmit = !!token && pw.length >= 8 && pw === pw2 && phase === 'form';

  const submit = async (e) => {
    if (e?.preventDefault) e.preventDefault();
    if (!canSubmit) return;
    setError('');
    setPhase('submitting');
    try {
      await window.HelperMatchApi.resetPassword({ token, newPassword: pw });
      setPhase('done');
    } catch (err) {
      setError(err?.message || t('auth.reset.invalidToken'));
      setPhase('form');
    }
  };

  if (phase === 'done') {
    return (
      <_AuthShell
        eyebrow={t('auth.reset.eyebrow')}
        title={t('auth.reset.doneTitle')}
        subtitle={t('auth.reset.doneSub')}
      >
        <button className="btn btn-primary btn-lg btn-block" onClick={() => go && go('auth:login')}>
          {t('auth.submitLogin')}
        </button>
      </_AuthShell>
    );
  }

  return (
    <_AuthShell
      eyebrow={t('auth.reset.eyebrow')}
      title={t('auth.reset.title')}
      subtitle={t('auth.reset.sub')}
    >
      {!token && <_StatusBox tone="error">{t('auth.reset.invalidToken')}</_StatusBox>}
      {error && <_StatusBox tone="error">{error}</_StatusBox>}
      <form onSubmit={submit}>
        <div style={{ marginBottom: 12 }}>
          <label className="label">{t('auth.newPassword')}</label>
          <input
            className="input"
            type="password"
            value={pw}
            onChange={(e) => setPw(e.target.value)}
            placeholder="••••••••"
            minLength={8}
            required
          />
          {tooShort && (
            <div style={{ color: '#D64545', fontSize: 12, marginTop: 4 }}>
              {t('auth.passwordTooShort')}
            </div>
          )}
        </div>
        <div style={{ marginBottom: 16 }}>
          <label className="label">{t('auth.confirmPassword')}</label>
          <input
            className="input"
            type="password"
            value={pw2}
            onChange={(e) => setPw2(e.target.value)}
            placeholder="••••••••"
            required
          />
          {mismatch && (
            <div style={{ color: '#D64545', fontSize: 12, marginTop: 4 }}>
              {t('auth.passwordMismatch')}
            </div>
          )}
        </div>
        <button
          className="btn btn-primary btn-lg btn-block"
          type="submit"
          disabled={!canSubmit}
          style={{ opacity: phase === 'submitting' ? 0.72 : 1 }}
        >
          {phase === 'submitting' ? t('common.saving') : t('auth.reset.cta')}
        </button>
      </form>
    </_AuthShell>
  );
};

// ============================ VerifyEmailPage ===============================
// API returns 204 on success without a session, so post-verify we send the
// user to the login page rather than the dashboard.
const VerifyEmailPage = ({ go }) => {
  const { t } = window.useI18n();
  const [phase, setPhase] = useState('verifying'); // verifying | verified | failed

  useEffect(() => {
    const token = _readUrlToken();
    if (!token) {
      setPhase('failed');
      return;
    }
    let cancelled = false;
    window.HelperMatchApi.verifyEmail({ token })
      .then(() => { if (!cancelled) setPhase('verified'); })
      .catch(() => { if (!cancelled) setPhase('failed'); });
    return () => { cancelled = true; };
  }, []);

  if (phase === 'verifying') {
    return (
      <_AuthShell
        eyebrow={t('auth.verify.eyebrow')}
        title={t('auth.verify.verifying')}
        subtitle={t('auth.verify.verifyingSub')}
      />
    );
  }

  if (phase === 'failed') {
    return (
      <_AuthShell
        eyebrow={t('auth.verify.eyebrow')}
        title={t('auth.verify.failedTitle')}
        subtitle={t('auth.verify.failedSub')}
      >
        <button className="btn btn-primary btn-lg btn-block" onClick={() => go && go('auth:login')}>
          {t('auth.backToLogin')}
        </button>
      </_AuthShell>
    );
  }

  return (
    <_AuthShell
      eyebrow={t('auth.verify.eyebrow')}
      title={t('auth.verify.successTitle')}
      subtitle={t('auth.verify.successSub')}
    >
      <button className="btn btn-primary btn-lg btn-block" onClick={() => go && go('auth:login')}>
        {t('auth.verify.goLogin')}
      </button>
    </_AuthShell>
  );
};

Object.assign(window, { ForgotPasswordPage, ResetPasswordPage, VerifyEmailPage });
