import React, { useState, useEffect } from "react";
import {
  View,
  ScrollView,
  InteractionManager,
  ActivityIndicator,
} from "react-native";
import { useFocusEffect } from "expo-router";
import { Button } from "~/components/ui/button";
import { Text } from "~/components/ui/text";
import { PhonePinKeypad } from "~/components/ui/PhonePinKeypad";
import { router, useLocalSearchParams } from "expo-router";
import { ROUTES } from "~/lib/routes";
import { useAuthWithProfile } from "~/lib/hooks/useAuthWithProfile";
import { useUserWallet } from "~/lib/hooks/useUserWallet";
import {
  validateBalanceWithFee,
  getFeeInformation,
  calculateTotalAmountForSending,
} from "~/lib/utils/feeUtils";
import {
  parseDisplayToCents,
  formatDisplayAmount,
} from "~/lib/utils/monetaryUtils";
import SendMoneyBar from "~/components/ui/sendMoneyBar";
import { Big } from "big.js";
import { PinConfirmationModal } from "~/components/ui/pinConfirmationModal";
import { amountSchema, validate } from "~/lib/utils/validationSchemas";
import { showAlert } from "~/lib/utils/alertUtils";
import ScreenWrapper from "~/components/ui/ScreenWrapper";
import ModalToast from "~/components/ui/toast";
import { useTranslation } from "react-i18next";

export default function SendOrRequestMoney() {
  const { user } = useAuthWithProfile();
  const { wallet } = useUserWallet(user);
  const [amount, setAmount] = useState("");
  const [showPinModal, setShowPinModal] = useState(false);
  const [pendingAction, setPendingAction] = useState<"send" | "request" | null>(
    null
  );
  const [isSecurityVerified, setIsSecurityVerified] = useState(false);
  const { t } = useTranslation();

  const [toastVisible, setToastVisible] = useState(false);
  const [toastTitle, setToastTitle] = useState("");
  const [toastDescription, setToastDescription] = useState<string | undefined>(
    undefined
  );
  const [toastVariant, setToastVariant] = useState<
    "success" | "error" | "warning" | "info"
  >("info");
  const toastTimeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(
    null
  );

  const showToast = (
    title: string,
    description?: string,
    variant: "success" | "error" | "warning" | "info" = "info"
  ) => {
    if (toastTimeoutRef.current) {
      clearTimeout(toastTimeoutRef.current);
    }

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

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

  useEffect(() => {
    const task = InteractionManager.runAfterInteractions(() => {
      if (__DEV__) {
        console.log("SEND OR REQUEST MONEY PAGE MOUNTED");
      }
    });
    return () => task.cancel();
  }, []);

  // Get contact params from navigation
  const params = useLocalSearchParams<{
    selectedContactId?: string;
    selectedContactName?: string;
    selectedContactPhone?: string;
  }>();

  // Reset state and show PIN modal when screen comes into focus
  // useFocusEffect only runs when screen is focused, so we can safely show modal here
  useFocusEffect(
    React.useCallback(() => {
      setIsSecurityVerified(false);
      setShowPinModal(true);
      setAmount("");
      setPendingAction(null);

      // Cleanup: hide modal when screen loses focus
      return () => {
        setShowPinModal(false);
        setIsSecurityVerified(false);
      };
    }, [])
  );

  // Handle number input and special actions (copied from addcash.tsx)
  const handleNumberPress = (input: string) => {
    if (input === "clear") {
      handleClear();
      return;
    }

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

    // Handle decimal point
    if (input === ".") {
      // Prevent multiple decimals
      if (amount.includes(".")) return;

      // If empty, start with "0."
      if (amount === "") {
        setAmount("0.");
        return;
      }

      // Add decimal point
      setAmount(amount + ".");
      return;
    }

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

    // Handle leading zeros
    if (amount === "0" && input !== ".") {
      setAmount(input); // Replace leading zero
      return;
    }

    const newAmount = amount + input;

    // Check decimal places limit (max 2 decimal places)
    if (newAmount.includes(".")) {
      const [whole, decimal] = newAmount.split(".");
      if (decimal && decimal.length > 2) return;
    }

    // Check maximum amount (max $999.99)
    try {
      const numValue = new Big(newAmount);
      if (numValue.gt(999.99)) return;
    } catch (error) {
      return;
    }

    // Check total length to prevent very long inputs
    if (newAmount.length > 6) return; // Max: 999.99

    setAmount(newAmount);
  };

  // Handle backspace
  const handleBackspace = () => {
    if (amount.length === 0) return;

    // Remove last character
    const newAmount = amount.slice(0, -1);
    setAmount(newAmount);
  };

  // Clear all input
  const handleClear = () => {
    setAmount("");
  };

  // Validate if amount is valid for submission
  const isValidAmount = () => {
    if (
      !amount ||
      amount === "" ||
      amount === "0" ||
      amount === "0." ||
      amount === "0.00"
    ) {
      return false;
    }

    const amountInCents = parseDisplayToCents(amount);
    if (amountInCents < 1 || amountInCents > 99999) {
      // 1 cent to $999.99
      return false;
    }

    // Check if amount is within wallet balance (including processing fee)
    const currentBalance = wallet?.balance || 0; // Balance in cents
    const totalRequired = calculateTotalAmountForSending(amountInCents);

    return currentBalance >= totalRequired;
  };

  // Get validation error message
  const getValidationError = () => {
    // Validate basic amount using valibot
    const amountValidationResult = validate(
      amountSchema({ min: 1, max: 99999 }),
      amount
    );
    if (!amountValidationResult.success) {
      return amountValidationResult.error;
    }

    const amountInCents = parseDisplayToCents(amount);
    if (amountInCents < 1) {
      return t("sendorrequestmoney.validationMinAmount");
    }

    if (amountInCents > 99999) {
      // $999.99
      return t("sendorrequestmoney.validationMaxAmount");
    }

    // Check if amount exceeds wallet balance (including processing fee)
    const currentBalance = wallet?.balance || 0; // Balance in cents
    const balanceValidation = validateBalanceWithFee(
      currentBalance,
      amountInCents
    );

    if (!balanceValidation.hasSufficientBalance) {
      const balanceInDollars = currentBalance / 100;
      const requiredInDollars = balanceValidation.requiredBalance / 100;
      return t("sendorrequestmoney.validationInsufficientBalance", {
        required: requiredInDollars.toFixed(2),
        fee: balanceValidation.feeInfo.formatted.fee,
        available: balanceInDollars.toFixed(2),
      });
    }

    return null;
  };

  // Handle PIN confirmation success
  const handlePinSuccess = () => {
    setShowPinModal(false);
    setIsSecurityVerified(true);
  };

  // Handle send money action (called after PIN is verified)
  const handleSendMoney = async () => {
    const validationError = getValidationError();
    if (validationError) {
      showToast(
        t("sendorrequestmoney.validationErrorTitle"),
        validationError,
        "error"
      );
      return;
    }

    const amountInCents = parseDisplayToCents(amount);
    console.log("Sending money:", amountInCents, "cents");

    router.push({
      pathname: ROUTES.SELECT_RECIPIENT,
      params: {
        amount: amountInCents.toString(), // Pass cents as string
        selectedContactId: params.selectedContactId,
        selectedContactName: params.selectedContactName,
        selectedContactPhone: params.selectedContactPhone,
      },
    });
  };

  const handleRequestMoney = async () => {
    const validationError = getValidationError();
    if (validationError) {
      showToast(
        t("sendorrequestmoney.validationErrorTitle"),
        validationError,
        "error"
      );
      return;
    }

    const amountInCents = parseDisplayToCents(amount);
    console.log("Requesting money:", amountInCents, "cents");

    router.push({
      pathname: ROUTES.SELECT_DONOR,
      params: {
        amount: amountInCents.toString(), // Pass cents as string
        selectedContactId: params.selectedContactId,
        selectedContactName: params.selectedContactName,
        selectedContactPhone: params.selectedContactPhone,
      },
    });
  };

  return (
    <ScreenWrapper edges={[]}>
      <View className="flex-1">
        {!isSecurityVerified && !showPinModal ? (
          <View className="flex-1 justify-center items-center bg-background">
            <ActivityIndicator size="large" color="#1F7A47" />
            <View className="h-4" />
            <Text className="text-gray-600 font-dmsans-medium text-lg">
              {t("sendorrequestmoney.verifyingSecurity")}
            </Text>
          </View>
        ) : (
          <View className="flex-1">
            <SendMoneyBar />
            <View className="flex-1 px-5 pb-4 pt-10 justify-between">
              <View>
                <View className="items-center mb-2">
                  <View className="flex flex-row items-center space-y-1">
                    <Text className="text-lg font-dmsans-medium text-gray-600">
                      {t("sendorrequestmoney.availableBalanceLabel")}
                    </Text>
                    <View className="w-2" />
                    <Text className="text-lg font-dmsans-medium text-gray-800">
                      ${wallet ? (wallet.balance / 100).toFixed(2) : "0.00"}
                    </Text>
                  </View>
                </View>

                {/* Big amount */}
                <View className="items-center mb-4">
                  <Text className="text-8xl py-2 font-dmsans-bold text-center text-black ">
                    {formatDisplayAmount(amount)}
                  </Text>
                </View>

                {/* Fee Information Display */}
                <View className="w-full mb-2">
                  {amount && parseDisplayToCents(amount) > 0 && (
                    <View className="px-4">
                      {(() => {
                        const amountInCents = parseDisplayToCents(amount);
                        const feeInfo = getFeeInformation(amountInCents);
                        return (
                          <View className="p-3">
                            <Text className="text-sm font-dmsans-medium text-gray-600 text-center">
                              {t("sendorrequestmoney.processingFee", {
                                fee: feeInfo.formatted.fee,
                                percent: "1.25",
                              })}
                            </Text>
                            <Text className="text-sm font-dmsans-bold text-gray-800 text-center mt-1">
                              {t("sendorrequestmoney.totalLabel", {
                                total: feeInfo.formatted.total,
                              })}
                            </Text>
                          </View>
                        );
                      })()}
                    </View>
                  )}
                </View>
              </View>

              <View className="pb-16">
                <View className="">
                  <PhonePinKeypad
                    onKeyPress={handleNumberPress}
                    showDecimal={true}
                  />
                </View>
                <View className="items-center flex flex-row justify-between w-full mt-4 gap-2">
                  <View className="w-1/2">
                    <Button
                      className="bg-primary rounded-3xl"
                      disabled={!isValidAmount()}
                      onPress={handleRequestMoney}
                    >
                      <Text className="font-dmsans-medium text-white">
                        {isValidAmount()
                          ? t("sendorrequestmoney.requestButtonWithAmount", {
                              amount: formatDisplayAmount(amount),
                            })
                          : t("sendorrequestmoney.requestButton")}
                      </Text>
                    </Button>
                  </View>
                  <View className="w-1/2 ">
                    <Button
                      className="bg-primary rounded-3xl"
                      onPress={handleSendMoney}
                      disabled={!isValidAmount()}
                    >
                      <Text className="font-dmsans-medium text-white">
                        {isValidAmount()
                          ? t("sendorrequestmoney.payButtonWithAmount", {
                              amount: formatDisplayAmount(amount),
                            })
                          : t("sendorrequestmoney.payButton")}
                      </Text>
                    </Button>
                  </View>
                </View>
              </View>
            </View>
          </View>
        )}
      </View>

      {/* PIN Confirmation Modal */}
      <PinConfirmationModal
        visible={showPinModal}
        onClose={() => {
          setShowPinModal(false);
        }}
        onSuccess={handlePinSuccess}
        title={t("sendorrequestmoney.pinModalTitle")}
      />
      <ModalToast
        visible={toastVisible}
        title={toastTitle}
        description={toastDescription}
        variant={toastVariant}
      />
    </ScreenWrapper>
  );
}
