import { Trans } from "@lingui/react/macro";
import { plumeMainnet, sei } from "@reown/appkit/networks";
import { useEffect, useMemo, useRef, useState } from "react";

import { MIcon } from "@components/common/MIcon";
import { AnimatePresence, motion } from "framer-motion";
import { useTheme } from "../../hooks/useTheme";
import type { Chain } from "../../store/globalSlice";
import { getBorderRadius } from "../../utils/getBorderRadius";
import { FourSquareIcon, NetworkButton } from "./NetworkButton";

export const NetworkList = ({
	chains,
	activeNetwork,
	setActiveNetwork,
	showAllNetworksBtn = false,
}: {
	chains: Chain[];
	activeNetwork: number | "all";
	setActiveNetwork: (value: number | "all") => void;
	showAllNetworksBtn?: boolean;
}) => {
	const theme = useTheme();
	const ref = useRef<HTMLDivElement>(null);
	const allNetworksBtnRef = useRef<HTMLDivElement>(null);

	// default width of the networks list container
	const DEFAULT_WIDTH = 388;
	// width available for displaying network icons
	const [width, setWidth] = useState<number>(DEFAULT_WIDTH);

	const [showDropdown, setShowDropdown] = useState(false);

	useEffect(() => {
		const containerWidth = ref?.current?.clientWidth;
		const allNetworksBtnWidth = allNetworksBtnRef?.current?.clientWidth;
		let _width = 0;

		if (containerWidth) {
			if (showAllNetworksBtn && allNetworksBtnWidth) {
				// 32 is the x padding
				_width = containerWidth - 32 - allNetworksBtnWidth;
			} else {
				_width = containerWidth - 32;
			}

			setWidth(_width);
		}
	}, [showAllNetworksBtn]);

	// network button width (including right margin of 6px)
	const NETWORK_BUTTON_WIDTH = 43.8;

	// number of network buttons that can be fit without overflow
	// subtracting one to accommodate dropdown button
	const numberOfItems = Math.floor(width / NETWORK_BUTTON_WIDTH) - 1;

	// networks shown upfront
	const [priorityItems, restItems] = useMemo(() => {
		const priorityChains = chains?.slice(0, numberOfItems);

		// networks hidden in the overflow dropdown
		const restItems =
			chains && priorityChains && chains?.length > priorityChains?.length
				? chains?.slice(-(chains.length - numberOfItems))
				: null;

		// to handle the UI when the network from the overflow is selected
		const activeNetworkOverflowed =
			activeNetwork !== "all" &&
			restItems?.filter((item) => item.chainId === activeNetwork)?.[0];

		// replaceing the last network from the priority list w/ active network when the dropdown is closed
		if (!showDropdown && activeNetworkOverflowed) {
			priorityChains?.pop();
			priorityChains?.push(activeNetworkOverflowed);
		}
		return [priorityChains, restItems];
	}, [chains, activeNetwork, showDropdown, numberOfItems]);

	const newNetworks = [sei.id, plumeMainnet.id, 999, 747474];

	return (
		<div className="bn-mt-[15px] bn-space-y-1.5 bn-mb-4">
			<div className="bn-flex bn-px-4 bn-relative bn-space-x-1.5" ref={ref}>
				{showAllNetworksBtn && (
					<div ref={allNetworksBtnRef} className="bn-w-fit">
						<AllNetworks
							onClick={() => setActiveNetwork("all")}
							active={activeNetwork === "all"}
							numberOfChains={chains.length}
						/>
					</div>
				)}
				{priorityItems?.map((item) => {
					return (
						<NetworkButton
							url={item.icon}
							onClick={() => setActiveNetwork(item.chainId)}
							key={item.chainId}
							active={activeNetwork === item.chainId}
							networkName={item.name}
							newlyAdded={newNetworks.includes(item.chainId)}
						/>
					);
				})}

				{restItems?.length && (
					<button
						type="button"
						className="bn-cursor-pointer bn-flex bn-items-center bn-justify-between bn-bg-layer-2 bn-shrink-0 bn-border-none bn-text-secondary sm:bn-pr-2.5 bn-px-1.5 bn-py-1.5 bn-flex-nowrap bn-overflow-hidden sm:bn-w-[82px] bn-h-[37.8px] bn-relative"
						style={{ borderRadius: getBorderRadius(theme.borderRadius, 8) }}
						onClick={() => setShowDropdown(!showDropdown)}
					>
						<FourSquareIcon />
						<MIcon name={showDropdown ? "keyboard_arrow_up" : "keyboard_arrow_down"} />
					</button>
				)}
			</div>

			<AnimatePresence>
				{showDropdown && (
					<motion.div
						className="bn-flex bn-flex-wrap bn-gap-1.5 bn-px-4"
						initial={{ opacity: 0, y: -10 }}
						animate={{ opacity: 1, y: 0 }}
						exit={{ opacity: 0, height: 0 }}
					>
						{restItems?.map((item) => {
							return (
								<NetworkButton
									url={item.icon}
									onClick={() => setActiveNetwork(item.chainId)}
									key={item.chainId}
									active={activeNetwork === item.chainId}
									networkName={item.name}
									newlyAdded={newNetworks.includes(item.chainId)}
								/>
							);
						})}
					</motion.div>
				)}
			</AnimatePresence>
		</div>
	);
};

const AllNetworks = ({
	onClick,
	active,
	numberOfChains,
}: {
	onClick: () => void;
	active: boolean;
	numberOfChains: number;
}) => {
	const theme = useTheme();

	return (
		<button
			type="button"
			onClick={onClick}
			// biome-ignore format:
			className={`bn-border bn-border-solid bn-whitespace-nowrap bn-flex bn-items-center bn-px-4 bn-h-[38px] bn-w-[81px] bn-text-[15px] bn-leading-[18px] bn-cursor-pointer bn-font-medium ${
        active
          ? "bn-bg-accent-1 bn-text-accent-1 bn-border-theme"
          : "bn-bg-layer-2 bn-text-primary bn-border-transparent"
      }`}
			style={{ borderRadius: getBorderRadius(theme.borderRadius, 8) }}
		>
			<Trans>All ({numberOfChains})</Trans>
		</button>
	);
};
