import { useDispatch, useSelector } from "react-redux";

import {
	type FormattedQuoteResponse,
	ROUTE_TAG,
} from "@hooks/apis/common/quote/types";
import { useActiveRoute } from "@hooks/apis/common/quote/useActiveRoute";
import { useTopRoutes } from "@hooks/apis/common/quote/useTopRoutes";
import { isManualQuote } from "@hooks/apis/common/quote/utils";
import { setActiveRoute } from "@store/routesSlice";
import type { ReduxStateType } from "@store/types";
import { areBothRoutesSame } from "@utils/areBothRoutesSame";
import { onSelectRoute } from "../../../analytics/events";
import { TokenIcon } from "../TokenIcon";
import { NewRouteItem } from "./NewRouteItem";

const protocolIcons = [
	"https://bridgelogos.s3.ap-south-1.amazonaws.com/1inch.png",
	"https://movricons.s3.ap-south-1.amazonaws.com/CCTP.svg",
	"https://media.socket.tech/dexes/0x.svg",
	"https://media.socket.tech/bridges/across.png",
	"https://media.socket.tech/dexes/openocean.png",
	// "https://media.socket.tech/bridges/mayan-new-logo.svg",
];

export const RoutesWrapper = () => {
	const { auto, manual } = useTopRoutes();
	const { data: activeRoute, isLoading } = useActiveRoute();
	const dispatch = useDispatch();
	const routingMode = useSelector(
		(state: ReduxStateType) => state.settings.routingMode,
	);

	// Get routes based on routingMode
	const suggestedRoute =
		routingMode === "auto" ? auto.suggestedRoute : undefined;
	const maxOutputRoute =
		routingMode === "auto" ? auto.maxOutputRoute : manual.maxOutputRoute;
	const fastestRoute =
		routingMode === "auto" ? auto.fastestRoute : manual.fastestRoute;

	function setRoute(route: FormattedQuoteResponse) {
		dispatch(setActiveRoute(route));
	}

	const isSuggestedRouteActive =
		suggestedRoute && areBothRoutesSame(suggestedRoute, activeRoute);
	const isMaxOutputRouteActive =
		maxOutputRoute && areBothRoutesSame(maxOutputRoute, activeRoute);
	const isFastestRouteActive =
		fastestRoute && areBothRoutesSame(fastestRoute, activeRoute);

	const neitherRoutesSelected =
		!isSuggestedRouteActive && !isMaxOutputRouteActive && !isFastestRouteActive;

	const emitEvent = (route: FormattedQuoteResponse) => {
		const protocol = isManualQuote(route) ? route.protocol : undefined;

		onSelectRoute({
			provider_name: protocol?.dexDetails?.protocol.name ?? "",
			source_chain_id: route.primaryInput.token.chainId,
			destination_chain_id: route.primaryOutput.token.chainId,
			source_token_symbol: route.primaryInput.token.symbol,
			destination_token_symbol: route.primaryOutput.token.symbol,
			input_amount_usd: Number(route.primaryInput.amount),
			estimated_output_amount: Number(route.minOutput?.formattedAmount),
			estimated_time: route.estimatedFulfilTime,
			provider_best_output: Number(route.primaryOutput.amount),
			provider_name_best_output: protocol?.dexDetails?.amountOut,
			provider_best_time: route.estimatedFulfilTime,
		});
	};

	if (isLoading) return <LoadingSkeleton />;

	return (
		<div className="bn-mb-4 bn-mt-1.5 bn-w-full bn-space-y-1.5 bn-flex-col">
			{/* Show suggested route if available */}
			{suggestedRoute && (
				<NewRouteItem
					route={suggestedRoute}
					onClick={() => {
						setRoute(suggestedRoute);
						emitEvent(suggestedRoute);
					}}
					isActive={isSuggestedRouteActive || false}
					type={ROUTE_TAG.SUGGESTED}
					selectedRoute={activeRoute}
				/>
			)}
			{/* Show max output route if available */}
			{maxOutputRoute && (
				<NewRouteItem
					route={maxOutputRoute}
					onClick={() => {
						setRoute(maxOutputRoute);
						emitEvent(maxOutputRoute);
					}}
					isActive={isMaxOutputRouteActive || false}
					type={ROUTE_TAG.MAX_OUTPUT}
					selectedRoute={activeRoute}
				/>
			)}
			{/* Show fastest route if available */}
			{fastestRoute && (
				<NewRouteItem
					route={fastestRoute}
					onClick={() => {
						setRoute(fastestRoute);
						emitEvent(fastestRoute);
					}}
					isActive={isFastestRouteActive || false}
					type={ROUTE_TAG.FASTEST}
					selectedRoute={activeRoute}
				/>
			)}
			{/* Show alternative route if selected and not matching any top route */}
			{neitherRoutesSelected && activeRoute && (
				<NewRouteItem
					route={activeRoute}
					isActive={true}
					onClick={() => {}} // no action needed (as this item will be unmounted when one of the top routes is selected)
					type="DEFAULT"
					maxOutputRoute={maxOutputRoute}
				/>
			)}
		</div>
	);
};

const LoadingSkeleton = () => {
	return (
		<div className="bn-flex bn-flex-col bn-items-center bn-justify-center bn-py-2.5 bn-mt-4">
			<ProtocolIconsAnimation />
			<span className="bn-text-secondary bn-text-sm bn-font-medium bn-mt-1.5">
				Searching for the best route...
			</span>
		</div>
	);
};

const ProtocolIconsAnimation = () => {
	return (
		<div className="bn-flex bn-items-center">
			{protocolIcons.map((icon) => (
				<div key={icon} className="snake-icon">
					<TokenIcon
						url={icon}
						classNames="bn-w-5 bn-h-5 -bn-ml-1 bn-border bn-border-solid bn-border-strong"
					/>
				</div>
			))}
		</div>
	);
};
