import { useSelector } from "react-redux";

import type { Output, STATUS_CODE } from "@/types/index";
import { MIcon } from "@components/common/MIcon";
import { TokensStacked } from "@components/common/TokensStacked";
import { Tooltip } from "@components/common/Tooltip";
import { WarnBar } from "@components/common/WarnBar";
import type { OrderData } from "@hooks/apis/auto/useAutoHistory";
import { useMappedChainData } from "@hooks/useMappedChainData";
import { useTheme } from "@hooks/useTheme";
import type { ReduxStateType } from "@store/types";
import { adjustDecimals } from "@utils/adjustDecimals";
import { NATIVE_TOKEN_ADDRESS } from "@utils/constants";
import { formatValue } from "@utils/formatValue";
import { getBorderRadius } from "@utils/getBorderRadius";
import { getOrderStatus } from "@utils/getOrderStatus";
import { shortenAddress } from "@utils/shortenAddress";
import { AddTokenToWalletSmall } from "./AddTokenToWallet";
import { OrderId } from "./OrderId";
import { Stepper } from "./Stepper";

export const InfoSection = ({
	routeData,
	openFaq,
	openShare,
}: {
	routeData: OrderData;
	openFaq: () => void;
	openShare: () => void;
}) => {
	const theme = useTheme();
	const mappedChainData = useMappedChainData();
	const {
		statusCode,
		requestHash,
		primaryInput,
		primaryOutput,
		output,
		srcTimestamp,
		destTimestamp,
		receiver,
		sender,
		routingMode,
		isSwapRoute,
	} = routeData || {};

	const { isCompleted, isExpired, isReverted } = getOrderStatus(statusCode);
	const isNativeToken =
		primaryOutput?.token?.address?.toLowerCase() === NATIVE_TOKEN_ADDRESS;

	const differentRecipientAddress = (() => {
		if (receiver && sender) {
			return receiver.toLowerCase() !== sender.toLowerCase();
		}

		return false;
	})();

	return (
		<div
			className="bn-bg-layer-2 bn-px-3 bn-py-2 bn-overflow-hidden"
			style={{ borderRadius: getBorderRadius(theme.borderRadius, 8) }}
		>
			{isExpired && (
				<WarnBar
					title="Recommended: Use Suggested Slippage"
					subtitle="We will find the best slippage for a successful swap."
					icon="settings"
					classNames="-bn-mt-2 -bn-mx-3 bn-mb-2"
				/>
			)}
			<Stepper
				statusCode={statusCode}
				destTimeStamp={destTimestamp}
				srcTimeStamp={srcTimestamp}
			/>

			{/* @fixme: remove this later */}
			{primaryInput && (
				<div className="bn-mt-[14px] bn-flex bn-justify-between bn-items-center">
					<TokenDetails
						chainName={mappedChainData?.[primaryInput?.token.chainId]?.name ?? ""}
						tokenData={[{ ...primaryInput, minAmountOut: "" }]}
						statusCode={statusCode}
					/>
					<TokenDetails
						chainName={mappedChainData?.[primaryOutput?.token.chainId]?.name ?? ""}
						tokenData={output}
						statusCode={statusCode}
						rtl
					/>
				</div>
			)}

			<div className="bn-my-[14px] bn-border-0 bn-border-b bn-border-solid bn-border-subtle" />

			{differentRecipientAddress && <RecipientAddress address={receiver} />}

			<div className="bn-flex bn-justify-between bn-items-center">
				<OrderId
					id={requestHash}
					chainId={primaryInput.token.chainId}
					openChainExplorer={routingMode === "manual" && isSwapRoute} // socketscan does not support swap routes for manual
				/>

				<div className="bn-flex bn-items-center">
					{isCompleted && !isNativeToken && (
						<AddTokenToWalletSmall token={primaryOutput.token} />
					)}
					{!isExpired && !isReverted && <HelperButton icon="share" onClick={openShare} />}
					<HelperButton icon="question_mark" onClick={openFaq} />
				</div>
			</div>
		</div>
	);
};

const HelperButton = ({
	icon,
	onClick,
}: { icon: string; onClick: () => void }) => {
	return (
		<button
			type="button"
			onClick={onClick}
			className="bn-w-9 bn-h-9 bn-rounded-full bn-ml-2 bn-bg-layer-3 bn-border-none bn-text-primary bn-inline-flex bn-justify-center bn-items-center bn-cursor-pointer"
		>
			<MIcon name={icon} classNames="bn-text-xl" />
		</button>
	);
};

const TokenDetails = ({
	chainName,
	tokenData,
	rtl = false,
	statusCode,
}: {
	chainName: string;
	tokenData: Output[];
	rtl?: boolean;
	statusCode: STATUS_CODE;
}) => {
	const locale = useSelector((state: ReduxStateType) => state.settings.language);
	const { isCompleted } = getOrderStatus(statusCode);

	// biome-ignore format:
	const style = `bn-flex bn-flex-col ${rtl ? 'bn-items-end' : 'bn-items-start'}`
	// biome-ignore format:
	const label = `${rtl ? isCompleted ? "Received on" : "Min. Received on" : 'Sent from'} ${chainName}`

	function getAmount(endpoint: Output) {
		// Hanlidng both input and output amounts
		if (isCompleted)
			return endpoint?.fulfilledAmount || endpoint?.amount || endpoint?.minAmountOut;
		return endpoint?.minAmountOut || endpoint?.amount;
	}

	return (
		<div className={style}>
			<p className="bn-text-[13px] bn-font-normal bn-text-secondary bn-mb-1.5">
				{label}
			</p>
			{/* biome-ignore format: */}
			<div className={`bn-flex bn-items-center bn-space-x-1 ${rtl ? 'bn-flex-row-reverse bn-space-x-reverse': 'bn-flex-row'}`}>
				<div className="bn-size-fit bn-flex bn-items-center">
					<TokensStacked endpoints={tokenData} small/>
				</div>

				<div className="bn-flex bn-items-center bn-space-x-2">
					{tokenData?.map((endpoint, index) => {
						const amount = formatValue(
							getAmount(endpoint),
							endpoint.token.decimals,
						);
						return (
							<div
								className="bn-text-primary bn-font-medium bn-text-[15px] bn-aeonik-font"
								// biome-ignore format:
								key={`${endpoint.amount}-${index}`}
							>
								{index !== 0 && "&"}{" "}
								<Tooltip content={amount}>
									<span>{adjustDecimals(amount, 2, locale)}</span>
								</Tooltip>{" "}
								{endpoint.token.symbol}
							</div>
						);
					})}
				</div>
			</div>
		</div>
	);
};

const RecipientAddress = ({ address }: { address: string }) => {
	return (
		<>
			<div className="bn-flex bn-text-sm bn-items-center bn-space-x-1">
				<div className="bn-flex bn-items-center bn-size-5 bn-justify-center bn-rounded-full bn-bg-layer-3">
					<MIcon name="wallet" classNames="bn-text-accent-1 bn-text-sm" />
				</div>
				<span className="bn-text-secondary">Recipient Address: </span>
				<span className="bn-text-primary bn-font-medium bn-aeonik-font">
					{shortenAddress(address, 10)}
				</span>
			</div>
			<div className="bn-my-[14px] bn-border-0 bn-border-b bn-border-solid bn-border-subtle" />
		</>
	);
};
