import { useCallback, useEffect, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";

import { useMappedChainData } from "@hooks/useMappedChainData";
import { useSupportedChains } from "@hooks/useSupportedChains";
import { useSupportedTokens } from "@hooks/useSupportedTokens";
import { addOutputToken } from "@store/quoteParamSlice";
import type { TokenSelectorParams } from "@store/tokenSelectorSlice";
import type { ReduxStateType } from "@store/types";
import { useFallbackToken } from "./useFallbackToken";

/** Token Selector Data for Output Token Modal */
export const useOutputTokenSelectorData = () => {
	const dispatch = useDispatch();
	const mappedChainData = useMappedChainData();
	const { supportedChains: chains } = useSupportedChains({ input: false });
	const tokens = useSupportedTokens({ input: false });

	const activeChainId = useSelector(
		(state: ReduxStateType) => state.quoteParams.toChainId,
	);
	const activeChain = mappedChainData?.[activeChainId ?? 10]; // @todo: need to pass 'all' if balance is available

	const activeTokens = useSelector(
		(state: ReduxStateType) => state.quoteParams.toTokens,
	);
	const activeSourceTokens = useSelector(
		(state: ReduxStateType) => state.quoteParams.fromTokens,
	);
	const primarySourceToken = useMemo(
		() => activeSourceTokens?.[0],
		[activeSourceTokens],
	);

	const [fallbackToken] = useFallbackToken({
		tokenA: primarySourceToken,
		tokenB: activeTokens?.[0],
	});

	useEffect(() => {
		if (!dispatch) return;

		if (fallbackToken) {
			dispatch(addOutputToken({ id: 0, token: fallbackToken }));
		}
	}, [fallbackToken, dispatch]);

	const tokensToDisable = useCallback(() => {
		if (!primarySourceToken) return;

		return { [primarySourceToken?.chainId]: [primarySourceToken?.address] };
	}, [primarySourceToken]);

	const data: TokenSelectorParams = useMemo(() => {
		return {
			isVisible: true,
			data: {
				id: 0,
				chains,
				activeChain,
				activeToken: activeTokens?.[0],
				tokens,
				isSourceTokenSelector: false,
			},
		};
	}, [chains, tokens, activeChain, activeTokens]);

	return {
		data: data,
		isLoading: !Object.keys(tokens)?.length || !chains?.length,
	};
};
