import { ReloadOutlined } from "@ant-design/icons";
import { Button, Col, Input, message, Row } from "antd";
import {
  ChangeEvent,
  ClipboardEvent,
  KeyboardEvent,
  useEffect,
  useRef,
  useState,
} from "react";
import { useTranslation } from "react-i18next";
import { colors } from "ThemeConstants";
import ProText from "../ProText";

const OtpInput = ({
  length = 6,
  onComplete,
  resendOtp,
  isLoading = false,
  resendCountdown = 120, // 2 minutes in seconds
}: {
  length?: number;
  onComplete: (otp: string) => void;
  resendOtp: () => void;
  isLoading?: boolean;
  resendCountdown?: number; // Cooldown time in seconds
}) => {
  const [otp, setOtp] = useState(Array(length).fill(""));
  const [countdown, setCountdown] = useState(resendCountdown);
  const [canResend, setCanResend] = useState(false);
  const inputRefs = useRef<HTMLInputElement[]>([]);
  const { t } = useTranslation();

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

    // Start the countdown timer
    const timer = setInterval(() => {
      setCountdown((prev) => {
        if (prev <= 1) {
          clearInterval(timer);
          setCanResend(true);
          return 0;
        }
        return prev - 1;
      });
    }, 1000);

    return () => clearInterval(timer);
  }, []);

  useEffect(() => {
    // Reset countdown when resendOtp is called
    if (countdown === 0) {
      setCanResend(true);
    }
  }, [countdown]);

  const handleChange = (index: number, e: ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;

    if (isNaN(Number(value))) return; // Only allow numbers

    const newOtp = [...otp];
    newOtp[index] = value.substring(value.length - 1); // Only take the last character
    setOtp(newOtp);

    // Move to next input if current input is filled
    if (value && index < length - 1) {
      inputRefs.current[index + 1].focus();
    }

    onComplete(newOtp.join(""));
  };

  const handleKeyDown = (index: number, e: KeyboardEvent<HTMLInputElement>) => {
    // Move to previous input on backspace if current input is empty
    if (e.key === "Backspace" && !otp[index] && index > 0) {
      inputRefs.current[index - 1].focus();
    }
  };

  const handlePaste = (e: ClipboardEvent) => {
    e.preventDefault();
    const pastedData = e?.clipboardData?.getData("text/plain").slice(0, length);

    if (!pastedData?.length) return;

    // Check if all characters are numbers
    const pastedChars = pastedData.split("");
    if (pastedChars.some((char) => isNaN(Number(char)))) return;

    const newOtp = [...otp];
    for (let i = 0; i < pastedData.length; i++) {
      if (i < length) {
        newOtp[i] = pastedData[i];
      }
    }
    setOtp(newOtp);

    // Focus on the next empty input or the last one
    const nextIndex = Math.min(pastedData.length, length - 1);
    inputRefs.current[nextIndex].focus();

    if (newOtp.every((digit) => digit !== "")) {
      onComplete(newOtp.join(""));
    }
  };

  const handleResend = () => {
    if (!canResend) return;

    setOtp(Array(length).fill(""));
    inputRefs.current[0].focus();
    resendOtp();
    message.success("New OTP sent successfully!");

    // Reset the countdown timer
    setCanResend(false);
    setCountdown(resendCountdown);

    // Start the countdown timer again
    const timer = setInterval(() => {
      setCountdown((prev) => {
        if (prev <= 1) {
          clearInterval(timer);
          setCanResend(true);
          return 0;
        }
        return prev - 1;
      });
    }, 1000);
  };

  // Format the time as mm:ss
  const formatTime = (seconds: number) => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins.toString().padStart(2, "0")}:${secs
      .toString()
      .padStart(2, "0")}`;
  };

  return (
    <div style={{ padding: "20px 0" }}>
      <Row
        gutter={8}
        style={{
          display: "grid",
          gridTemplateColumns: "repeat(7, 1fr)",
          gap: 16,
        }}
      >
        <div />
        {Array.from({ length }, (_, index) => (
          <Col key={index}>
            <Input
              ref={(el) => {
                if (el) {
                  inputRefs.current[index] = (
                    el as { input: HTMLInputElement }
                  ).input;
                }
              }}
              value={otp[index]}
              onChange={(e) => handleChange(index, e)}
              onKeyDown={(e) => handleKeyDown(index, e)}
              onPaste={(e) => handlePaste(e)}
              style={{
                width: "50px",
                height: "50px",
                textAlign: "center",
                fontSize: "20px",
                fontWeight: "bold",
                borderRadius: 8,
              }}
              maxLength={1}
              inputMode="numeric"
              pattern="[0-9]*"
            />
          </Col>
        ))}
        <div />
      </Row>

      <div style={{ textAlign: "center", marginTop: 20 }}>
        {canResend ? (
          <Button
            icon={<ReloadOutlined style={{ fontSize: 16 }} />}
            onClick={handleResend}
            loading={isLoading}
            type="link"
            style={{
              fontSize: 16,
              color: colors.primary,
            }}
          >
            {t("otp.resendOtp")}
          </Button>
        ) : (
          <ProText type="secondary">
            {t("otp.resendAvailableIn")} {formatTime(countdown)}
          </ProText>
        )}
      </div>
    </div>
  );
};

export default OtpInput;
