import { Trans } from "@lingui/macro";
import React, { useEffect, useRef, useState } from "react";
import { useTheme } from "../../hooks/useTheme";
import type { Chain } from "../../store/globalSlice";
import { getBorderRadius } from "../../utils/getBorderRadius";
import { MoreChainsDropdown, NetworkButton } from "./NetworkButton";

export const NetworkList = ({
	chains,
	activeNetwork,
	setActiveNetwork,
	showAllNetworksBtn = false,
}: {
	chains: Chain[];
	activeNetwork: number | "all";
	setActiveNetwork: (value: number | "all") => void;
	showAllNetworksBtn?: boolean;
}) => {
	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);

	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 = chains?.slice(0, numberOfItems);

	// networks hidden in the overflow dropdown
	let restItems =
		chains && priorityItems && chains?.length > priorityItems?.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
	if (activeNetworkOverflowed) {
		const replacedNetwork = priorityItems?.pop();
		priorityItems?.push(activeNetworkOverflowed);

		// placing the replaced network in the overflown list
		if (replacedNetwork && restItems) restItems = [replacedNetwork, ...restItems];
	}

	return (
		<div className="bn-mt-[15px] bn-flex bn-px-4 bn-mb-4 bn-relative" ref={ref}>
			{showAllNetworksBtn && (
				<div ref={allNetworksBtnRef} className="bn-w-fit bn-mr-1.5">
					<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}
					/>
				);
			})}

			{restItems?.length && (
				<MoreChainsDropdown chains={restItems} setActiveNetwork={setActiveNetwork} />
			)}
		</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-[18px] bn-h-[38px] bn-text-[15px] bn-leading-[18px] bn-cursor-pointer ${
				active
				? "bn-bg-accent bn-text-accent bn-border-accent"
				: "bn-bg-layer-2 bn-text-primary bn-border-transparent"
			}`}
			style={{ borderRadius: getBorderRadius(theme.borderRadius, 8) }}
		>
			<Trans>All Networks ({numberOfChains})</Trans>
		</button>
	);
};
