import { useAuthHandler } from "@/hooks/useAuthHandler";
import { useAuthStore } from "@/providers/AuthStoreProviders";
import { emailOrPhone } from "@/utils/helper";
import { router, useLocalSearchParams } from "expo-router";
import React, {
  SetStateAction,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import {
  NativeSyntheticEvent,
  Pressable,
  StyleSheet,
  Text,
  TextInput,
  TextInputKeyPressEventData,
  View,
} from "react-native";
import OtpTimer from "./OTPTimer";
import { User } from "@/types/user";
import Button from "../ui/Button";
import { storage } from "@/configs/storage";

interface OTPFieldProps {
  length?: number;
  onComplete?: (otp: string) => void;
  otp: string[];
  setOtp: React.Dispatch<SetStateAction<string[]>>;
  time: number;
}

const OTPField: React.FC<OTPFieldProps> = ({
  length = 6,
  onComplete,
  otp,
  setOtp,
  time,
}) => {
  const { email, phone } = useLocalSearchParams();
  const { user, getUser, login } = useAuthStore((state: any) => state);
  const otp_expire_key =
    (Array.isArray(email) ? email[0] : email) ||
    (Array.isArray(phone) ? phone[0] : phone) ||
    user?.email ||
    user?.phone;
  const [otpBreakTime, setOtpBreakTime] = useState(0);

  const {
    sendOTP,
    otpSendLoading,
    verifyOTP,
    verifyLoading,
    redirect,
    setOtpBreakTimer,
    signInWith2fa,
  } = useAuthHandler();

  const [otpInputHandler, setOtpInputHandler] = useState<{
    isComplete: boolean;
    isInvalid: boolean;
    otp: string;
    isReset: boolean;
  }>({
    isComplete: false,
    isInvalid: false,
    otp: "",
    isReset: false,
  });
  // const signInCount = Cookies.get("sign_in_count");

  const isEmail = useMemo(() => !!email || !!user?.email, [email, user]);

  const handleVerify = async () => {
    if (!otpInputHandler.otp.length) {
      setOtpInputHandler((prev) => ({
        ...prev,
        isInvalid: true,
        isComplete: false,
        isReset: false,
      }));
      return;
    }

    const signInCount = storage.getString("sign_in_count");

    signInWith2fa(
      { otp: otpInputHandler.otp, ...emailOrPhone(otp_expire_key, isEmail) },
      {
        onSuccess: async (response: any) => {
          // toast.success(response?.data?.message);
          const updatedUser: User = await getUser();
          setOtpInputHandler((prev) => ({
            ...prev,
            isReset: true,
            isComplete: false,
            isInvalid: false,
          }));

          if (isEmail && updatedUser?.email_verified_at) {
            storage.remove(updatedUser?.email);
          }

          if (!isEmail && updatedUser?.phone_verified_at) {
            storage.remove(updatedUser?.phone);
          }

          setOtpBreakTime(0);

          if (!updatedUser?.phone_verified_at && signInCount === "2") {
            handleResend();
          }

          const redirectURL = await redirect(response?.data?.user);

          login(response?.data?.token, response?.data?.user);

          router.replace(redirectURL as any);
        },
        onError: (error: any) => {
          // toast.error(error?.response?.data?.message);
          setOtpInputHandler((prev) => ({
            ...prev,
            isReset: true,
            isComplete: false,
            isInvalid: true,
          }));
        },
      },
    );
  };

  const handleResend = () => {
    sendOTP(emailOrPhone(otp_expire_key, isEmail), {
      onSuccess: (response: any) => {
        // toast.success(response?.data?.message);
        setOtpInputHandler((prev) => ({
          ...prev,
          isReset: true,
          isComplete: false,
          isInvalid: false,
        }));
        setOtpBreakTimer(otp_expire_key);
        setOtpBreakTime(0);
        // router.replace(redirect(user));
      },
    });
  };

  const inputRefs = useRef<(TextInput | null)[]>([]);

  useEffect(() => {
    // Focus first input on mount
    inputRefs.current[0]?.focus();
  }, []);

  const handleChange = (text: string, index: number): void => {
    if (isNaN(Number(text))) return; // Only allow numbers

    const newOtp = [...otp];
    newOtp[index] = text;
    setOtp(newOtp);

    const joinedOtp = newOtp.join("");

    // Store the OTP string inside otpInputHandler
    setOtpInputHandler((prev) => ({
      ...prev,
      otp: joinedOtp,
      isComplete: joinedOtp.length === length,
      isInvalid: false,
      isReset: false,
    }));

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

    // Optionally call onComplete when done
    if (joinedOtp.length === length && onComplete) {
      onComplete(joinedOtp);
    }
  };

  const handleKeyPress = (
    e: NativeSyntheticEvent<TextInputKeyPressEventData>,
    index: number,
  ): void => {
    // Handle backspace
    if (e.nativeEvent.key === "Backspace") {
      if (otp[index] === "" && index > 0) {
        // Move to previous input if current is empty
        inputRefs.current[index - 1]?.focus();
      } else {
        // Clear current input
        const newOtp = [...otp];
        newOtp[index] = "";
        setOtp(newOtp);
      }
    }
  };

  const handleClear = (): void => {
    setOtp(Array(length).fill(""));
    inputRefs.current[0]?.focus();
  };

  return (
    <View style={styles.container}>
      <View style={styles.otpContainer}>
        {otp.map((digit, index) => (
          <TextInput
            key={index}
            ref={(ref) => {
              inputRefs.current[index] = ref;
            }}
            style={[styles.otpInput, digit !== "" && styles.otpInputFilled]}
            value={digit}
            onChangeText={(text) => handleChange(text, index)}
            onKeyPress={(e) => handleKeyPress(e, index)}
            keyboardType="number-pad"
            maxLength={1}
            selectTextOnFocus
            autoComplete="sms-otp"
          />
        ))}
      </View>

      <Pressable onPress={handleClear} style={styles.clearButton}>
        <Text style={styles.clearButtonText}>Clear</Text>
      </Pressable>

      <OtpTimer onClick={handleResend} otpTimerKey="email" time={time * 60} />

      <Button
        className=""
        onPress={handleVerify}
        text="Verify"
        isLoading={otpSendLoading || verifyLoading}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    backgroundColor: "white",
    borderRadius: 16,
    padding: 24,
    width: "100%",
  },
  title: {
    fontSize: 24,
    fontWeight: "bold",
    color: "#1a1a1a",
    textAlign: "center",
    marginBottom: 8,
  },
  subtitle: {
    fontSize: 14,
    color: "#666",
    textAlign: "center",
    marginBottom: 32,
  },
  otpContainer: {
    flexDirection: "row",
    justifyContent: "space-between",
    marginBottom: 24,
  },
  otpInput: {
    width: 48,
    height: 56,
    borderWidth: 2,
    borderColor: "#e0e0e0",
    borderRadius: 12,
    textAlign: "center",
    fontSize: 24,
    fontWeight: "600",
    color: "#1a1a1a",
    backgroundColor: "#fafafa",
  },
  otpInputFilled: {
    borderColor: "#4f46e5",
    backgroundColor: "#eef2ff",
  },
  clearButton: {
    alignSelf: "center",
    paddingVertical: 12,
    paddingHorizontal: 24,
    borderRadius: 8,
    backgroundColor: "#f3f4f6",
    marginBottom: 16,
  },
  clearButtonText: {
    color: "#4b5563",
    fontSize: 14,
    fontWeight: "600",
  },
  resendButton: {
    alignSelf: "center",
    paddingVertical: 8,
  },
  resendButtonText: {
    color: "#4f46e5",
    fontSize: 14,
    fontWeight: "500",
  },
});

export default OTPField;
