import { useActiveRoute } from "@hooks/apis/common/quote/useActiveRoute";
import { isAutoQuote, isManualQuote } from "@hooks/apis/common/quote/utils";
import { formatValue } from "@utils/formatValue";

interface EligibleRewardsProps {
	approvedSourceTokens?: string[];
	requiredSourceTokens?: string[];
	requiredSourceChains?: number[];
	approvedSourceChains?: number[];
	approvedDestinationTokens?: `${string}:${number}`[];
	requiredDestinationTokens?: `${string}:${number}`[];
	requiredDestinationChains?: number[];
	rewardCap?: number;
	destinationRequirement: "token" | "chain" | null; // null means any token or chain
	sourceRequirement: "token" | "chain" | null; // null means any token or chain
	minimumAmount?: number;
	minimumAmountType?: "usd" | "token";
	routeType?: "auto" | "manual" | null;
	excemptedDestinationTokens?: string[];
	excemptedSourceTokens?: string[];
	excemptedSourceChains?: number[];
	excemptedDestinationChains?: number[];
	minimumEligibleAmountInUsd?: number;
}

export const useEligibleRewards = ({
	approvedSourceTokens = [],
	approvedDestinationTokens = [],
	requiredSourceTokens = [],
	requiredSourceChains = [],
	requiredDestinationTokens = [],
	requiredDestinationChains = [],
	approvedSourceChains = [],
	rewardCap = 30,
	destinationRequirement,
	sourceRequirement,
	minimumAmount = 200,
	minimumAmountType = "usd",
	routeType = "auto",
	excemptedDestinationTokens = [],
	excemptedSourceTokens = [],
	minimumEligibleAmountInUsd = 0.01,
	excemptedDestinationChains = [],
	excemptedSourceChains = [],
}: EligibleRewardsProps) => {
	const { data: activeRoute } = useActiveRoute();
	const autoQuote = isAutoQuote(activeRoute);
	const manualQuote = isManualQuote(activeRoute);

	// Check if amount is >= $minimumAmount in token amount
	const inputAmountUsd = activeRoute?.primaryInput?.valueInUsd;
	//   const inputAmountToken = getDecimals(Number(activeRoute?.primaryInput?.amount || "0"));
	const inputAmountToken = formatValue(
		activeRoute?.primaryInput?.amount || "0",
		activeRoute?.primaryInput?.token?.decimals || 18,
	);

	const hasMinimumAmount =
		minimumAmountType === "usd"
			? inputAmountUsd &&
				Number.parseFloat(inputAmountUsd.toString()) >= minimumAmount
			: inputAmountToken &&
				Number.parseFloat(inputAmountToken.toString()) >= minimumAmount;
	// Check if route is auto quote and has minimum amount

	const routeRequirementEligible =
		routeType === null ? true : routeType === "auto" ? autoQuote : manualQuote;

	if (!activeRoute || !hasMinimumAmount || !routeRequirementEligible) {
		return null;
	}

	// Check token addresses
	const sourceTokenAddress =
		activeRoute.primaryInput?.token?.address?.toLowerCase();
	const sourceChainId = activeRoute.primaryInput?.token?.chainId;
	const destinationChainId = activeRoute.primaryOutput?.token?.chainId;
	const destinationTokenAddress =
		activeRoute.primaryOutput?.token?.address?.toLowerCase();

	const isExcemptedSourceToken = validateTokensEligibility(
		excemptedSourceTokens,
		sourceTokenAddress,
		sourceChainId,
	);

	const isExcemptedDestinationToken = validateTokensEligibility(
		excemptedDestinationTokens,
		destinationTokenAddress,
		destinationChainId,
	);

	const isExcemptedDestinationChain =
		excemptedDestinationChains?.includes(destinationChainId);

	const isExcemptedSourceChain = excemptedSourceChains?.includes(sourceChainId);

	if (
		isExcemptedSourceToken ||
		isExcemptedDestinationToken ||
		isExcemptedSourceChain ||
		isExcemptedDestinationChain
	) {
		return null;
	}

	const isValidRequiredSourceToken =
		sourceRequirement === null
			? true
			: sourceRequirement === "token"
				? requiredSourceTokens
						.map((token) => token.toLowerCase())
						.includes(sourceTokenAddress?.toLowerCase())
				: requiredSourceChains?.includes(sourceChainId);

	//   TODO: Add support for approved chains
	const isValidApprovedSourceToken = approvedSourceTokens.length
		? validateTokensEligibility(
				approvedSourceTokens,
				sourceTokenAddress,
				sourceChainId,
			)
		: true;

	const isValidRequiredDestinationToken =
		destinationRequirement === null
			? true
			: destinationRequirement === "chain"
				? requiredDestinationChains?.includes(destinationChainId)
				: validateTokensEligibility(
						requiredDestinationTokens,
						destinationTokenAddress,
						destinationChainId,
					);

	const isValidApprovedDestinationToken = approvedDestinationTokens.length
		? validateTokensEligibility(
				approvedDestinationTokens,
				destinationTokenAddress,
				destinationChainId,
			)
		: true;

	if (
		!isValidRequiredSourceToken ||
		!isValidRequiredDestinationToken ||
		(!isValidApprovedSourceToken && !isValidApprovedDestinationToken)
	)
		return null;

	// Calculate USD value difference (source - destination)
	if (
		!activeRoute.primaryInput?.valueInUsd ||
		!activeRoute.primaryOutput?.valueInUsd
	)
		return null;

	const sourceUsdValue = activeRoute.primaryInput.valueInUsd;
	const destinationUsdValue = activeRoute.primaryOutput.valueInUsd;
	const usdDifference = sourceUsdValue - destinationUsdValue;

	// Only show if difference is positive
	if (usdDifference <= minimumEligibleAmountInUsd) return null;

	return Math.min(rewardCap, usdDifference);
};

const validateTokensEligibility = (
	tokens: string[],
	token_address: string,
	chainId: number,
) => {
	return tokens
		.map((token) => {
			const [address, chainId] = token.split(":");
			return {
				address: address?.toLowerCase(),
				chainId: chainId ? Number(chainId) : null,
			};
		})
		.some((token) => {
			if (token.chainId) {
				return (
					token.chainId === chainId &&
					token.address === token_address?.toLowerCase()
				);
			}
			return token.address === token_address?.toLowerCase();
		});
};
