import { useEffect, useMemo, useState } from "react";
import { useSelector } from "react-redux";

import { Amount } from "@components/common/Amount";
import { Balance } from "@components/common/Balance";
import { PriceImpact } from "@components/common/PriceImpact";
import { UsdValue } from "@components/common/UsdValue";
import { useActiveRoute } from "@hooks/apis/common/quote/useActiveRoute";
import { useTheme } from "@hooks/useTheme";
import { useTokenBalance } from "@hooks/useTokenBalance";
import type { ReduxStateType } from "@store/types";
import { adjustDecimals } from "@utils/adjustDecimals";
import { formatValue } from "@utils/formatValue";
import { getBorderRadius } from "@utils/getBorderRadius";
import { Refuel } from "../Refuel";
import { OutputToken } from "./OutputToken";

export const Output = () => {
	const { data: activeRoute, isLoading, isRefetching } = useActiveRoute();
	const [amount, setAmount] = useState<string>("");
	const locale = useSelector(
		(state: ReduxStateType) => state.settings.language,
	);

	useEffect(() => {
		const _output = activeRoute?.output[0];
		const _token = _output?.token;

		if (_output && _token) {
			const _outputFormatted = formatValue(_output.amount, _token?.decimals);
			setAmount(_outputFormatted);
		} else {
			setAmount("");
		}
	}, [activeRoute]);

	// to get token balance
	const selectedOutputTokens = useSelector(
		(state: ReduxStateType) => state.quoteParams.toTokens,
	);
	const activeToToken = useMemo(
		() => selectedOutputTokens?.[0],
		[selectedOutputTokens],
	);

	const { balance: tokenBalance, isLoading: isFetchingBalance } =
		useTokenBalance({
			token: activeToToken,
			query: { refetchOnMount: "always" },
		});

	const activeTokenBalanceFormatted = useMemo(() => {
		if (tokenBalance && activeToToken && !isFetchingBalance) {
			return formatValue(tokenBalance, activeToToken.decimals);
		}
		return null;
	}, [tokenBalance, activeToToken, isFetchingBalance]);

	// to get usd value
	const output = activeRoute?.output?.[0];
	const multiTokensAdded = activeRoute?.output?.length
		? activeRoute.output.length > 1
		: false;

	// Note: temporary
	const ratio = useSelector(
		(state: ReduxStateType) => state.quoteParams.outputRatio,
	);

	// amount with loader
	const amountContent = useMemo(() => {
		if (isLoading) return <Loader />;
		if (!multiTokensAdded) {
			return (
				<Amount
					amount={amount}
					setAmount={() => {}}
					refuel={activeRoute?.refuel?.output}
				/>
			);
		}
		return null;
	}, [isLoading, multiTokensAdded, amount, activeRoute?.refuel?.output]);

	// usd value with loader
	const usdValueContent = useMemo(() => {
		if (isLoading) {
			return (
				<span className="bn-text-sm bn-text-secondary bn-font-medium bn-leading-[16.8px]">
					Fetching the best guaranteed price...
				</span>
			);
		}

		if (output?.valueInUsd) {
			return (
				<UsdValue
					value={adjustDecimals({
						value: output.valueInUsd,
						decimals: 2,
						locale,
						showApproximateZero: true,
					})}
				/>
			);
		}

		return null;
	}, [isLoading, output?.valueInUsd, locale]);

	const balanceContent = useMemo(() => {
		if (isFetchingBalance) {
			return (
				<div className="bn-h-[22px] bn-w-[100px] bn-animate-pulse bn-bg-layer-3" />
			);
		}

		return <Balance balance={activeTokenBalanceFormatted ?? "0.00"} />;
	}, [isFetchingBalance, activeTokenBalanceFormatted]);

	// percentage bar or usd value & balance
	const barContent = useMemo(() => {
		return (
			<div className="bn-flex bn-items-center bn-w-full bn-h-5 bn-justify-between">
				<div className="bn-flex bn-items-center bn-space-x-1">
					<span className={`${isRefetching ? "bn-animate-pulse" : ""}`}>
						{usdValueContent}
					</span>
					<PriceImpact />
					{/* <RewardDisplay rebateDetails={activeRoute?.rebateDetails} /> */}
				</div>
				{balanceContent}
			</div>
		);
	}, [isRefetching, usdValueContent, balanceContent]);

	return (
		<div className="bn-flex bn-flex-col bn-gap-4">
			{/* Amount and Token */}
			<div className="bn-flex bn-items-center bn-justify-between">
				<span className={isRefetching ? "bn-animate-pulse" : ""}>
					{amountContent}
				</span>
				{multiTokensAdded && isLoading ? null : <OutputToken />}
			</div>

			{/* USD value and Balance with Percentage Bar*/}
			{barContent}

			<Refuel />
		</div>
	);
};

const Loader = () => {
	const theme = useTheme();
	return (
		<div
			className="bn-h-[19px] bn-bg-layer-3 bn-min-w-[140px] bn-animate-pulse"
			style={{ borderRadius: getBorderRadius(theme.borderRadius, 6) }}
		/>
	);
};
