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

import { Boosters } from "@components/Boosters";
import { BoosterProvider } from "@components/Boosters/BoosterProvider";
import { AddRecipientButton } from "@components/common/AddRecipientButton";
import { Stars } from "@components/common/Icons";
import { NoGasTag } from "@components/common/NoGasTag";
import { ReviewItem } from "@components/common/ReviewItem";
import { TokenIcon } from "@components/common/TokenIcon";
import { Tooltip } from "@components/common/Tooltip";
import { TransferType } from "@components/common/TransferType";
import { useFetchQuote } from "@hooks/apis/useFetchQuote";
import type { ReduxStateType } from "@store/types";
import { adjustDecimals } from "@utils/adjustDecimals";
import { formatValue } from "@utils/formatValue";
import { intlNumberFormatter } from "@utils/intlNumberFormatter";
import { isNativeToken } from "@utils/isNativeToken";
import { toFixedSafe } from "@utils/toFixedSafe";

export const ReviewSection = ({ full = false }: { full?: boolean }) => {
	const locale = useSelector((state: ReduxStateType) => state.settings.language);
	const autoSlippage = useSelector(
		(state: ReduxStateType) => state.settings.autoSlippage,
	);
	const { data: quoteData, isRefetching } = useFetchQuote();

	const { output, estimatedFulfilTime, primaryInput, rebateDetails, slippage } =
		quoteData || {};

	const intlFormatter = intlNumberFormatter(locale);

	const formattedOpAmount = useMemo(() => {
		if (rebateDetails?.amount !== "0" && rebateDetails?.token) {
			return formatValue(rebateDetails.amount, rebateDetails.token.decimals);
		}
	}, [rebateDetails]);

	return (
		<>
			{!isNativeToken(primaryInput?.token?.address) && (
				<ReviewItem label="Gas Fee:">
					<NoGasTag />
				</ReviewItem>
			)}

			{output?.map((endpoint) => {
				const token = endpoint.token;
				const amount = endpoint?.slippageAdjustedAmount ?? endpoint.amount;
				// biome-ignore format:
				const label = `Min. ${token.symbol} Received:`;
				const formattedValue = formatValue(amount, token.decimals);

				const usdValue = toFixedSafe(
					(endpoint.valueInUsd ?? 0) -
						((endpoint.valueInUsd ?? 0) * Number(slippage)) / 100,
				);
				return (
					<ReviewItem label={label} isLoading={isRefetching} key={token.address}>
						<div className="bn-text-primary bn-text-sm bn-font-medium bn-aeonik-font bn-flex bn-items-center bn-space-x-1">
							<TokenIcon url={token?.logoURI} classNames="bn-size-4" />
							<Tooltip content={formattedValue}>
								<span>{adjustDecimals(formattedValue, 3, locale)}</span>
							</Tooltip>
							{endpoint?.valueInUsd && (
								<span className="bn-text-secondary">
									(${intlFormatter.format(Number(usdValue))})
								</span>
							)}
						</div>
					</ReviewItem>
				);
			})}

			{formattedOpAmount && (
				<ReviewItem label="Est. Rewards:">
					<div className="bn-text-success bn-text-sm bn-font-medium bn-aeonik-font bn-flex bn-items-center bn-space-x-1">
						<Stars />
						<Tooltip content={formattedOpAmount}>
							<span>
								+ {adjustDecimals(formattedOpAmount, 3, locale)} {rebateDetails.token.symbol}
							</span>
						</Tooltip>
					</div>
				</ReviewItem>
			)}

			<ReviewItem label="Slippage:" isLoading={isRefetching}>
				<SlippageDisplay autoSlippage={autoSlippage} slippage={slippage} />
			</ReviewItem>

			{full && (
				<ReviewItem label="Est. Swap Time:" isLoading={isRefetching}>
					<TransferType time={estimatedFulfilTime} />
				</ReviewItem>
			)}

			<ReviewItem label="Recipient Address:">
				<AddRecipientButton />
			</ReviewItem>

			{/* {full && (
				<BoosterProvider>
					<Boosters />
				</BoosterProvider>
			)} */}
		</>
	);
};

const SlippageDisplay = ({
	autoSlippage,
	slippage,
}: {
	autoSlippage: boolean;
	slippage: string;
}) => (
	<span className="bn-font-medium bn-flex bn-items-center bn-space-x-1">
		{autoSlippage ? (
			<span>
				<span className="bn-text-white">Auto</span> (
				<span className="bn-aeonik-font">{slippage}%</span>)
			</span>
		) : (
			<span>{slippage}%</span>
		)}
	</span>
);
