import { useEffect, useState } from 'react';
import { authApi } from '../../api/endpoints';
import { ApiRequestError } from '../../api/client';
import { Button } from '../../components/ui/Button';
import { IconShieldCheck } from '../../components/ui/icons';
import type { LoginResponse, OtpSetupResponse } from '../../api/types';

/**
 * 로그인 2단계 OTP 패널 — LoginPage 1단계 성공 후 표시.
 *  - mode="verify" : 이미 OTP 등록된 사용자 → 6자리 코드만 입력.
 *  - mode="enroll" : 필수 역할 미등록 → setup(QR·시크릿) 발급 후 6자리 확인·활성화.
 * challengeToken 은 짧은 수명(5분)·1회성 프리오스 토큰(정식 JWT 아님).
 */
interface Props {
  challengeToken: string;
  mode: 'verify' | 'enroll';
  onSuccess: (res: LoginResponse) => void;
  onCancel: () => void;
}

export function OtpChallengePanel({ challengeToken, mode, onSuccess, onCancel }: Props) {
  const [setup, setSetup] = useState<OtpSetupResponse | null>(null);
  const [code, setCode] = useState('');
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);
  const [loadingSetup, setLoadingSetup] = useState(mode === 'enroll');

  // 등록 강제 모드 — 진입 시 시크릿·QR 발급.
  useEffect(() => {
    if (mode !== 'enroll') return;
    let alive = true;
    (async () => {
      try {
        const res = await authApi.otpEnrollSetup(challengeToken);
        if (alive) setSetup(res);
      } catch (err) {
        if (alive) setError(messageOf(err));
      } finally {
        if (alive) setLoadingSetup(false);
      }
    })();
    return () => {
      alive = false;
    };
  }, [mode, challengeToken]);

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    if (code.length !== 6) return;
    setError(null);
    setBusy(true);
    try {
      const res =
        mode === 'enroll'
          ? await authApi.otpEnrollVerify(challengeToken, code)
          : await authApi.otpVerify(challengeToken, code);
      onSuccess(res);
    } catch (err) {
      setError(messageOf(err));
      setCode('');
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="kx-login__card">
      <div className="kx-otp__badge" aria-hidden="true">
        <IconShieldCheck size={28} />
      </div>
      <h2 className="kx-login__title">2차 인증</h2>
      <p className="kx-login__title-sub">
        {mode === 'enroll'
          ? '보안 정책에 따라 OTP(Authenticator) 등록이 필요합니다.'
          : 'Authenticator 앱에 표시된 6자리 코드를 입력하세요.'}
      </p>

      {mode === 'enroll' && (
        <div className="kx-otp__enroll">
          {loadingSetup && <p className="kx-login__title-sub">QR 발급 중…</p>}
          {setup && (
            <>
              <ol className="kx-otp__steps">
                <li>Google/Microsoft Authenticator 앱에서 아래 QR을 스캔하세요.</li>
                <li>스캔이 안 되면 수동 키를 직접 입력하세요.</li>
                <li>앱에 표시된 6자리 코드로 등록을 완료하세요.</li>
              </ol>
              <div className="kx-otp__qr">
                <img src={setup.qrImageDataUri} alt="OTP QR" width={180} height={180} />
              </div>
              <div className="kx-otp__secret">
                <span className="kx-otp__secret-label">수동 입력 키</span>
                <code>{setup.secret}</code>
              </div>
            </>
          )}
        </div>
      )}

      <form className="kx-login__form" onSubmit={submit}>
        <div className="kx-field">
          <label htmlFor="otp-code">인증 코드 (6자리)</label>
          <input
            id="otp-code"
            inputMode="numeric"
            autoComplete="one-time-code"
            maxLength={6}
            placeholder="000000"
            className="kx-otp__code-input"
            value={code}
            onChange={(e) => setCode(e.target.value.replace(/\D/g, '').slice(0, 6))}
            autoFocus
          />
        </div>

        {error && (
          <p className="kx-login__error" role="alert">
            {error}
          </p>
        )}

        <Button type="submit" block disabled={busy || code.length !== 6}>
          {busy ? '확인 중…' : mode === 'enroll' ? '등록 완료 · 로그인' : '인증 · 로그인'}
        </Button>
        <button type="button" className="kx-login__text-link kx-otp__cancel" onClick={onCancel}>
          ← 다시 로그인
        </button>
      </form>
    </div>
  );
}

function messageOf(err: unknown): string {
  if (err instanceof ApiRequestError) {
    if (err.code === 'OTP_INVALID') return '코드가 올바르지 않습니다. 다시 시도해 주세요.';
    if (err.code === 'OTP_REQUIRED') return '인증 세션이 만료되었습니다. 다시 로그인해 주세요.';
    return err.message;
  }
  return '인증 중 오류가 발생했습니다.';
}
