import ErrorModal from "@components/modals/ErrorModal";
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";
import { useModalsManagerContext } from "@/contexts/ModalsManagerContext";
import type { IpaymentStackNavigator } from "@/navigations/types";
import {
	getTransactionStatus,
	type IwavePaymentStarter,
	initTransaction,
} from "@/utils/requests/wavePayment";

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

const paymentObjectDefault: IwavePaymentStarter = {
	// biome-ignore lint/style/useNamingConvention: <api>
	type_paiement: 2,
	marchand: "1",
	service: "2",
	montant: 0,
};

const useWave = (
	navigation?: NativeStackNavigationProp<
		IpaymentStackNavigator,
		"paymentAmountInputScreen",
		"IpaymentStackNavigator"
	>,
) => {
	const { showModal, closeModal } = useModalsManagerContext();
	const [_isBrowserOpen, setIsBrowserOpen] = useState(false);

	const _queryClient = useQueryClient();

	// Mutations

	const waveTransactionInitializerMutation = useMutation({
		mutationFn: (amount: number) =>
			initTransaction({
				...paymentObjectDefault,
				montant: amount,
			}),
		onSuccess: (_data) => {},
		onError: (err) => {
			log.error("waveTransactionInitializerMutation |", err);
		},
	});

	const waveTransactionStatusMutation = useMutation({
		mutationFn: (orderId: string) => getTransactionStatus(orderId),
		onSuccess: (_data) => {
			log.debug("waveTransactionStatusMutation request success");
		},
		onError: (err) => {
			log.error("waveTransactionStatusMutation |", err);
		},
	});

	// Browser stuff

	const handlePaymentUsingBrowser = async (url: string) => {
		log.debug("handlePaymentUsingBrowser | Opening the browser at url :: ", url);

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

	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 waveTransactionStatusMutation.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;
			// }
		}
	};

	// Handlers

	const waveTransactionHandler = async (amount: number) => {
		try {
			showModal(<LoadingModal message="Initialization de la transaction." />);

			const response = await waveTransactionInitializerMutation.mutateAsync(amount);
			log.info("waveTransactionHandler payment url received :: ", response.wave_launch_url);
			// log.info("Opening browser for payment...");
			log.info("Navigating to the qr code screen...");
			closeModal();
			navigation?.getParent()?.navigate("waveQrCodePaymentScreen", { data: response });

			// await openBrowserThenCheckStatus(response.wave_launch_url, response.id);
		} catch (error) {
			log.error("waveTransactionHandler |", error);
			showModal(<ErrorModal message="Une erreur s'est produite." />);
			throw error;
		}
	};

	const handlePaymentVerification = async (id: string) => {
		log.info("handlePaymentVerification |", id);
		try {
			showModal(<LoadingModal message="Vérification du statut de la transaction..." />);
			const _response = await waveTransactionStatusMutation.mutateAsync(id);
			closeModal();
		} catch (error) {
			log.error("handlePaymentVerification |", error);
			// closeModal();
			// showModal(<ErrorModal message="Le paiment a été echoué." />);
		} finally {
			// TODO : remove this finally block once a proper implementation workflow is set. currently we close the modal after logging whatever response we get from the request
			closeModal();
		}
	};

	return {
		waveTransactionInitializerMutation,
		waveTransactionHandler,
		handlePaymentVerification,
	};
};

export default useWave;
