"use client";

import {
  useRef,
  useEffect,
  useState,
  KeyboardEvent,
  ClipboardEvent,
} from "react";

interface OTPInputProps {
  length?: number;
  value: string;
  onChange: (value: string) => void;
  onComplete?: (value: string) => void;
  disabled?: boolean;
  error?: boolean;
  autoFocus?: boolean;
  dir?: "ltr" | "rtl";
}

export default function OTPInput({
  length = 6,
  value,
  onChange,
  onComplete,
  disabled = false,
  error = false,
  autoFocus = true,
  dir = "ltr",
}: OTPInputProps) {
  const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
  const [activeIndex, setActiveIndex] = useState(0);

  useEffect(() => {
    inputRefs.current = inputRefs.current.slice(0, length);
  }, [length]);

  useEffect(() => {
    if (autoFocus && !disabled && inputRefs.current[0]) {
      inputRefs.current[0].focus();
    }
  }, [autoFocus, disabled]);

  useEffect(() => {
    if (value.length === length && onComplete) {
      onComplete(value);
    }
  }, [value, length, onComplete]);

  const focusInput = (index: number) => {
    const targetIndex = Math.max(0, Math.min(index, length - 1));
    if (inputRefs.current[targetIndex]) {
      inputRefs.current[targetIndex]?.focus();
      setActiveIndex(targetIndex);
    }
  };

  const handleChange = (index: number, inputValue: string) => {
    if (disabled) return;

    // Only allow numbers
    const sanitized = inputValue.replace(/[^0-9]/g, "");

    if (sanitized.length === 0) {
      // Handle deletion
      const newValue = value.substring(0, index) + value.substring(index + 1);
      onChange(newValue);
      return;
    }

    if (sanitized.length === 1) {
      // Single digit input
      const newValue =
        value.substring(0, index) + sanitized + value.substring(index + 1);
      onChange(newValue);

      // Move to next input
      if (index < length - 1) {
        focusInput(index + 1);
      }
    } else if (sanitized.length > 1) {
      // Multiple digits (paste or fast typing)
      handlePaste(index, sanitized);
    }
  };

  const handleKeyDown = (index: number, e: KeyboardEvent<HTMLInputElement>) => {
    if (disabled) return;

    if (e.key === "Backspace") {
      e.preventDefault();

      if (value[index]) {
        // Clear current digit
        const newValue = value.substring(0, index) + value.substring(index + 1);
        onChange(newValue);
      } else if (index > 0) {
        // Move to previous input and clear it
        focusInput(index - 1);
        const newValue = value.substring(0, index - 1) + value.substring(index);
        onChange(newValue);
      }
    } else if (e.key === "Delete") {
      e.preventDefault();

      if (value[index]) {
        // Clear current digit
        const newValue = value.substring(0, index) + value.substring(index + 1);
        onChange(newValue);
      }
    } else if (e.key === "ArrowLeft") {
      e.preventDefault();
      const prevIndex = dir === "rtl" ? index + 1 : index - 1;
      if (prevIndex >= 0 && prevIndex < length) {
        focusInput(prevIndex);
      }
    } else if (e.key === "ArrowRight") {
      e.preventDefault();
      const nextIndex = dir === "rtl" ? index - 1 : index + 1;
      if (nextIndex >= 0 && nextIndex < length) {
        focusInput(nextIndex);
      }
    } else if (e.key === "Home") {
      e.preventDefault();
      focusInput(0);
    } else if (e.key === "End") {
      e.preventDefault();
      focusInput(length - 1);
    } else if (/^[0-9]$/.test(e.key)) {
      // Allow number keys
      e.preventDefault();
      handleChange(index, e.key);
    }
  };

  const handlePaste = (startIndex: number, pastedData: string) => {
    if (disabled) return;

    const sanitized = pastedData.replace(/[^0-9]/g, "").slice(0, length);

    if (sanitized.length === 0) return;

    // Fill from current position
    let newValue = value;
    for (let i = 0; i < sanitized.length && startIndex + i < length; i++) {
      newValue =
        newValue.substring(0, startIndex + i) +
        sanitized[i] +
        newValue.substring(startIndex + i + 1);
    }

    onChange(newValue);

    // Focus the next empty input or last input
    const nextEmptyIndex =
      newValue.length < length ? newValue.length : length - 1;
    focusInput(nextEmptyIndex);
  };

  const handlePasteEvent = (
    index: number,
    e: ClipboardEvent<HTMLInputElement>,
  ) => {
    e.preventDefault();
    const pastedData = e.clipboardData.getData("text");
    handlePaste(index, pastedData);
  };

  const handleFocus = (index: number) => {
    setActiveIndex(index);
    // Select the content for easy replacement
    inputRefs.current[index]?.select();
  };

  const renderInputs = () => {
    const inputs = [];
    for (let i = 0; i < length; i++) {
      inputs.push(
        <input
          key={i}
          ref={(el) => (inputRefs.current[i] = el)}
          type="text"
          inputMode="numeric"
          pattern="[0-9]*"
          maxLength={1}
          value={value[i] || ""}
          onChange={(e) => handleChange(i, e.target.value)}
          onKeyDown={(e) => handleKeyDown(i, e)}
          onPaste={(e) => handlePasteEvent(i, e)}
          onFocus={() => handleFocus(i)}
          disabled={disabled}
          className={`
            w-12 h-14 text-center text-2xl font-semibold
            border-2 rounded-lg
            transition-all duration-200
            focus:outline-none focus:ring-2 focus:ring-offset-2
            disabled:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50
            ${
              error
                ? "border-red-500 focus:border-red-500 focus:ring-red-500 text-red-900"
                : activeIndex === i
                  ? "border-brand-green focus:border-brand-green focus:ring-brand-green"
                  : value[i]
                    ? "border-brand-ink/30 text-brand-ink"
                    : "border-gray-300 text-gray-900"
            }
            dark:bg-gray-800 dark:border-gray-600 dark:text-white
            dark:disabled:bg-gray-700 dark:disabled:text-gray-500
            ${dir === "rtl" ? "font-arabic" : ""}
          `}
          aria-label={`Digit ${i + 1}`}
          autoComplete="off"
          autoCorrect="off"
          autoCapitalize="off"
          spellCheck="false"
        />,
      );
    }
    return inputs;
  };

  return (
    <div className="flex gap-2 justify-center" dir={dir}>
      {renderInputs()}
    </div>
  );
}

// Separate component for OTP with resend functionality
interface OTPWithResendProps extends OTPInputProps {
  onResend: () => void | Promise<void>;
  resendDelay?: number;
  resendText?: string;
  resendingText?: string;
  lang?: "en" | "ar";
}

export function OTPWithResend({
  onResend,
  resendDelay = 60,
  resendText = "Resend code",
  resendingText = "Sending...",
  lang = "en",
  ...otpProps
}: OTPWithResendProps) {
  const [countdown, setCountdown] = useState(resendDelay);
  const [isResending, setIsResending] = useState(false);

  useEffect(() => {
    if (countdown > 0) {
      const timer = setTimeout(() => setCountdown(countdown - 1), 1000);
      return () => clearTimeout(timer);
    }
  }, [countdown]);

  const handleResend = async () => {
    if (countdown > 0 || isResending) return;

    setIsResending(true);
    try {
      await onResend();
      setCountdown(resendDelay);
    } catch (error) {
      console.error("Failed to resend OTP:", error);
    } finally {
      setIsResending(false);
    }
  };

  return (
    <div className="space-y-4">
      <OTPInput {...otpProps} />

      <div className="flex justify-center">
        {countdown > 0 ? (
          <p className="text-sm text-gray-600 dark:text-gray-400">
            {lang === "ar"
              ? `يمكنك إعادة الإرسال خلال ${countdown} ثانية`
              : `Resend in ${countdown}s`}
          </p>
        ) : (
          <button
            type="button"
            onClick={handleResend}
            disabled={isResending}
            className="
              text-sm font-medium text-brand-green hover:text-brand-green/80
              disabled:text-gray-400 disabled:cursor-not-allowed
              transition-colors duration-200
            "
          >
            {isResending ? resendingText : resendText}
          </button>
        )}
      </div>
    </div>
  );
}
