import { useQuery } from "@tanstack/react-query";
import { useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";

import type { Token } from "@/types/index";
import { canViewFeature } from "@components/FeatureFlag/config";
import { useAccounts } from "@hooks/useAccounts";
import { useConfig } from "@hooks/useConfig";
// import { useWalletCapabilities } from "@hooks/useWalletCapabilities";
import { setIsFetchingDisabled } from "@store/quoteParamSlice";
import type { ReduxStateType } from "@store/types";
import { bungeeApiFetcher } from "@utils/fetcher";
import { getValidAddress } from "@utils/getValidAddress";
import { isSolana } from "@utils/isSolana";
import { onQuoteResult, onRequestQuote } from "../../../../analytics/events";
import type { BungeeQuote } from "./types";
import { formatAutoRoute, formatManualRoutes } from "./utils";

function getTokenAddresses(tokens: Token[]) {
	return tokens?.map((token) => token.address);
}

export const useFetchQuotes = () => {
	const { apiKey, baseUrl } = useConfig();
	const { accounts } = useAccounts();
	const dispatch = useDispatch();
	const {
		fromChainId,
		fromTokens,
		toChainId,
		toTokens,
		sender,
		amounts,
		receiver,
		addOnRefuel,
		isFetchingDisabled,
	} = useSelector((state: ReduxStateType) => state.quoteParams);
	const { slippage, dynamicSlippage } = useSelector(
		(state: ReduxStateType) => state.settings,
	);
	const manualModeFeatureEnabled = canViewFeature("MANUAL_MODE");

	const shouldFetch = !!(
		amounts?.length &&
		fromChainId &&
		toChainId &&
		fromTokens?.length &&
		toTokens?.length
	);

	// const { supportsAtomicBatching } = useWalletCapabilities(
	// 	fromChainId ?? undefined,
	// );

	const queryParams = useMemo(() => {
		dispatch(setIsFetchingDisabled(false));

		const userAddress = getValidAddress({
			chainId: fromChainId,
			address: sender,
			fallbackAddress: null,
		});

		const addressWithSameNetwork = accounts.find(
			(account) => account.chainType === (isSolana(toChainId || 0) ? "SVM" : "EVM"),
		)?.address;

		const receiverAddress = getValidAddress({
			chainId: toChainId,
			address: receiver,
			fallbackAddress: addressWithSameNetwork || sender,
		});

		const params = new URLSearchParams({
			userAddress,
			originChainId: fromChainId?.toString() ?? "",
			destinationChainId: toChainId?.toString() ?? "",
			inputAmount: amounts?.[0]?.toString() ?? "",
			inputToken: fromTokens?.[0]?.address ?? "",
			// enable manual if feature is enabled - can be extended to user setting (not implemented yet)
			enableManual: manualModeFeatureEnabled ? "true" : "false",
			receiverAddress,
			refuel: addOnRefuel ? "true" : "false",
			// useInbox: supportsAtomicBatching ? "true" : "false",
		});

		// appending output tokens
		if (toTokens?.length) {
			params.append("outputToken", getTokenAddresses(toTokens).join(","));
		}

		if (!dynamicSlippage) {
			params.append("slippage", slippage);
		}

		return params;
	}, [
		accounts,
		fromChainId,
		toChainId,
		sender,
		dispatch,
		fromTokens,
		toTokens,
		amounts,
		receiver,
		slippage,
		addOnRefuel,
		manualModeFeatureEnabled,
		dynamicSlippage,
		// supportsAtomicBatching,
	]);

	// biome-ignore format:
	const query = `${baseUrl}/bungee/quote?${queryParams.toString()}`;

	const { data, isLoading, refetch, isFetching } = useQuery({
		queryKey: [
			"bungee-auto-quote",
			apiKey,
			amounts,
			fromChainId,
			toChainId,
			fromTokens,
			toTokens,
			sender,
			receiver,
			slippage,
			addOnRefuel,
			dynamicSlippage,
		],
		queryFn: async () => {
			onRequestQuote({
				source_chain_id: fromChainId as number,
				destination_chain_id: toChainId as number,
				source_token_symbol: fromTokens?.[0]?.symbol,
				destination_token_symbol: toTokens?.[0]?.symbol,
				input_amount: Number(amounts[0]),
			});
			const response = await bungeeApiFetcher(query, apiKey);
			return response;
		},
		enabled: shouldFetch && !isFetchingDisabled,
		refetchInterval: 30000,
		refetchOnWindowFocus: false,
		refetchOnMount: false,
		retry: 1,
		staleTime: 30000,
		throwOnError: () => {
			onQuoteResult({
				bestoutput_option: undefined,
				fastest_option: undefined,
				default_selected: undefined,
				quote_count: 0,
				status: "error",
				source_chain_id: fromChainId as number,
				destination_chain_id: toChainId as number,
				source_token_symbol: fromTokens?.[0]?.symbol,
				destination_token_symbol: toTokens?.[0]?.symbol,
				input_amount: Number(amounts[0]),
			});
			return false;
		},
	});

	return {
		data: data?.result as BungeeQuote,
		formattedAutoRoute: formatAutoRoute(data?.result),
		formattedManualRoutes: addOnRefuel ? null : formatManualRoutes(data?.result),
		isLoading,
		isRefetching: isFetching,
		refetch,
	};
};

// function getMultiplePairs(key: string, values: string[] | number[]) {
// 	const _arr = [];

// 	for (const value of values) {
// 		// biome-ignore format:
// 		_arr.push(`${key}=${value}`);
// 	}

// 	return _arr.join("&");
// }
