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, oauthRedirectUri } 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;
      mfa_challenge_id?: string;
      tenant?: string;
    } | null;
    if (state?.tenant) {
      setTenant(state.tenant);
      localStorage.setItem('tenant_slug', state.tenant);
    }
    if (state?.mfa_challenge_id) {
      setMfaChallengeId(state.mfa_challenge_id);
      setInfo(state.message ?? '請輸入驗證碼以完成登入');
      navigate(location.pathname, { replace: true, state: null });
      return;
    }
    if (state?.message) {
      setInfo(state.message);
      navigate(location.pathname, { replace: true, state: null });
    }
  }, [location.pathname, location.state, navigate]);

  const startFederated = async (provider: authApi.FederatedProvider) => {
    setError('');
    setLoading(true);
    try {
      localStorage.setItem('tenant_slug', tenant);
      const { oauth_url } = await authApi.loginSocialStart(
        tenant,
        provider,
        oauthRedirectUri('/auth/callback/login'),
      );
      authApi.startOAuthRedirect(oauth_url);
    } catch (err) {
      setError(err instanceof ApiError ? err.message : '無法啟動登入');
      setLoading(false);
    }
  };

  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 || result.mfa_challenge_id) {
        if (!result.mfa_challenge_id) {
          throw new Error('缺少 MFA challenge');
        }
        setMfaChallengeId(result.mfa_challenge_id);
        setTotpCode('');
        setInfo('');
        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 {
      const code = totpCode.replace(/\s/g, '');
      await authApi.loginMfaConfirm(tenant, mfaChallengeId, code);
      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">
          {email ? (
            <>
              帳號 <strong>{email}</strong> 已啟用 TOTP。
            </>
          ) : (
            <>此帳號已啟用 TOTP。</>
          )}
          請輸入驗證器 App 的 6 位數驗證碼，或一次性備援碼。
        </p>
        <form onSubmit={submitMfa} className="form">
          <label>
            驗證碼
            <input
              value={totpCode}
              onChange={(e) => setTotpCode(e.target.value)}
              inputMode="numeric"
              autoComplete="one-time-code"
              autoFocus
              required
              minLength={6}
              maxLength={32}
              placeholder="000000"
            />
          </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>
      <div className="auth-divider">
        <span>或</span>
      </div>
      <div className="auth-oauth">
        <button
          type="button"
          className="btn-oauth"
          disabled={loading}
          onClick={() => startFederated('google')}
        >
          使用 Google 登入
        </button>
        <button
          type="button"
          className="btn-oauth btn-oauth-secondary"
          disabled={loading}
          onClick={() => startFederated('ldap')}
        >
          使用 LDAP 登入
        </button>
      </div>
      <p className="auth-footer">
        還沒有帳號？ <Link to="/register">註冊</Link>
        {' · '}
        <Link to="/register/confirm">尚未完成驗證？</Link>
        {' · '}
        <Link to="/password/forgot">忘記密碼？</Link>
      </p>
    </div>
  );
}
