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 } from '../../config';
import { useAuth } from '../../context/AuthContext';
import * as permApi from '../../api/permission';

export function LoginPage() {
  const navigate = useNavigate();
  const location = useLocation();
  const { syncSession, refreshRoles } = useAuth();
  const [tenant, setTenant] = useState(
    () => localStorage.getItem('tenant_slug') ?? DEFAULT_TENANT,
  );
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [mfaChallengeId, setMfaChallengeId] = useState<string | null>(null);
  const [totpCode, setTotpCode] = useState('');
  const [error, setError] = useState('');
  const [info, setInfo] = useState('');
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const state = location.state as { message?: string } | null;
    if (state?.message) {
      setInfo(state.message);
      navigate(location.pathname, { replace: true, state: null });
    }
  }, [location.pathname, location.state, navigate]);

  const finishLogin = async () => {
    syncSession();
    await refreshRoles();
    const me = await permApi.getMyPermissions();
    const admin = permApi.isAdminRole(me.roles ?? []);
    navigate(admin ? '/admin' : '/app');
  };

  const submit = async (e: FormEvent) => {
    e.preventDefault();
    setError('');
    setLoading(true);
    try {
      localStorage.setItem('tenant_slug', tenant);
      const result = await authApi.login(tenant, email, password);
      if (result.mfa_required) {
        if (!result.mfa_challenge_id) {
          throw new Error('缺少 MFA challenge');
        }
        setMfaChallengeId(result.mfa_challenge_id);
        return;
      }
      await finishLogin();
    } catch (err) {
      if (err instanceof ApiError && err.code === 28505000) {
        setError('帳號尚未完成 Email 驗證，請先完成註冊驗證。');
      } else {
        setError(err instanceof ApiError ? err.message : '登入失敗');
      }
    } finally {
      setLoading(false);
    }
  };

  const submitMfa = async (e: FormEvent) => {
    e.preventDefault();
    if (!mfaChallengeId) return;
    setError('');
    setLoading(true);
    try {
      await authApi.loginMfaConfirm(tenant, mfaChallengeId, totpCode);
      await finishLogin();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : '驗證碼錯誤');
    } finally {
      setLoading(false);
    }
  };

  const backToPassword = () => {
    setMfaChallengeId(null);
    setTotpCode('');
    setError('');
  };

  if (mfaChallengeId) {
    return (
      <div className="auth-card">
        <h1>雙因素驗證</h1>
        <p className="auth-hint">請輸入驗證器 App 的 6 位數驗證碼，或備援碼。</p>
        <form onSubmit={submitMfa} className="form">
          <label>
            驗證碼
            <input
              value={totpCode}
              onChange={(e) => setTotpCode(e.target.value)}
              inputMode="numeric"
              autoComplete="one-time-code"
              required
              maxLength={6}
            />
          </label>
          {error && <p className="form-error">{error}</p>}
          <button type="submit" className="btn-primary" disabled={loading}>
            {loading ? '驗證中…' : '確認登入'}
          </button>
          <button
            type="button"
            className="btn-link"
            onClick={backToPassword}
            disabled={loading}
          >
            返回重新輸入密碼
          </button>
        </form>
      </div>
    );
  }

  return (
    <div className="auth-card">
      <h1>登入</h1>
      <form onSubmit={submit} 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>
        <label>
          密碼
          <input
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
        </label>
        {error && <p className="form-error">{error}</p>}
        {info && <p className="form-ok">{info}</p>}
        <button type="submit" className="btn-primary" disabled={loading}>
          {loading ? '登入中…' : '登入'}
        </button>
      </form>
      <p className="auth-footer">
        還沒有帳號？ <Link to="/register">註冊</Link>
        {' · '}
        <Link to="/register/confirm">尚未完成驗證？</Link>
        {' · '}
        <Link to="/password/forgot">忘記密碼？</Link>
      </p>
    </div>
  );
}
