'use client';

import { useState, useEffect, useRef, Suspense } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { signIn } from 'next-auth/react';
import Link from 'next/link';
import { twoFactorService } from '@/services';

function VerifyTwoFactorContent() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [code, setCode] = useState(['', '', '', '', '', '']);
  const [backupCode, setBackupCode] = useState('');
  const [useBackup, setUseBackup] = useState(false);
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);
  const inputRefs = useRef<(HTMLInputElement | null)[]>([]);

  // Get tempToken and email from URL params
  const tempToken = searchParams.get('token') || '';
  const userEmail = searchParams.get('email') || '';

  useEffect(() => {
    // If no token, redirect to login
    if (!tempToken) {
      router.push('/login');
    }
  }, [tempToken, router]);

  const handleCodeChange = (index: number, value: string) => {
    // Only allow single digit
    if (value.length > 1) {
      value = value.slice(-1);
    }

    // Only allow numbers
    if (value && !/^\d$/.test(value)) {
      return;
    }

    const newCode = [...code];
    newCode[index] = value;
    setCode(newCode);

    // Auto-focus next input
    if (value && index < 5) {
      inputRefs.current[index + 1]?.focus();
    }

    // Auto-submit when all digits are entered
    if (value && index === 5 && newCode.every((digit) => digit !== '')) {
      handleSubmit(newCode.join(''));
    }
  };

  const handleKeyDown = (index: number, e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Backspace' && !code[index] && index > 0) {
      inputRefs.current[index - 1]?.focus();
    }
  };

  const handlePaste = (e: React.ClipboardEvent) => {
    e.preventDefault();
    const pastedData = e.clipboardData.getData('text').replace(/\D/g, '').slice(0, 6);
    if (pastedData.length === 6) {
      const newCode = pastedData.split('');
      setCode(newCode);
      inputRefs.current[5]?.focus();
      // Auto-submit after paste
      setTimeout(() => handleSubmit(pastedData), 100);
    }
  };

  const handleSubmit = async (codeValue?: string) => {
    const verificationCode = codeValue || code.join('');

    if (!useBackup && verificationCode.length !== 6) {
      setError('Please enter a 6-digit code');
      return;
    }

    if (useBackup && !backupCode.trim()) {
      setError('Please enter a backup code');
      return;
    }

    setLoading(true);
    setError('');

    try {
      let response;

      if (useBackup) {
        response = await twoFactorService.verifyBackupCode({
          tempToken,
          backupCode: backupCode.trim(),
        });
      } else {
        response = await twoFactorService.verifyLogin({
          tempToken,
          token: verificationCode,
        });
      }

      // Save tokens to localStorage BEFORE signIn to prevent race condition
      localStorage.setItem('accessToken', response.data.accessToken);
      localStorage.setItem('refreshToken', response.data.refreshToken);

      // Now sign in with NextAuth using the tokens we received
      const result = await signIn('credentials', {
        email: userEmail,
        accessToken: response.data.accessToken,
        refreshToken: response.data.refreshToken,
        redirect: false,
      });

      if (result?.error) {
        localStorage.removeItem('accessToken');
        localStorage.removeItem('refreshToken');
        setError('Failed to complete login. Please try again.');
        setLoading(false);
      } else {
        router.push('/');
        router.refresh();
      }
    } catch (err) {
      setLoading(false);
      if (err instanceof Error) {
        setError(err.message);
      } else {
        setError('Invalid code. Please try again.');
      }
      // Clear code on error
      if (!useBackup) {
        setCode(['', '', '', '', '', '']);
        inputRefs.current[0]?.focus();
      }
    }
  };

  const handleFormSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    handleSubmit();
  };

  if (!tempToken) {
    return null; // Will redirect in useEffect
  }

  return (
    <>
      {/* Heading */}
      <div className="text-center mb-6">
        <div className="w-16 h-16 mx-auto mb-4 bg-[#f0f5fc] rounded-full flex items-center justify-center">
          <svg
            className="w-8 h-8 text-[#e58625]"
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
            />
          </svg>
        </div>
        <h2 className="text-[30px] font-normal text-[#00293d] mb-3">Two-Factor Authentication</h2>
        <p className="text-sm text-[#00293d] px-4 leading-relaxed">
          {useBackup
            ? 'Enter one of your backup codes to continue'
            : 'Enter the 6-digit code from your authenticator app'}
        </p>
      </div>

      {/* Form */}
      <form onSubmit={handleFormSubmit} className="space-y-5">
        {error && (
          <div className="bg-red-50 border border-red-200 text-red-600 px-4 py-3 rounded-[20px] text-sm">
            {error}
          </div>
        )}

        {!useBackup ? (
          /* 6-digit code input */
          <div className="flex justify-center gap-3" onPaste={handlePaste}>
            {code.map((digit, index) => (
              <input
                key={index}
                ref={(el) => {
                  inputRefs.current[index] = el;
                }}
                type="text"
                inputMode="numeric"
                maxLength={1}
                value={digit}
                onChange={(e) => handleCodeChange(index, e.target.value)}
                onKeyDown={(e) => handleKeyDown(index, e)}
                className="w-12 h-14 text-center text-xl font-bold bg-[#f0f5fc] rounded-[15px] text-[#00293d] focus:outline-none focus:ring-2 focus:ring-[#e58625] transition-all"
                disabled={loading}
              />
            ))}
          </div>
        ) : (
          /* Backup code input */
          <div>
            <input
              type="text"
              placeholder="Enter backup code"
              value={backupCode}
              onChange={(e) => setBackupCode(e.target.value.toUpperCase())}
              className="w-full px-6 py-6 bg-[#f0f5fc] rounded-[20px] text-[#00293d] text-sm font-light placeholder:text-[#00293d] focus:outline-none focus:ring-2 focus:ring-[#00293d]/20 transition-all text-center tracking-widest"
              disabled={loading}
            />
          </div>
        )}

        {/* Switch between code and backup */}
        <div className="text-center">
          <button
            type="button"
            onClick={() => {
              setUseBackup(!useBackup);
              setError('');
              setCode(['', '', '', '', '', '']);
              setBackupCode('');
            }}
            className="text-[#00293d] text-sm font-light hover:underline"
          >
            {useBackup ? 'Use authenticator code instead' : 'Use a backup code'}
          </button>
        </div>

        {/* Verify Button */}
        <button
          type="submit"
          disabled={loading}
          className="w-full py-6 bg-[#e58625] hover:bg-[#d47a1f] text-[#00293d] font-bold text-sm rounded-[20px] transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
        >
          {loading ? 'Verifying...' : 'Verify'}
        </button>
      </form>

      {/* Back to Login */}
      <div className="text-center mt-8">
        <Link href="/login" className="text-[#00293d] text-sm font-light hover:underline">
          ← Back to Login
        </Link>
      </div>

      {/* Help text */}
      <div className="mt-6 p-4 bg-[#f0f5fc] rounded-[15px]">
        <p className="text-xs text-[#00293d]/70 text-center">
          {useBackup ? (
            <>
              Backup codes are single-use. After using one, it will be invalidated. If you&apos;ve
              used all your backup codes, you&apos;ll need to generate new ones from your account
              settings.
            </>
          ) : (
            <>
              Open your authenticator app (Google Authenticator, Authy, etc.) and enter the 6-digit
              code shown for Re-Quest.
            </>
          )}
        </p>
      </div>
    </>
  );
}

// Loading component for Suspense fallback
function VerifyTwoFactorLoading() {
  return (
    <div className="text-center">
      <div className="w-16 h-16 mx-auto mb-4 bg-[#f0f5fc] rounded-full flex items-center justify-center animate-pulse">
        <svg
          className="w-8 h-8 text-[#e58625]"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
          />
        </svg>
      </div>
      <h2 className="text-[30px] font-normal text-[#00293d] mb-3">Loading...</h2>
    </div>
  );
}

// Page component wrapped in Suspense for useSearchParams
export default function VerifyTwoFactorPage() {
  return (
    <Suspense fallback={<VerifyTwoFactorLoading />}>
      <VerifyTwoFactorContent />
    </Suspense>
  );
}
