import { useEffect, useState, type FormEvent } from 'react';
import { Link, useLocation, 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 { useAuth } from '../../context/AuthContext';
import {
  RESEND_COOLDOWN_SECONDS,
  useResendCooldown,
} from '../../hooks/useResendCooldown';

type ConfirmStep = 'email' | 'otp';

type ConfirmNavState = {
  tenant: string;
  email: string;
  challenge_id: string;
};

function resumeErrorMessage(err: unknown): string {
  if (!(err instanceof ApiError)) return '無法寄送驗證碼';
  if (err.code === 29301000) {
    return '找不到此 Email 的待驗證帳號，請確認租戶與 Email 是否正確';
  }
  if (err.code === 28309000) 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 ConfirmPage() {
  const navigate = useNavigate();
  const location = useLocation();
  const { syncSession, refreshRoles } = useAuth();
  const { secondsLeft, canSend, startCooldown } = useResendCooldown();
  const [step, setStep] = useState<ConfirmStep>('email');
  const [tenant, setTenant] = useState(
    () => localStorage.getItem('tenant_slug') ?? DEFAULT_TENANT,
  );
  const [challengeId, setChallengeId] = useState('');
  const [email, setEmail] = useState('');
  const [code, setCode] = useState('');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);
  const [resendMsg, setResendMsg] = useState('');

  useEffect(() => {
    const state = location.state as ConfirmNavState | null;
    if (!state?.challenge_id || !state.email) return;
    setTenant(state.tenant);
    setEmail(state.email);
    setChallengeId(state.challenge_id);
    setStep('otp');
    startCooldown();
  }, [location.state, startCooldown]);

  const dispatchCode = async () => {
    const data = await authApi.registerResume(tenant, email);
    setChallengeId(data.challenge_id);
    setStep('otp');
    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(resumeErrorMessage(err));
    } finally {
      setLoading(false);
    }
  };

  const submit = async (e: FormEvent) => {
    e.preventDefault();
    setError('');
    setLoading(true);
    try {
      await authApi.registerConfirm(tenant, challengeId, code);
      syncSession();
      await refreshRoles();
      navigate('/app', { replace: true });
    } catch (err) {
      setError(err instanceof ApiError ? err.message : '驗證失敗');
    } 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(resumeErrorMessage(err));
    } finally {
      setLoading(false);
    }
  };

  const sendDisabled = loading || !canSend;

  if (step === 'email') {
    return (
      <div className="auth-card">
        <h1>完成 Email 驗證</h1>
        <p className="hint">
          輸入註冊 Email，若有待驗證帳號將寄送驗證碼（{RESEND_COOLDOWN_SECONDS}{' '}
          秒內不可重複寄送）。
        </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>}
          <button type="submit" className="btn-primary" disabled={sendDisabled}>
            {loading
              ? '寄送中…'
              : cooldownLabel(secondsLeft, '寄送驗證碼')}
          </button>
        </form>
        <p className="auth-footer">
          還沒註冊？ <Link to="/register">前往註冊</Link>
          {' · '}
          <Link to="/login">登入</Link>
        </p>
      </div>
    );
  }

  return (
    <div className="auth-card">
      <h1>Email 驗證</h1>
      <p className="hint">
        驗證碼已寄至 <strong>{email}</strong>（開發環境請到 MailHog 查看）
      </p>
      <form onSubmit={submit} className="form">
        <label>
          6 位數驗證碼
          <input
            value={code}
            onChange={(e) => setCode(e.target.value)}
            maxLength={6}
            pattern="\d{6}"
            required
          />
        </label>
        {error && <p className="form-error">{error}</p>}
        <button type="submit" className="btn-primary" disabled={loading}>
          {loading ? '驗證中…' : '完成註冊'}
        </button>
      </form>
      <button
        type="button"
        className="btn-link"
        onClick={resend}
        disabled={sendDisabled}
      >
        {cooldownLabel(secondsLeft, '重送驗證碼')}
      </button>
      {resendMsg && <p className="hint">{resendMsg}</p>}
      <p className="auth-footer">
        <button
          type="button"
          className="btn-link"
          onClick={() => {
            setStep('email');
            setCode('');
            setError('');
            setResendMsg('');
          }}
        >
          換一個 Email
        </button>
        {' · '}
        <Link to="/login">返回登入</Link>
      </p>
    </div>
  );
}
