import { useSelector } from "react-redux";

import {
	type Output,
	RequestStatusEnum,
	type STATUS_CODE,
} from "@/types/index";
import { OrderId } from "@components/InFlight/layout/OrderId";
import { MIcon } from "@components/common/MIcon";
import { TokenDetails } from "@components/common/TokenDetails";
import type { OrderData } from "@hooks/apis/auto/useAutoHistory";
import { useTheme } from "@hooks/useTheme";
import type { ReduxStateType } from "@store/types";
import { formatValue } from "@utils/formatValue";
import { getBorderRadius } from "@utils/getBorderRadius";
import { getOrderStatus } from "@utils/getOrderStatus";

export const HistoryItem = ({
	data,
	onClick,
}: { data: OrderData; onClick: () => void }) => {
	const theme = useTheme();
	const locale = useSelector((state: ReduxStateType) => state.settings.language);
	const {
		statusCode,
		primaryInput,
		primaryOutput,
		orderTimestamp,
		requestHash,
		routingMode,
		isSwapRoute,
	} = data;

	const srcToken = primaryInput?.token;
	const formattedFromAmount = formatValue(
		primaryInput.amount ?? "0",
		srcToken?.decimals,
	);

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

	const destToken = primaryOutput?.token;
	const formattedToAmount = formatValue(
		getAmount(primaryOutput),
		destToken?.decimals,
	);

	// auto and manual returns different types, hence converting
	const timestamp =
		typeof orderTimestamp === "number"
			? convertTimestampToDate(orderTimestamp)
			: orderTimestamp;

	const date = new Date(timestamp);
	const options: Intl.DateTimeFormatOptions = {
		day: "numeric",
		month: "short",
		year: "2-digit",
	};

	// @fixme: type error
	// biome-ignore format:
	const dateString = `${date.toLocaleDateString(
		locale,
		options
	)}, ${date.toLocaleTimeString(
		locale,
		{
			hour: "2-digit",
			minute: "2-digit",
	})}`;

	const disabled =
		statusCode === RequestStatusEnum.EXPIRED ||
		statusCode === RequestStatusEnum.REVERTED;

	return (
		<div
			// biome-ignore lint/a11y/useSemanticElements: <explanation>
			role="button"
			tabIndex={0}
			aria-disabled={disabled}
			onClick={!disabled ? onClick : undefined}
			onKeyUp={!disabled ? (e) => e.key === "Enter" && onClick?.() : undefined}
			className="bn-w-full bn-bg-layer-2 bn-border-0 bn-p-4 bn-cursor-pointer bn-space-y-2.5"
			style={{ borderRadius: getBorderRadius(theme.borderRadius, 8) }}
		>
			<div className="bn-flex bn-items-center bn-justify-between">
				<TokenDetails
					token={primaryInput?.token}
					amount={formattedFromAmount}
					showTokens
				/>
				<TokenDetails
					token={primaryOutput?.token}
					amount={formattedToAmount}
					showTokens
					rtl
				/>
			</div>

			<div className="bn-flex bn-items-center bn-justify-between bn-border-0 bn-border-t bn-border-solid bn-border-subtle bn-pt-2.5">
				<OrderId
					id={requestHash}
					showIcon={false}
					chainId={primaryInput.token.chainId}
					openChainExplorer={routingMode === "manual" && isSwapRoute}
				/>
				<div className="bn-flex bn-flex-col bn-items-end">
					<span className="bn-text-secondary bn-text-sm bn-text-normal bn-text-right bn-mb-1">
						{dateString}
					</span>
					<Status statusCode={statusCode} />
				</div>
			</div>
		</div>
	);
};

function getStatusLabel(statusCode: STATUS_CODE) {
	const { isCompleted, isExpired, isReverted } = getOrderStatus(statusCode);

	if (isReverted) return "reverted";
	if (isExpired) return "expired";
	if (isCompleted) return "completed";
	return "in progress";
}

function getIconName(statusCode: STATUS_CODE) {
	const { isExpired, isCompleted, isReverted } = getOrderStatus(statusCode);

	if (isExpired || isReverted) return "error";
	if (isCompleted) return "verified";
	return "donut_large";
}

function getIconColor(statusCode: STATUS_CODE) {
	const { isCompleted, isExpired, isReverted } = getOrderStatus(statusCode);

	if (isExpired || isReverted) return "bn-text-accent-4";
	if (isCompleted) return "bn-text-accent-3";
	return "bn-text-accent-2";
}

const Status = ({ statusCode }: { statusCode: STATUS_CODE }) => {
	const { isPending } = getOrderStatus(statusCode);
	const color = getIconColor(statusCode);

	// biome-ignore format:
	const style = `bn-flex bn-items-center bn-space-x-1 ${color}`

	return (
		<div className={style}>
			{/* biome-ignore format: */}
			<MIcon name={getIconName(statusCode)} classNames={`bn-text-base ${color} ${isPending ? 'bn-animate-spin' : ''}`} />
			<span className="bn-capitalize bn-font-medium">
				{getStatusLabel(statusCode)}
			</span>
		</div>
	);
};

function convertTimestampToDate(timestamp: number) {
	// Convert seconds to milliseconds
	const date = new Date(timestamp * 1000);
	return date.toString();
}
