import { useSelector } from "react-redux";

import { useIsVeryLowSlippage } from "@components/Home/Warnings/SlippageWarning";
import { AddRecipientButton } from "@components/common/AddRecipientButton";
import { ExchangeRate } from "@components/common/ExchangeRate";
import { DoubleChevronRight, Stars } from "@components/common/Icons";
import { MIcon } from "@components/common/MIcon";
import { NoGasTag } from "@components/common/NoGasTag";
import { ReviewItem } from "@components/common/ReviewItem";
import { TokenIcon } from "@components/common/TokenIcon";
import { TokenIconWithAmount } from "@components/common/TokenIconWithLabel";
import { Tooltip } from "@components/common/Tooltip";
import { TransferType } from "@components/common/TransferType";
import type { AutoRefuel, ManualRefuel } from "@hooks/apis/common/quote/types";
import { useActiveRoute } from "@hooks/apis/common/quote/useActiveRoute";
import { isAutoQuote, isManualQuote } from "@hooks/apis/common/quote/useQuote";
import type { ReduxStateType } from "@store/types";
import { adjustDecimals } from "@utils/adjustDecimals";
import { calculatePriceImpact } from "@utils/calculatePriceImpact";
import { formatValue } from "@utils/formatValue";
import { isNativeToken } from "@utils/isNativeToken";
import { RefundWarning } from "./RefundWarning";

export const ReviewSection = ({ full = false }: { full?: boolean }) => {
	const locale = useSelector((state: ReduxStateType) => state.settings.language);
	const suggestedSlippage = useSelector(
		(state: ReduxStateType) => state.settings.dynamicSlippage,
	);
	const { data: activeRoute, isRefetching } = useActiveRoute();

	const {
		estimatedFulfilTime,
		primaryInput,
		slippage,
		srcToDestRate,
		destToSrcRate,
		minOutput,
		primaryOutput,
		refuel,
		receiver,
		isSwapRoute,
	} = activeRoute || {};

	const toToken = primaryOutput?.token;
	const rewards = isAutoQuote(activeRoute) ? activeRoute?.rewards : undefined;
	const formattedRewardAmount = rewards
		? formatValue(rewards.totalRewardAmount, rewards.token.decimals)
		: "";

	// biome-ignore format:
	const minReceivedLabel = `Min. ${toToken?.symbol}`;

	const isManualMode = isManualQuote(activeRoute);
	const priceImpact = calculatePriceImpact(
		primaryInput?.valueInUsd,
		primaryOutput?.valueInUsd,
	);
	return (
		<>
			<div className="bn-p-[14px]">
				{!isNativeToken(primaryInput?.token?.address) && full && (
					<ReviewItem label="Gas Fee:" isLoading={isManualMode && isRefetching}>
						{isManualMode && activeRoute?.totalGasFeesInUsd ? (
							<p>${adjustDecimals(activeRoute?.totalGasFeesInUsd, 2, locale)}</p>
						) : (
							<NoGasTag />
						)}
					</ReviewItem>
				)}

				{minOutput?.amount && (
					<ReviewItem
						label={minReceivedLabel}
						isLoading={isRefetching}
						key={toToken?.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={toToken?.logoURI || ""} classNames="bn-size-4" />
							<Tooltip content={minOutput.formattedAmount}>
								<span>{adjustDecimals(minOutput.formattedAmount, 3, locale)}</span>
							</Tooltip>
							{minOutput?.valueInUsd && (
								<span
									// biome-ignore format:
									className={`${
										priceImpact ? "bn-text-accent-4" : "bn-text-secondary"
									}`}
								>
									(${adjustDecimals(minOutput.valueInUsd, 2, locale)})
								</span>
							)}
						</div>
					</ReviewItem>
				)}

				{isAutoQuote(activeRoute) && activeRoute?.rewards && (
					<ReviewItem label="Est. Reward:">
						<div className="bn-flex bn-items-center bn-text-accent-3">
							<Stars className="bn-text-accent-3 bn-mr-1" />
							<p>
								+{adjustDecimals(formattedRewardAmount, 2, locale)} {rewards?.token.symbol}
							</p>
						</div>
					</ReviewItem>
				)}

				{Boolean(srcToDestRate && destToSrcRate) && (
					<ReviewItem label="Exchange Rate:" isLoading={isRefetching}>
						<ExchangeRate />
					</ReviewItem>
				)}

				{/* {formattedOpAmount && (
					<ReviewItem label="Est. Rewards:">
						<div className="bn-text-accent-3 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={isManualMode ? "Swap Slippage:" : "Slippage:"}
					isLoading={isRefetching}
				>
					<SlippageDisplay
						autoSlippage={suggestedSlippage}
						slippage={slippage ?? undefined}
					/>
				</ReviewItem>

				{isSwapRoute && isManualQuote(activeRoute) ? (
					<ReviewItem label="Protocol" isLoading={isRefetching}>
						<TransferType
							type={isManualMode ? "manual" : "auto"}
							time={estimatedFulfilTime}
							protocol={isManualMode ? activeRoute?.protocol : undefined}
						/>
					</ReviewItem>
				) : (
					<ReviewItem label="Est. Swap Time:" isLoading={isRefetching}>
						<TransferType
							type={isManualMode ? "manual" : "auto"}
							time={estimatedFulfilTime}
							protocol={isManualMode ? activeRoute?.protocol : undefined}
						/>
					</ReviewItem>
				)}

				{refuel && (
					<ReviewItem label="Refuel:" isLoading={isRefetching}>
						<RefuelInfo refuel={refuel} />
					</ReviewItem>
				)}

				<ReviewItem label="Recipient Address:">
					<AddRecipientButton receiver={receiver} />
				</ReviewItem>
			</div>

			<RefundWarning />
		</>
	);
};

const SlippageDisplay = ({
	autoSlippage,
	slippage,
}: {
	autoSlippage: boolean;
	slippage?: number;
}) => {
	const isVeryLowSlippage = useIsVeryLowSlippage();

	return (
		<span className="bn-font-medium bn-flex bn-items-center bn-space-x-1">
			{autoSlippage ? (
				<span>
					<span className="bn-aeonik-font bn-text-primary">{slippage}% ~ </span>
					<span className="bn-text-secondary">Suggested</span>
				</span>
			) : slippage ? (
				<span className="bn-flex bn-items-center bn-justify-end bn-space-x-1 bn-w-[200px]">
					{isVeryLowSlippage && (
						<Tooltip content="Using a lower slippage than suggested might prevent your swap from going through.">
							<MIcon name="warning" classNames="bn-text-accent-4 bn-text-base" />
						</Tooltip>
					)}
					<span>{slippage}%</span>
				</span>
			) : null}
		</span>
	);
};

export const RefuelInfo = ({
	refuel,
}: {
	refuel: AutoRefuel | ManualRefuel;
}) => {
	if ("input" in refuel && refuel.input) {
		return (
			<div className="bn-flex bn-items-center bn-space-x-2">
				<TokenIconWithAmount amount={refuel.input.amount} token={refuel.input.token} />
				<DoubleChevronRight />
				<TokenIconWithAmount
					amount={refuel.output.amount}
					token={refuel.output.token}
				/>
			</div>
		);
	}

	return (
		<TokenIconWithAmount
			amount={refuel.output.amount}
			token={refuel.output.token}
		/>
	);
};
