import { memo, useEffect, useState } from "react";

import { RequestStatusEnum, type STATUS_CODE } from "@/types/index";
import { DoubleChevron, VerifiedCheck } from "@components/common/Icons";
import { MIcon } from "@components/common/MIcon";
import { useTheme } from "@hooks/useTheme";
import { getOrderStatus } from "@utils/getOrderStatus";

export const Stepper = ({
	statusCode,
	srcTimeStamp,
	destTimeStamp,
}: {
	statusCode: STATUS_CODE;
	srcTimeStamp?: number;
	destTimeStamp?: number;
}) => {
	const {
		inProgress,
		isCompleted,
		isExpired,
		isReverted,
		isRefunded,
		isRefunding,
	} = getOrderStatus(statusCode);
	if (isReverted) return null;

	return (
		<div className="bn-h-7 bn-w-full bn-relative">
			<ProgressBar statusCode={statusCode} />

			{!isCompleted && !(isExpired || isRefunded || isRefunding) && (
				<MovingDots right={inProgress} />
			)}

			<div className="bn-flex bn-justify-between bn-items-center bn-relative">
				<StepIcon icon="wallet" isSuccess />
				<StepIcon
					icon={isExpired ? "error" : "chevron"}
					isSuccess={inProgress || isCompleted || isRefunded || isRefunding}
					timeStamp={srcTimeStamp}
					isExpired={isExpired}
				/>
				<StepIcon
					icon={isRefunded || isRefunding ? "error" : "wallet"}
					isSuccess={isCompleted}
					timeStamp={destTimeStamp}
					isExpired={isRefunded || isRefunding}
				/>
			</div>
		</div>
	);
};

const StepIcon = memo(
	({
		icon,
		isSuccess = false,
		timeStamp,
		isExpired = false,
	}: {
		icon?: string;
		isSuccess?: boolean;
		timeStamp?: number;
		isExpired?: boolean;
	}) => {
		const theme = useTheme();
		const [height, setHeight] = useState<string>("0");

		useEffect(() => {
			const interval = setInterval(() => {
				if (timeStamp) {
					const timeNow = Date.now() / 1000; // in sec

					const timeStampMs = timeStamp;
					const diff = timeNow - timeStampMs;

					if (diff > 20) setHeight("60%");
					else if (diff > 15) setHeight("45%");
					else if (diff > 10) setHeight("30%");
					else if (diff > 5) setHeight("15%");
				}
			}, 5000);

			return () => {
				clearInterval(interval);
			};
		}, [timeStamp]);

		if (isSuccess) return <VerifiedCheck fill={theme.colors?.text?.accent3} />;

		if (icon) {
			return (
				<div className="bn-bg-layer-3 bn-w-7 bn-h-7 bn-rounded-full bn-flex bn-items-center bn-justify-center bn-relative bn-overflow-hidden">
					<div
						className="bn-size-full bn-bg-accent-3-text bn-absolute bn-left-0 bn-bottom-0 bn-w-full"
						style={{ height: height }}
					/>
					{icon === "chevron" ? (
						<DoubleChevron
							fill={theme.colors?.text?.primary}
							className="bn-relative"
						/>
					) : (
						<MIcon
							name={icon}
							classNames={`${
								isExpired ? "bn-text-accent-4" : "bn-text-secondary"
							} bn-text-[20px] bn-relative`}
						/>
					)}
				</div>
			);
		}
	},
);

function getProgressWidth(_statusCode: STATUS_CODE) {
	if (_statusCode < RequestStatusEnum.EXTRACTED) return 0;
	if (
		_statusCode < RequestStatusEnum.COMPLETED ||
		_statusCode === RequestStatusEnum.REFUNDED ||
		_statusCode === RequestStatusEnum.REFUND_PENDING
	)
		return "50%";

	if (
		_statusCode >= RequestStatusEnum.COMPLETED &&
		_statusCode < RequestStatusEnum.EXPIRED
	)
		return "100%";

	return 0;
}

const ProgressBar = ({ statusCode }: { statusCode: STATUS_CODE }) => {
	const { isExpired } = getOrderStatus(statusCode);

	return (
		<div className="bn-absolute bn-h-0.5 bn-w-[95%] bn-mx-auto bn-my-auto bn-inset-0">
			{/* track */}
			<div className="bn-h-px bn-border-0 bn-border-b-[2.2px] bn-border-dashed bn-border-subtle bn-w-full bn-absolute bn-my-auto bn-inset" />
			{isExpired && (
				<div className="bn-h-px bn-border-0 bn-border-b-[2.2px] bn-border-dashed bn-border-fail bn-w-[50%] bn-absolute bn-my-auto bn-inset" />
			)}

			{/* fill */}
			<div
				className="bn-absolute bn-left-0 bn-top-0 bn-h-full bn-w-[100px] bn-bg-accent-3-text"
				style={{ width: getProgressWidth(statusCode) }}
			/>
		</div>
	);
};

const MovingDots = ({ right = false }: { right?: boolean }) => {
	const style = `bn-w-1/2 bn-h-full bn-absolute bn-top-0 bn-overflow-hidden bn-flex bn-items-center bn-mx-2 ${
		right ? "bn-right-0" : "bn-left-0"
	}`;
	return (
		<div className={style}>
			<div className="bn-animate-slide-in-out bn-w-full bn-flex bn-justify-center">
				<div className="bn-w-[55px] bn-flex bn-justify-between">
					<div className="bn-size-[5px] bn-rounded-full bn-bg-accent-3-text" />
					<div className="bn-size-[5px] bn-rounded-full bn-bg-accent-3-text" />
					<div className="bn-size-[5px] bn-rounded-full bn-bg-accent-3-text" />
				</div>
			</div>
		</div>
	);
};
