import { useModalsManagerContext } from "@/contexts/ModalsManagerContext";
import type { IpaymentStackNavigator } from "@/navigations/Types";
import {
	getTransactionStatus,
	getTransactionsData,
	type IorangePaymentStarter,
} from "@/utils/requests/orangePayment";
import ErrorModal from "@components/modals/ErrorModal";
import InformationModal from "@components/modals/InformationModal";
import LoadingModal from "@components/modals/LoadingModal";
import { LOG } from "@logger";
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";

import { useMutation, useQueryClient } from "@tanstack/react-query";
import * as WebBrowser from "expo-web-browser";
import { useState } from "react";

const log = LOG.extend("useOrangeMoney");

const paymentObjectDefault: IorangePaymentStarter = {
	// biome-ignore lint/style/useNamingConvention: <api expect type_paiement>
	type_paiement: 1,
	marchand: "1",
	service: "1",
	montant: 0,
	numero: "0707070707",
	commentaire: "Un commentaire",
};
const useOrangeMoney = (
	navigation?: NativeStackNavigationProp<
		IpaymentStackNavigator,
		"paymentAmountInputScreen",
		"IpaymentStackNavigator"
	>,
) => {
	const queryClient = useQueryClient();

	const [isBrowserOpen, setIsBrowserOpen] = useState(false);
	const { showModal, closeModal } = useModalsManagerContext();

	const handlePaymentUsingBrowser = async (url: string) => {
		setIsBrowserOpen(true);
		const result = await WebBrowser.openBrowserAsync(url);
		// setResult(result);
		log.debug("handlePaymentUsingBrowser | Result ::", result);
		setIsBrowserOpen(false);
	};

	const orangeTransactionInitializerMutation = useMutation({
		mutationFn: (amount: number) =>
			getTransactionsData({
				...paymentObjectDefault,
				montant: amount,
			}),
		onSuccess: (data) => {
			// return data.payment_url
			log.debug("orangeTransactionInitializerMutation request success, opening browser...");
			queryClient.invalidateQueries({ queryKey: ["transactionsHistory"] });
			// await handlePaymentUsingBrowser(data.payment_url);
			// await transactionsStatusMutation.mutate(data.order_id);
			// setResult(result);
		},
		onError: (err) => {
			log.error("orangeTransactionInitializerMutation |", err);
		},
	});

	const maxRetry = 3;
	const retryDelay = 5000;

	const transactionsStatusMutation = useMutation({
		mutationFn: (orderId: string) => getTransactionStatus(orderId),
		onSuccess: (data) => {
			log.debug("transactionsStatusMutation request success");
			queryClient.invalidateQueries({ queryKey: ["transactionsHistory"] });
			return data.status;
		},
		onError: (err) => {
			log.error("transactionsStatusMutation |", err);
			queryClient.invalidateQueries({ queryKey: ["transactionsHistory"] });
		},
		// retry: (failureCount, error) => {
		// 	log.warn("transactionsStatusMutation | retrying", failureCount, error);
		// 	return failureCount < maxRetry;
		// },
		// retryDelay(_failureCount, _error) {
		// 	return retryDelay;
		// },
	});

	const openBrowserThenCheckStatus = async (paymentUrl: string, orderId: string) => {
		try {
			await handlePaymentUsingBrowser(paymentUrl);
			log.info("openBrowserThenCheckStatus | Verifying transaction status...");
			showModal(<LoadingModal message="Vérification du statut de la transaction..." />);
			await transactionsStatusMutation.mutateAsync(orderId);
			closeModal();
			navigation?.getParent()?.navigate("paymentResultScreen");
		} catch (error) {
			log.error("openBrowserThenCheckStatus |", error);
			if (error instanceof Error) {
				if (error.name === "ORANGE_PAYMENT_IN_PROGRESS") {
					log.warn("openBrowserThenCheckStatus | ORANGE_PAYMENT_IN_PROGRESS");
					await showModal(
						<InformationModal
							message="Le payment est toujours en cours."
							actionLabel="Rééssayer"
							onPress={() => openBrowserThenCheckStatus(paymentUrl, orderId)}
						/>,
					);
				} else if (error.name === "ORANGE_PAYMENT_FAILED") {
					showModal(<ErrorModal message="Le paiment à échoué." />);
					log.error("openBrowserThenCheckStatus | ORANGE_PAYMENT_FAILED");
				}
			} else {
				log.error("openBrowserThenCheckStatus |", error);
				closeModal();
				throw error;
			}
		}
	};

	const orangePaymentTransactionHandler = async (amount: number) => {
		try {
			showModal(<LoadingModal message="Initialization de la transaction." />);
			const { payment_url, order_id } =
				await orangeTransactionInitializerMutation.mutateAsync(amount);
			log.info("orangePaymentTransactionHandler |", payment_url, order_id);
			log.info("Opening browser for payment...");
			await openBrowserThenCheckStatus(payment_url, order_id);
		} catch (error) {
			log.error("makePayment |", error);
			throw error;
		} finally {
			//closeModal(); // just to be ultra sure that the modal is closed
		}
	};

	return {
		orangeTransactionInitializerMutation: orangeTransactionInitializerMutation,

		handlePaymentUsingBrowser,
		isBrowserOpen,
		isWaitingForOmPaymentUrl: orangeTransactionInitializerMutation.isPending,
		isCheckingForTransactionStatus: transactionsStatusMutation.isPending,
		transactionsStatusMutation,
		orangePaymentTransactionHandler,
	};
};

export default useOrangeMoney;
