import React from "react";
import { useDispatch, useSelector } from "react-redux";

import { useConfig } from "@hooks/useConfig";
import { useTokenBalance } from "@hooks/useTokenBalance";
import type { ReduxStateType } from "@store/types";
import { NATIVE_TOKEN_ADDRESS } from "@utils/constants";
import { isWrapUnwrapCase } from "@utils/isWrapUnwrapCase";
import { useFetchQuote } from "../hooks/apis/useFetchQuote";
import { ScreenTab, setScreenTab } from "../store/globalSlice";
import { Button } from "./common/Button";

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

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

	return amountBn <= balanceBn;
}

export const ActionButton = () => {
	const dispatch = useDispatch();
	const bungeeConfig = useConfig();
	const activeFromTokens = useSelector(
		(state: ReduxStateType) => state.quoteParams.fromTokens,
	);
	const amounts = useSelector(
		(state: ReduxStateType) => state.quoteParams.amounts,
	);
	const { data: quote, isLoading, noData, isRefetching } = useFetchQuote();

	const amount = amounts?.[0];

	const { balance } = useTokenBalance({ token: activeFromTokens?.[0] });
	const _isBalanceAvailable = isBalanceAvailable(balance, amount);

	// note: adding temporary max cap
	function amountExceedsCap() {
		if (quote && bungeeConfig.maxCap) {
			// Setting it to false for same chain swaps
			if (quote.primaryInput.chainId === quote.primaryOutput.chainId) return false;

			const _valInUsd = quote?.input?.[0]?.valueInUsd;
			if (_valInUsd) return _valInUsd > bungeeConfig.maxCap;
			return false;
		}
		return false;
	}

	const getLabel = () => {
		if (amountExceedsCap()) return "Please lower the amount";
		if (!_isBalanceAvailable && Boolean(quote)) return "Insufficient Balance";
		if (noData) return "No Quote Found";

		const isNativeToken =
			quote?.primaryInput?.token?.address?.toLowerCase() === NATIVE_TOKEN_ADDRESS;
		if (isWrapUnwrapCase(quote)) {
			if (isNativeToken) return "Wrap";
			return "Unwrap";
		}
		return "Swap";
	};

	function openReview() {
		dispatch(setScreenTab(ScreenTab.REVIEW));
	}

	return (
		<Button
			label={getLabel()}
			onClick={openReview}
			classNames="bn-mt-4"
			disabled={
				isLoading ||
				!quote ||
				!_isBalanceAvailable ||
				amountExceedsCap() ||
				isRefetching
			}
		/>
	);
};
