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 { useConfig } from "@hooks/useConfig";
import { setIsFetchingDisabled } from "@store/quoteParamSlice";
import type { ReduxStateType } from "@store/types";
import { DUMMY_ADDRESS } from "@utils/constants";
import { bungeeApiFetcher } from "@utils/fetcher";
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 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 queryParams = useMemo(() => {
		dispatch(setIsFetchingDisabled(false));
		const params = new URLSearchParams({
			userAddress: sender || DUMMY_ADDRESS,
			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: receiver || sender || DUMMY_ADDRESS,
			refuel: addOnRefuel ? "true" : "false",
		});

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

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

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

	// 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: () => bungeeApiFetcher(query, apiKey),
		enabled: shouldFetch && !isFetchingDisabled,
		refetchInterval: 30000,
		refetchOnWindowFocus: false,
		refetchOnMount: false,
		retry: 1,
		staleTime: 30000,
	});

	return {
		data: data?.result as BungeeQuote,
		formattedAutoRoute: formatAutoRoute(data?.result),
		formattedManualRoutes: 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("&");
// }
