import { useSelector } from "react-redux";

import { useActiveRoute } from "@hooks/apis/common/quote/useActiveRoute";
import { useIsAbstractNetwork } from "@hooks/useIsAbstractNetwork";
import { useTokenBalance } from "@hooks/useTokenBalance";
import type { ReduxStateType } from "@store/types";
import { getPairsNetworkFromRoute } from "@utils/getPairsNetworkFromRoute";
import { isDummyAddress } from "@utils/isDummyAddress";

export interface ValidationResult {
	isValid: boolean;
	errorType: "insufficient_balance" | "no_quote" | "recipient_missing" | null;
	label: string;
	requiresRecipientSelection: boolean;
	showRecipientButton: boolean;
	disabled: boolean;
}

function isBalanceAvailable(balance?: string | bigint, amount?: string) {
	if (!balance || !amount) return null;

	const amountBn = BigInt(amount);
	const balanceBn = BigInt(balance);

	return amountBn <= balanceBn;
}

export const useActionButtonValidation = (): ValidationResult => {
	const {
		amounts,
		fromTokens: activeFromTokens,
		toTokens,
		receiver,
	} = useSelector((state: ReduxStateType) => state.quoteParams);

	const { data: activeRoute, isLoading, isRefetching } = useActiveRoute();
	const amount = amounts?.[0];
	const activeFromToken = activeFromTokens?.[0];
	const { balance } = useTokenBalance({
		token: activeFromToken,
		shouldFetch: Boolean(activeFromToken),
	});
	const isAbstractNetwork = useIsAbstractNetwork();

	// Balance validation
	const hasEnoughBalance = isBalanceAvailable(balance, amount);

	// Quote validation
	const hasValidQuote = Boolean(activeRoute);

	// Address validations
	const senderIsDummyAddress = isDummyAddress(activeRoute?.sender ?? "");
	const receiverIsDummyAddress = isDummyAddress(activeRoute?.receiver ?? "");

	// Recipient validation for abstract networks
	const requiresRecipientForAbstract = isAbstractNetwork && !receiver;

	// Recipient validation for cross-chain transfers
	let requiresRecipientForCrossChain = false;
	if (activeRoute && !senderIsDummyAddress) {
		const { isSingleNetwork } = getPairsNetworkFromRoute(activeRoute);
		requiresRecipientForCrossChain = !isSingleNetwork && receiverIsDummyAddress;
	}

	// Determine validation state
	let errorType: ValidationResult["errorType"] = null;
	let label = "Swap";
	let showRecipientButton = false;

	// Check for validation errors in priority order
	if (requiresRecipientForAbstract) {
		errorType = "recipient_missing";
		label = "Select Recipient Address";
		showRecipientButton = true;
	} else if (requiresRecipientForCrossChain) {
		errorType = "recipient_missing";
		label = "Select Recipient Wallet";
		showRecipientButton = true;
	} else if (hasValidQuote && hasEnoughBalance === false) {
		errorType = "insufficient_balance";
		label = "Insufficient Balance";
	} else if (!hasValidQuote && !(isLoading || isRefetching)) {
		if (amount && activeFromTokens?.length && toTokens?.length) {
			errorType = "no_quote";
			label = "No Quote Found";
		}
	}

	// Determine if button should be disabled
	const disabled =
		isLoading ||
		!hasValidQuote ||
		hasEnoughBalance === false ||
		isRefetching ||
		senderIsDummyAddress ||
		receiverIsDummyAddress ||
		requiresRecipientForAbstract;

	return {
		isValid: Boolean(activeRoute) && errorType === null,
		errorType,
		label,
		requiresRecipientSelection:
			requiresRecipientForAbstract || requiresRecipientForCrossChain,
		showRecipientButton,
		disabled,
	};
};
