import { useMemo } from "react";
import { useSelector } from "react-redux";

import type { Token } from "@/types/index";
import type { ReduxStateType } from "@store/types";
import { addImportedTokens } from "@utils/addImportedTokens";
import { useConfig } from "./useConfig";
import { useSupportedChains } from "./useSupportedChains";

interface UseSupportedTokensResult {
	[chainId: number]: Token[];
}

/**
 *  This hooks returns tokens as per chains supported
 *
 * 	Adds imported tokens to the list &
 *  filters out tokens for the chains that are not supported
 *
 *  Filters out the config tokens if available
 */

export const useSupportedTokens = ({ input = true }: { input: boolean }) => {
	const config = useConfig();

	const importedTokens = useSelector(
		(state: ReduxStateType) => state.global.importedTokens,
	);
	const shortListTokens = useSelector(
		(state: ReduxStateType) => state.global.shortTokenList,
	);
	const { supportedChainIds } = useSupportedChains({ input: input });

	// Filtering out config token address if provided
	const tokensFromConfig = useMemo(() => {
		const _fromTokens = config?.supportedTokens?.from;
		const _toTokens = config?.supportedTokens?.to;

		if (input) {
			if (_fromTokens) return _fromTokens;
		} else {
			if (_toTokens) return _toTokens;
		}
	}, [config, input]);

	return useMemo(() => {
		const filteredTokens = supportedChainIds
			? Object.keys(shortListTokens)
					.filter((chainId) => supportedChainIds.includes(Number(chainId)))
					.reduce((acc, _chainId) => {
						const chainId = Number(_chainId);
						if (tokensFromConfig) {
							acc[chainId] = shortListTokens[chainId]?.filter((token) =>
								tokensFromConfig[chainId].find(
									(item) => item.toLowerCase() === token?.address?.toLowerCase(),
								),
							);
						} else {
							acc[chainId] = shortListTokens[chainId];
						}
						return acc;
					}, {} as UseSupportedTokensResult)
			: shortListTokens;

		return addImportedTokens(filteredTokens, importedTokens);
	}, [shortListTokens, importedTokens, supportedChainIds, tokensFromConfig]);
};

export function filterSupportedTokens(
	mainList: { [chainid: number]: Token[] },
	subList: { [chainId: number]: string[] },
) {
	for (const _chainId of Object.keys(subList)) {
		const chainId = Number(_chainId);
		const supportedTokensAddresses = subList[chainId];

		const existingTokens = mainList[chainId] || [];
		return existingTokens?.filter((token) =>
			supportedTokensAddresses.find(
				(item) => item.toLowerCase() === token?.address?.toLowerCase(),
			),
		);
	}
}
