import React, {
  useRef,
  useEffect,
  type SetStateAction,
  type Dispatch,
  useState,
  type KeyboardEvent,
} from 'react';
import { TextField, Stack } from '@mui/material';
import { useTranslation } from 'react-i18next';
import { replacePersianWithRealNumbers } from '@/utils/replacePersianWithRealNumbers';

interface DigitInputProps {
  error: boolean;
  success: boolean;
  onChange: Dispatch<SetStateAction<string>>;
}

const DigitInput: React.FC<DigitInputProps> = ({
  onChange,
  error,
  success,
}) => {
  const [code, setCode] = useState<string[]>(['', '', '', '']);
  const { i18n } = useTranslation();
  const inputRefs = useRef<Array<HTMLInputElement | null>>([]);

  const isMobile =
    typeof navigator !== 'undefined' &&
    /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent);

  useEffect(() => {
    inputRefs.current[0]?.focus();
  }, []);

  const handleDigitInputValueChange = (value: string[]) => {
    const formatted = value.filter((char) => char !== '').join('');
    onChange(formatted);
  };

  const handleChange = (value: string, index: number) => {
    value = replacePersianWithRealNumbers(value);

    if (!/^\d$/.test(value) && value !== '') return;

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

    if (value && index < newCode.length - 1) {
      inputRefs.current[index + 1]?.focus();
    }
  };

  const handleBackspace = (
    event: KeyboardEvent<HTMLDivElement>,
    index: number,
  ) => {
    if (event.key === 'Backspace') {
      event.preventDefault();

      if (code[index]) {
        // We clear the current value.
        handleChange('', index);
      } else if (index > 0) {
        // We move focus to the previous input and SELECT its content.
        const prevInput = inputRefs.current[index - 1];
        if (prevInput) {
          prevInput.focus();
          prevInput.select();
        }
      }
    }
  };

  const handlePaste = (event: React.ClipboardEvent) => {
    event.preventDefault();
    const pastedData = event.clipboardData.getData('text').replace(/\D/g, '');
    const newCode = [...code];

    pastedData.split('').forEach((digit, i) => {
      if (i < newCode.length) newCode[i] = digit;
    });

    setCode(newCode);
    handleDigitInputValueChange(newCode);

    const nextEmpty = newCode.findIndex((d) => d === '');
    const focusIndex = nextEmpty === -1 ? newCode.length - 1 : nextEmpty;
    inputRefs.current[focusIndex]?.focus();
  };

  return (
    <Stack
      direction={i18n.dir() === 'ltr' ? 'row' : 'row-reverse'}
      alignItems="center"
      sx={{ gap: 2, width: '100%', my: 4 }}
      justifyContent="center"
    >
      {code.map((digit, index) => (
        <TextField
          error={error}
          color={success ? 'success' : 'primary'}
          key={index}
          inputRef={(el) => (inputRefs.current[index] = el)}
          autoFocus={index === 0}
          value={digit}
          onChange={(e) => handleChange(e.target.value, index)}
          onKeyDown={(e) => handleBackspace(e, index)}
          onPaste={handlePaste}
          type={isMobile ? 'tel' : 'text'}
          slotProps={{
            htmlInput: {
              maxLength: 1,
              inputMode: isMobile ? 'numeric' : undefined,
              pattern: isMobile ? '[0-9]*' : undefined,
              autoComplete: 'one-time-code',
              name: 'one-time-code',
              enterKeyHint: 'done',
              dir: 'ltr',
              sx: {
                height: '72px',
                color: error
                  ? 'error.main'
                  : success
                    ? 'success.main'
                    : 'text.primary',
              },
              style: {
                textAlign: 'center',
                fontSize: '48px',
              },
            },
          }}
          variant="standard"
          size="medium"
          sx={{
            width: { md: '83px', xs: '20%' },
          }}
        />
      ))}
    </Stack>
  );
};

export default DigitInput;
