import { useState, type FormEvent } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import * as authApi from '../../api/auth';
import { ApiError } from '../../api/http';
import { DEFAULT_TENANT, OTP_RESEND_COOLDOWN_SECONDS } from '../../config';
import {
  useResendCooldown,
} from '../../hooks/useResendCooldown';

type ForgotStep = 'email' | 'reset';

function forgotErrorMessage(err: unknown): string {
  if (!(err instanceof ApiError)) return '無法寄送重設信';
  if (err.code === 28301000) {
    return '找不到此 Email 的帳號，請確認租戶與 Email 是否正確';
  }
  if (err.code === 28505000) {
    return '此帳號由第三方或企業目錄登入，無法在此重設密碼';
  }
  if (err.code === 29604000) {
    return `寄送過於頻繁，請稍候 ${OTP_RESEND_COOLDOWN_SECONDS} 秒後再試`;
  }
  if (err.status === 404) return '密碼重設服務未就緒，請重啟 Gateway 後再試';
  return err.message;
}

function cooldownLabel(secondsLeft: number, idle: string) {
  if (secondsLeft <= 0) return idle;
  return `${idle}（${secondsLeft}s）`;
}

export function ForgotPasswordPage() {
  const navigate = useNavigate();
  const { secondsLeft, canSend, startCooldown } = useResendCooldown();
  const [step, setStep] = useState<ForgotStep>('email');
  const [tenant, setTenant] = useState(
    () => localStorage.getItem('tenant_slug') ?? DEFAULT_TENANT,
  );
  const [email, setEmail] = useState('');
  const [challengeId, setChallengeId] = useState('');
  const [code, setCode] = useState('');
  const [newPassword, setNewPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [error, setError] = useState('');
  const [resendMsg, setResendMsg] = useState('');
  const [loading, setLoading] = useState(false);

  const dispatchCode = async () => {
    const data = await authApi.passwordForgot(tenant, email);
    setChallengeId(data.challenge_id);
    setStep('reset');
    startCooldown();
    setResendMsg('重設驗證碼已寄出');
  };

  const sendCode = async (e: FormEvent) => {
    e.preventDefault();
    if (!canSend) return;
    setError('');
    setResendMsg('');
    setLoading(true);
    try {
      localStorage.setItem('tenant_slug', tenant);
      await dispatchCode();
    } catch (err) {
      if (err instanceof ApiError && err.code === 29604000) {
        startCooldown();
      }
      setError(forgotErrorMessage(err));
    } finally {
      setLoading(false);
    }
  };

  const resend = async () => {
    if (!canSend) return;
    setResendMsg('');
    setError('');
    setLoading(true);
    try {
      await dispatchCode();
      setResendMsg('驗證碼已重新寄出');
    } catch (err) {
      if (err instanceof ApiError && err.code === 29604000) {
        startCooldown();
      }
      setResendMsg(forgotErrorMessage(err));
    } finally {
      setLoading(false);
    }
  };

  const submitReset = async (e: FormEvent) => {
    e.preventDefault();
    if (newPassword !== confirmPassword) {
      setError('兩次輸入的新密碼不一致');
      return;
    }
    setError('');
    setLoading(true);
    try {
      await authApi.passwordReset(tenant, challengeId, code, newPassword);
      navigate('/login', {
        replace: true,
        state: { message: '密碼已重設，請使用新密碼登入' },
      });
    } catch (err) {
      setError(err instanceof ApiError ? err.message : '重設失敗');
    } finally {
      setLoading(false);
    }
  };

  if (step === 'email') {
    return (
      <div className="auth-card">
        <h1>忘記密碼</h1>
        <p className="auth-hint">
          僅限平台註冊（Email + 密碼）的帳號。第三方或 LDAP 登入請向管理員洽詢。
        </p>
        <form onSubmit={sendCode} className="form">
          <label>
            租戶
            <input value={tenant} onChange={(e) => setTenant(e.target.value)} />
          </label>
          <label>
            Email
            <input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              required
            />
          </label>
          {error && <p className="form-error">{error}</p>}
          {resendMsg && <p className="form-ok">{resendMsg}</p>}
          <button
            type="submit"
            className="btn-primary"
            disabled={loading || !canSend}
          >
            {loading
              ? '寄送中…'
              : cooldownLabel(secondsLeft, '寄送重設驗證碼')}
          </button>
        </form>
        <p className="auth-footer">
          <Link to="/login">返回登入</Link>
        </p>
      </div>
    );
  }

  return (
    <div className="auth-card">
      <h1>重設密碼</h1>
      <p className="auth-hint">
        驗證碼已寄至 <strong>{email}</strong>（開發環境請至 MailHog :8025 查看）。
      </p>
      <form onSubmit={submitReset} className="form">
        <label>
          驗證碼
          <input
            value={code}
            onChange={(e) => setCode(e.target.value)}
            inputMode="numeric"
            autoComplete="one-time-code"
            required
            maxLength={6}
          />
        </label>
        <label>
          新密碼
          <input
            type="password"
            value={newPassword}
            onChange={(e) => setNewPassword(e.target.value)}
            autoComplete="new-password"
            required
            minLength={8}
          />
        </label>
        <label>
          確認新密碼
          <input
            type="password"
            value={confirmPassword}
            onChange={(e) => setConfirmPassword(e.target.value)}
            autoComplete="new-password"
            required
            minLength={8}
          />
        </label>
        {error && <p className="form-error">{error}</p>}
        {resendMsg && <p className="form-ok">{resendMsg}</p>}
        <button type="submit" className="btn-primary" disabled={loading}>
          {loading ? '重設中…' : '確認重設密碼'}
        </button>
        <button
          type="button"
          className="btn-link"
          onClick={resend}
          disabled={loading || !canSend}
        >
          {cooldownLabel(secondsLeft, '重新寄送驗證碼')}
        </button>
        <button
          type="button"
          className="btn-link"
          onClick={() => {
            setStep('email');
            setCode('');
            setNewPassword('');
            setConfirmPassword('');
            setError('');
            setResendMsg('');
          }}
          disabled={loading}
        >
          更換 Email
        </button>
      </form>
      <p className="auth-footer">
        <Link to="/login">返回登入</Link>
      </p>
    </div>
  );
}
