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

import {
	CheckApproval,
	useIsApprovalRequired,
} from "@components/Review/Approval/CheckApproval";
import { AutoFlow } from "@components/Review/Auto";
import { SendNativeTransaction } from "@components/Review/Auto/SendNativeTransaction";
import { ManualFlow } from "@components/Review/Manual";
import { Button } from "@components/common/Button";
import { useActiveRoute } from "@hooks/apis/common/quote/useActiveRoute";
import { isAutoQuote } from "@hooks/apis/common/quote/utils";
import { useAccounts } from "@hooks/useAccounts";
import { useActionButtonValidation } from "@hooks/useActionButtonValidation";
import { useConfig } from "@hooks/useConfig";
import { useWalletCapabilities } from "@hooks/useWalletCapabilities";
import { setApprovalData } from "@store/approvalSlice";
import { toggleRecipientModal } from "@store/globalSlice";
import type { ReduxStateType } from "@store/types";
import { isSolana } from "@utils/isSolana";
import { isWrapUnwrapCase } from "@utils/isWrapUnwrapCase";

export const ActionButton = ({ disabled }: { disabled?: boolean }) => {
	const dispatch = useDispatch();
	const { eventHandlers } = useConfig();
	const { data: activeRoute } = useActiveRoute();
	const validation = useActionButtonValidation();
	const isApprovalGiven = useSelector(
		(state: ReduxStateType) => state.approval.isApprovalGiven,
	);
	const { smartBatching } = useSelector(
		(state: ReduxStateType) => state.settings,
	);
	const fromChainId = useSelector(
		(state: ReduxStateType) => state.quoteParams.fromChainId,
	);
	const { isAnyConnected } = useAccounts();
	const setApprovalState = useCallback(
		(value: boolean) => {
			dispatch(
				setApprovalData({
					isApprovalGiven: value,
				}),
			);
		},
		[dispatch],
	);

	const isApprovalRequired = useIsApprovalRequired();

	const { supportsAtomicBatching, isLoading } = useWalletCapabilities(
		activeRoute?.primaryInput?.token?.chainId,
	);

	const enableBatching = useMemo(
		() => Boolean(supportsAtomicBatching && smartBatching),
		[supportsAtomicBatching, smartBatching],
	);

	// Auto-approve for batching
	useEffect(() => {
		setApprovalState(!isLoading && enableBatching);
	}, [enableBatching, setApprovalState, isLoading]);

	// Reset approval state when switching between manual and auto routes
	useEffect(() => {
		if (activeRoute && !enableBatching) {
			setApprovalState(false);
		}
	}, [activeRoute, enableBatching, setApprovalState]);

	const isSolanaTx = isSolana(activeRoute?.primaryInput?.token?.chainId ?? 0);
	const needsApproval =
		!enableBatching && isApprovalRequired && !isApprovalGiven && !isSolanaTx;
	const isWrapUnwrap =
		activeRoute && isWrapUnwrapCase(activeRoute) && isAutoQuote(activeRoute);

	// Helper function to wrap content with consistent styling
	const withMargin = (content: ReactNode) => {
		return <div className="bn-mt-4">{content}</div>;
	};

	const isFlowDisabled = isLoading || validation.disabled || disabled;

	// Recipient selection
	if (validation.showRecipientButton) {
		return withMargin(
			<Button
				label={validation.label}
				onClick={() => dispatch(toggleRecipientModal(true))}
				disabled={isFlowDisabled}
				id={
					validation.errorType === "recipient_missing" &&
					validation.label.includes("Wallet")
						? "select-recipient-wallet-homescreen-btn"
						: undefined
				}
			/>,
		);
	}

	// Connect wallet button
	if (!isAnyConnected) {
		return withMargin(
			<Button
				label="Connect Wallet"
				onClick={() =>
					eventHandlers?.onOpenWalletConnect?.(
						fromChainId !== undefined && isSolana(fromChainId ?? 0)
							? "solana"
							: "eip155",
					)
				}
			/>,
		);
	}

	// Valid route cases
	if (activeRoute && validation.isValid) {
		// Native wrap/unwrap
		if (isWrapUnwrap) {
			return withMargin(
				<SendNativeTransaction
					quoteData={activeRoute}
					disabled={isFlowDisabled}
				/>,
			);
		}

		// Approval required
		if (needsApproval) {
			return withMargin(
				<CheckApproval
					setIsApprovalGiven={setApprovalState}
					disabled={isFlowDisabled}
				/>,
			);
		}

		// Execute transaction
		return withMargin(
			isAutoQuote(activeRoute) ? (
				<AutoFlow data={activeRoute} disabled={isFlowDisabled} />
			) : (
				<ManualFlow data={activeRoute} disabled={isFlowDisabled} />
			),
		);
	}

	// Fallback button
	return withMargin(
		<Button
			label={validation.label}
			onClick={() => {}}
			disabled={isFlowDisabled}
			id="swap-homescreen-btn"
		/>,
	);
};
