import React, { useState, useRef, useCallback, useEffect } from 'react';
import { verifyEmailOtp, sendEmailOtp } from '../core/checkout-api';
import type { EmailOtpStepProps } from '../core/types';

const OTP_LENGTH = 6;
const RESEND_COOLDOWN = 60; // seconds — email resend is slower than SMS

/** Mask email for display: y***@example.com */
function maskEmail(email: string): string {
  const [local, domain] = email.split('@');
  if (!domain || local.length <= 1) return email;
  return `${local[0]}***@${domain}`;
}

const EmailOtpStep: React.FC<EmailOtpStepProps> = ({
  email,
  codeReused = false,
  onVerified,
  onBack,
  functionBaseUrl,
  merchantId,
  sessionContext,
}) => {
  const [digits, setDigits] = useState<string[]>(Array(OTP_LENGTH).fill(''));
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [resendCountdown, setResendCountdown] = useState(RESEND_COOLDOWN);
  const [resendLoading, setResendLoading] = useState(false);
  const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
  const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);

  useEffect(() => {
    timerRef.current = setInterval(() => {
      setResendCountdown((c) => {
        if (c <= 1) { clearInterval(timerRef.current!); return 0; }
        return c - 1;
      });
    }, 1000);
    return () => { if (timerRef.current) clearInterval(timerRef.current); };
  }, []);

  const focusBox = (index: number) => inputRefs.current[index]?.focus();

  const handleDigitChange = useCallback((index: number, value: string) => {
    const char = value.replace(/\D/g, '').slice(-1);
    setError(null);
    setDigits((prev) => { const next = [...prev]; next[index] = char; return next; });
    if (char && index < OTP_LENGTH - 1) focusBox(index + 1);
  }, []);

  const handleKeyDown = useCallback((index: number, e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Backspace') {
      if (digits[index]) {
        setDigits((prev) => { const n = [...prev]; n[index] = ''; return n; });
      } else if (index > 0) {
        setDigits((prev) => { const n = [...prev]; n[index - 1] = ''; return n; });
        focusBox(index - 1);
      }
    } else if (e.key === 'ArrowLeft' && index > 0) {
      focusBox(index - 1);
    } else if (e.key === 'ArrowRight' && index < OTP_LENGTH - 1) {
      focusBox(index + 1);
    }
  }, [digits]);

  const handlePaste = useCallback((e: React.ClipboardEvent<HTMLInputElement>) => {
    e.preventDefault();
    const pasted = e.clipboardData.getData('text').replace(/\D/g, '').slice(0, OTP_LENGTH);
    if (!pasted) return;
    const next = Array(OTP_LENGTH).fill('');
    pasted.split('').forEach((ch, i) => { next[i] = ch; });
    setDigits(next);
    setError(null);
    focusBox(Math.min(pasted.length, OTP_LENGTH - 1));
  }, []);

  const code = digits.join('');
  const isComplete = code.length === OTP_LENGTH && !digits.includes('');

  const handleVerify = useCallback(async () => {
    if (!isComplete) return;
    setLoading(true);
    setError(null);
    try {
      const result = await verifyEmailOtp({ functionBaseUrl, merchantId }, email, code, sessionContext);
      onVerified(result.session_token, result.buyer_id, result.session_id);
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : 'Verification failed. Please try again.');
      setDigits(Array(OTP_LENGTH).fill(''));
      focusBox(0);
    } finally {
      setLoading(false);
    }
  }, [isComplete, code, email, functionBaseUrl, merchantId, onVerified, sessionContext]);

  useEffect(() => {
    if (isComplete && !loading) handleVerify();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isComplete]);

  const handleResend = useCallback(async () => {
    if (resendCountdown > 0 || resendLoading) return;
    setResendLoading(true);
    setError(null);
    setDigits(Array(OTP_LENGTH).fill(''));
    try {
      await sendEmailOtp({ functionBaseUrl, merchantId }, email);
      setResendCountdown(RESEND_COOLDOWN);
      timerRef.current = setInterval(() => {
        setResendCountdown((c) => {
          if (c <= 1) { clearInterval(timerRef.current!); return 0; }
          return c - 1;
        });
      }, 1000);
      focusBox(0);
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : 'Failed to resend code.');
    } finally {
      setResendLoading(false);
    }
  }, [resendCountdown, resendLoading, functionBaseUrl, merchantId, email]);

  return (
    <div className="qr-auth-step">
      <button type="button" className="qr-back-btn qr-back-btn--auth" onClick={onBack} disabled={loading}>
        <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
          <path d="M19 12H5M12 5l-7 7 7 7" />
        </svg>
      </button>

      {/* Icon */}
      <div className="qr-auth-step__icon" aria-hidden="true">
        <svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
          <circle cx="24" cy="24" r="24" fill="var(--qr-primary-light)" />
          <rect x="11" y="15" width="26" height="18" rx="3" stroke="var(--qr-primary)" strokeWidth="1.8" fill="none" />
          <path d="M11 18l13 9 13-9" stroke="var(--qr-primary)" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </div>

      <h3 className="qr-auth-step__title">Check your email</h3>
      <p className="qr-auth-step__sub">
        {codeReused
          ? <>Use the code we sent earlier — it&apos;s still valid for your next checkout.</>
          : <>6-digit code sent to <strong>{maskEmail(email)}</strong></>}
      </p>

      <div className="qr-otp-boxes" role="group" aria-label="Enter verification code">
        {digits.map((d, i) => (
          <input
            key={i}
            ref={(el) => { inputRefs.current[i] = el; }}
            type="text"
            inputMode="numeric"
            maxLength={1}
            className={`qr-otp-box${d ? ' qr-otp-box--filled' : ''}${error ? ' qr-otp-box--error' : ''}`}
            value={d}
            onChange={(e) => handleDigitChange(i, e.target.value)}
            onKeyDown={(e) => handleKeyDown(i, e)}
            onPaste={handlePaste}
            onFocus={(e) => e.target.select()}
            aria-label={`Code digit ${i + 1}`}
            disabled={loading}
            autoComplete={i === 0 ? 'one-time-code' : 'off'}
          />
        ))}
      </div>

      {error && (
        <p className="qr-auth-step__error" role="alert">{error}</p>
      )}

      <button
        type="button"
        className="qr-btn qr-btn--primary qr-btn--full"
        onClick={handleVerify}
        disabled={!isComplete || loading}
      >
        {loading ? (
          <span className="qr-spinner qr-spinner--sm" aria-hidden="true" />
        ) : 'Verify Code'}
      </button>

      <p className="qr-auth-step__resend">
        {resendCountdown > 0 ? (
          <span>Resend code in {resendCountdown}s</span>
        ) : (
          <button
            type="button"
            className="qr-link-btn"
            onClick={handleResend}
            disabled={resendLoading}
          >
            {resendLoading ? 'Sending…' : 'Resend Code'}
          </button>
        )}
      </p>
    </div>
  );
};

export default EmailOtpStep;
