import { useSelector } from "react-redux";

import type { Output } from "@/types/index";
import { MIcon } from "@components/common/MIcon";
import { TokensStacked } from "@components/common/TokensStacked";
import { Tooltip } from "@components/common/Tooltip";
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,
	} = routeData || {};

	const { isCompleted } = 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"
			style={{ borderRadius: getBorderRadius(theme.borderRadius, 8) }}
		>
			<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: "" }]}
					/>
					<TokenDetails
						chainName={mappedChainData?.[primaryOutput?.token.chainId]?.name ?? ""}
						tokenData={output}
						rtl
					/>
				</div>
			)}

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

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

			<div className="bn-flex bn-justify-between bn-items-center">
				<OrderId id={requestHash} />

				<div className="bn-flex bn-items-center">
					{isCompleted && !isNativeToken && (
						<AddTokenToWalletSmall token={primaryOutput.token} />
					)}
					<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,
}: { chainName: string; tokenData: Output[]; rtl?: boolean }) => {
	const locale = useSelector((state: ReduxStateType) => state.settings.language);
	// biome-ignore format:
	const style = `bn-flex bn-flex-col ${rtl ? 'bn-items-end' : 'bn-items-start'}`
	// biome-ignore format:
	const label = `${rtl ? "Min. Received on" : 'Sent from'} ${chainName}`

	function getAmount(endpoint: Output) {
		// Hanlidng both input and output amounts
		return endpoint?.fulfilledAmount || 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 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-2 bn-border-solid bn-border-primary" />
		</>
	);
};
