import React, { useEffect, useState, useRef } from "react";
import {
  View,
  Text,
  Modal,
  Platform,
  ActivityIndicator,
  TouchableOpacity,
} from "react-native";
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
import { Button } from "~/components/ui/button";
import { PhonePinKeypad } from "~/components/ui/PhonePinKeypad";
import { useAuthWithProfile } from "~/lib/hooks/useAuthWithProfile";
import { useUserProfile } from "~/lib/hooks/useUserProfile";
import { router } from "expo-router";
import { ROUTES } from "~/lib/routes";
import BackButton from "./backButton";
import { Fingerprint, Lock } from "lucide-react-native";
import ModalToast from "~/components/ui/toast";

// Only import LocalAuthentication on native platforms
let LocalAuthentication: any = null;
if (Platform.OS !== "web") {
  LocalAuthentication = require("expo-local-authentication");
}
import { useTranslation } from "react-i18next";

interface PinConfirmationModalProps {
  visible: boolean;
  onClose: () => void;
  onSuccess: () => void;
  title?: string;
}

export const PinConfirmationModal: React.FC<PinConfirmationModalProps> = ({
  visible,
  onClose,
  onSuccess,
  title,
}) => {
  const { t } = useTranslation();

  const effectiveTitle =
    title ?? t("components.pinconfirmationmodal.titleDefault");
  const { user } = useAuthWithProfile();
  const { profile } = useUserProfile(user);

  const [pin, setPin] = useState("");
  const [isVerifying, setIsVerifying] = useState(false);
  const [isAttemptingBiometric, setIsAttemptingBiometric] = useState(false);
  const [biometricAttempted, setBiometricAttempted] = useState(false);
  const [authMethod, setAuthMethod] = useState<"none" | "fingerprint" | "pin">(
    "none"
  );
  const [biometricAvailable, setBiometricAvailable] = useState(false);
  const prevVisibleRef = useRef(false);
  const [toastVisible, setToastVisible] = useState(false);
  const [toastTitle, setToastTitle] = useState("");
  const [toastDescription, setToastDescription] = useState<string | undefined>(
    undefined
  );
  const toastTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const showToast = (title: string, description?: string) => {
    if (toastTimeoutRef.current) {
      clearTimeout(toastTimeoutRef.current);
    }

    setToastTitle(title);
    setToastDescription(description);
    setToastVisible(true);

    toastTimeoutRef.current = setTimeout(() => {
      setToastVisible(false);
      toastTimeoutRef.current = null;
    }, 2500);
  };

  const attemptBiometric = async () => {
    // Web: No biometric support
    if (Platform.OS === "web" || !LocalAuthentication) {
      showToast("Error", "Biometric authentication not available on web");
      setAuthMethod("none");
      return;
    }

    if (!user) return;

    try {
      const hasHardware = await LocalAuthentication.hasHardwareAsync();
      if (!hasHardware) {
        showToast(
          t("components.pinconfirmationmodal.toastBiometricErrorTitle"),
          t(
            "components.pinconfirmationmodal.toastBiometricHardwareNotAvailable"
          )
        );
        setAuthMethod("none");
        return;
      }
      const isEnrolled = await LocalAuthentication.isEnrolledAsync();
      if (!isEnrolled) {
        showToast(
          t("components.pinconfirmationmodal.toastBiometricErrorTitle"),
          t("components.pinconfirmationmodal.toastBiometricNotEnrolled")
        );
        setAuthMethod("none");
        return;
      }

      setIsAttemptingBiometric(true);
      const result = await LocalAuthentication.authenticateAsync({
        promptMessage: effectiveTitle,
        cancelLabel: t("components.pinconfirmationmodal.cancelButton"),
        disableDeviceFallback: true,
        requireConfirmation: false,
      });
      setIsAttemptingBiometric(false);
      if (result.success) {
        setPin("");
        setBiometricAttempted(false);
        setAuthMethod("none");
        onSuccess();
      } else {
        // User cancelled or failed - reset to choice screen
        setAuthMethod("none");
      }
    } catch (e) {
      setIsAttemptingBiometric(false);
      setAuthMethod("none");
      showToast(
        t("components.pinconfirmationmodal.toastBiometricErrorTitle"),
        t("components.pinconfirmationmodal.toastBiometricFailed")
      );
    }
  };

  const handleFingerprintChoice = () => {
    setAuthMethod("fingerprint");
    attemptBiometric();
  };

  const handlePinChoice = () => {
    setAuthMethod("pin");
  };

  // Check biometric availability on mount and when modal opens
  useEffect(() => {
    const checkBiometricAvailability = async () => {
      // Web: Biometrics not available
      if (Platform.OS === "web" || !LocalAuthentication) {
        setBiometricAvailable(false);
        return;
      }

      // Native: Check for biometric hardware and enrollment
      if (Platform.OS === "android" || Platform.OS === "ios") {
        try {
          const hasHardware = await LocalAuthentication.hasHardwareAsync();
          const isEnrolled = await LocalAuthentication.isEnrolledAsync();
          setBiometricAvailable(hasHardware && isEnrolled);
        } catch (e) {
          setBiometricAvailable(false);
        }
      } else {
        setBiometricAvailable(false);
      }
    };

    if (visible) {
      checkBiometricAvailability();
    }
  }, [visible]);

  useEffect(() => {
    const prevVisible = prevVisibleRef.current;
    prevVisibleRef.current = visible;

    if (visible && !prevVisible) {
      // Modal just opened (transition from false to true)
      // Reset all states to ensure fresh start
      setPin("");
      setIsAttemptingBiometric(false);
      setBiometricAttempted(false);
      setAuthMethod("none");
    } else if (!visible && prevVisible) {
      // Modal just closed (transition from true to false)
      // Reset all states for next time
      setPin("");
      setIsAttemptingBiometric(false);
      setBiometricAttempted(false);
      setAuthMethod("none");
    }
  }, [visible]);

  // Render nothing when not requested
  if (!visible) {
    return null;
  }

  const handlePinSubmit = async () => {
    if (pin.length !== 6) {
      showToast(
        t("components.pinconfirmationmodal.toastInvalidPinTitle"),
        t("components.pinconfirmationmodal.toastInvalidPinDescription")
      );
      return;
    }
    setIsVerifying(true);

    if (!user) {
      showToast(
        t("components.pinconfirmationmodal.toastAuthErrorTitle"),
        t("components.pinconfirmationmodal.toastUserNotFound")
      );
      setIsVerifying(false);
      return;
    }

    const profilePin = profile?.pin;
    if (!profilePin) {
      showToast(
        t("components.pinconfirmationmodal.toastAuthErrorTitle"),
        t("components.pinconfirmationmodal.toastPinNotFound")
      );
      setIsVerifying(false);
      return;
    }

    // Incorrect PIN -> show inline toast instead of Alert
    if (pin !== profilePin) {
      showToast(
        t("components.pinconfirmationmodal.toastIncorrectPinTitle"),
        t("components.pinconfirmationmodal.toastIncorrectPinDescription")
      );
      setPin("");
      setIsVerifying(false);
      return;
    }

    // PIN is correct, call success callback
    setPin("");
    setIsVerifying(false);
    setBiometricAttempted(false);
    setIsAttemptingBiometric(false);
    onSuccess();
  };

  const handleNumberPress = (input: string) => {
    if (input === "clear") {
      setPin("");
      return;
    }

    if (input === "backspace") {
      handleBackspace();
      return;
    }

    // Handle digit input (0-9)
    if (!/^[0-9]$/.test(input)) return;

    // Limit to 6 digits
    if (pin.length >= 6) return;

    setPin(pin + input);
  };

  const handleBackspace = () => {
    setPin((prev) => prev.slice(0, -1));
  };

  const handleClose = () => {
    setPin("");
    setIsVerifying(false);
    setIsAttemptingBiometric(false);
    setBiometricAttempted(false);
    setAuthMethod("none");
    onClose();
  };

  const renderAuthMethodChoice = () => {
    // On web, skip biometric option entirely and go straight to PIN
    const showBiometricOption = biometricAvailable && Platform.OS !== "web";

    return (
      <View className="flex-1 justify-center items-center px-6 mt-[-20]">
        <View className="items-center mb-0">
          <Text className="text-2xl font-dmsans-bold text-gray-800 mb-2">
            {showBiometricOption
              ? "Choose Authentication Method"
              : "PIN Verification"}
          </Text>
          <Text className="text-gray-600 text-lg font-dmsans text-center mb-8">
            {effectiveTitle}
          </Text>
        </View>

        <View className="w-full space-y-4">
          {showBiometricOption && (
            <TouchableOpacity
              onPress={handleFingerprintChoice}
              className="flex-row items-center justify-between bg-gray-50 border-2 border-gray-200 rounded-2xl p-3 active:bg-gray-100"
            >
              <View className="flex-row items-center space-x-4">
                <View className="bg-primary/10 p-2 mr-4 rounded-full">
                  <Fingerprint size={26} color="hsl(147,55%,28%)" />
                </View>
                <View>
                  <Text className="text-xl font-dmsans-bold text-gray-800">
                    {t("components.pinconfirmationmodal.fingerprintTitle")}
                  </Text>
                  <Text className="text-gray-500 font-dmsans text-sm">
                    {t("components.pinconfirmationmodal.fingerprintSubtitle")}
                  </Text>
                </View>
              </View>
            </TouchableOpacity>
          )}

          {showBiometricOption && <View className="h-8" />}

          <TouchableOpacity
            onPress={handlePinChoice}
            className="flex-row items-center justify-between bg-gray-50 border-2 border-gray-200 rounded-2xl p-3 active:bg-gray-100"
          >
            <View className="flex-row items-center space-x-4">
              <View className="bg-primary/10 p-2 mr-4 rounded-full">
                <Lock size={26} color="hsl(147,55%,28%)" />
              </View>
              <View>
                <Text className="text-xl font-dmsans-bold text-gray-800">
                  {t("components.pinconfirmationmodal.pinTitle")}
                </Text>
                <Text className="text-gray-500 font-dmsans text-sm">
                  {t("components.pinconfirmationmodal.pinSubtitle")}
                </Text>
              </View>
            </View>
          </TouchableOpacity>
        </View>
      </View>
    );
  };

  const renderPinDots = () => {
    return (
      <View className="flex-row justify-around px-4 mb-6">
        {[0, 1, 2, 3, 4, 5].map((index) => (
          <View
            key={index}
            className={`w-5 h-5 rounded-full border-2 ${
              index < pin.length
                ? "bg-primary border-primary"
                : "bg-white border-gray-300"
            }`}
          />
        ))}
      </View>
    );
  };

  return (
    <View className="absolute inset-0 bg-white pb-14">
      <View className="flex-1">
        <BackButton
          onPress={() => {
            if (authMethod === "pin" || authMethod === "fingerprint") {
              setAuthMethod("none");
              setPin("");
              setIsAttemptingBiometric(false);
            } else {
              handleClose();
              router.replace(ROUTES.HOME);
            }
          }}
        />

        {authMethod === "none" ? (
          <Animated.View
            key="choice"
            className="flex-1"
            entering={FadeIn.duration(200).delay(50)}
            exiting={FadeOut.duration(150)}
          >
            {renderAuthMethodChoice()}
          </Animated.View>
        ) : isAttemptingBiometric ? (
          <Animated.View
            key="biometric"
            className="flex-1 justify-center items-center px-6"
            entering={FadeIn.duration(200).delay(50)}
            exiting={FadeOut.duration(150)}
          >
            <ActivityIndicator size="large" color="hsl(147,55%,28%)" />
            <View className="h-4" />
            <Text className="text-gray-600 font-dmsans text-lg">
              {t("components.pinconfirmationmodal.biometricWaiting")}
            </Text>
            <View className="h-8" />
            <TouchableOpacity
              onPress={() => {
                setAuthMethod("none");
                setIsAttemptingBiometric(false);
              }}
              className="px-6 py-3"
            >
              <Text className="text-primary font-dmsans-medium">
                {t("components.pinconfirmationmodal.cancelButton")}
              </Text>
            </TouchableOpacity>
          </Animated.View>
        ) : (
          <Animated.View
            key="pin"
            className="flex-1"
            entering={FadeIn.duration(200).delay(50)}
            exiting={FadeOut.duration(150)}
          >
            <View className="flex-1">
              {/* Header + title */}
              <View className="px-6 pt-20 pb-4">
                <View className="items-center mb-4">
                  <Text className="text-2xl font-dmsans-bold text-gray-800">
                    {t("components.pinconfirmationmodal.pinVerificationTitle")}
                  </Text>
                </View>

                <View className="items-center mb-4">
                  <Text className="text-gray-600 text-lg font-dmsans text-center">
                    {effectiveTitle}
                  </Text>
                </View>
              </View>

              {/* Bottom-aligned PIN area */}
              <View className="flex-1 justify-end">
                {/* PIN dots + Keypad - full width above button */}
                <View className="pb-2">
                  {renderPinDots()}
                  <View className="mt-6">
                    <PhonePinKeypad onKeyPress={handleNumberPress} />
                  </View>
                </View>

                {/* Submit Button - just above bottom bar */}
                <View className="px-5 py-5 bg-white border-t border-gray-100">
                  <Button
                    className={`rounded-3xl py-4 ${
                      pin.length === 6 ? "bg-primary" : "bg-gray-300"
                    }`}
                    onPress={handlePinSubmit}
                    disabled={
                      pin.length !== 6 || isVerifying || isAttemptingBiometric
                    }
                  >
                    <Text className="text-white font-dmsans-bold text-lg">
                      {isVerifying
                        ? t(
                            "components.pinconfirmationmodal.submitButtonVerifying"
                          )
                        : t(
                            "components.pinconfirmationmodal.submitButtonConfirm"
                          )}
                    </Text>
                  </Button>
                </View>
              </View>
            </View>
          </Animated.View>
        )}

        {/* Toast overlay above everything */}
        <ModalToast
          visible={toastVisible}
          title={toastTitle}
          description={toastDescription}
          variant="error"
        />
      </View>
    </View>
  );
};
