import { useRef } from "react";

import type { Token } from "@/types/index";
import { TokenItem } from "@components/TokenItem";
import { useMappedChainData } from "@hooks/useMappedChainData";
import { useVirtualizer } from "@tanstack/react-virtual";
import { NoTokens } from "./NoTokens";
import { SearchingForTokens } from "./SearchingForToken";

export const TokensSection = ({
  tokens,
  label,
  setToken,
  activeToken,
  isSearching = false,
  showNoTokensWarning = false,
  showChainDetails = false,
  shouldDisable,
  onAssetHoverIn,
  onAssetHoverOut,
}: {
  tokens: Token[];
  setToken: (value: Token) => void;
  shouldDisable: (token: Token) => boolean;
  activeToken?: Token;
  label?: string;
  isSearching?: boolean;
  showNoTokensWarning?: boolean;
  showChainDetails?: boolean;
  onAssetHoverIn?: (token: Token) => void;
  onAssetHoverOut?: (token: Token) => void;
}) => {
  const parentRef = useRef(null);
  const mappedChainData = useMappedChainData();

  const rowVirtualizer = useVirtualizer({
    count: tokens?.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 56,
  });

  if (isSearching && !tokens?.length) return <SearchingForTokens />;
  if (!tokens?.length && showNoTokensWarning) return <NoTokens />;
  if (!tokens?.length) return;

  return (
    <>
      {label && (
        <h4 className="bn-text-sm bn-font-normal bn-text-secondary bn-px-4 bn-mt-3 bn-pb-2.5 bn-border-0 bn-border-b bn-border-solid bn-border-strong">
          {label}
        </h4>
      )}

      <div ref={parentRef} className="bn-w-full bn-relative">
        <div
          style={{ height: `${tokens.length * 56}px` }}
          className="bn-flex bn-flex-col"
        >
          {rowVirtualizer.getVirtualItems().map((virtualRow) => {
            const item = tokens?.[virtualRow.index];
            const chain = mappedChainData?.[item?.chainId];
            return (
              <TokenItem
                token={item}
                // biome-ignore format:
                chainName={
                  showChainDetails
                    ? `on ${chain?.name || "network"}`
                    : undefined
                }
                onHoverIn={() => onAssetHoverIn?.(item)}
                onHoverOut={() => onAssetHoverOut?.(item)}
                onClick={() => setToken(item)}
                showChainIcon={showChainDetails}
                active={deepTokenComparison(item, activeToken)}
                disabled={shouldDisable(item)}
                key={virtualRow.key}
              />
            );
          })}
        </div>
      </div>

      {isSearching && <SearchingForTokens />}
    </>
  );
};

function deepTokenComparison(
  tokenA: Token | null | undefined,
  tokenB: Token | null | undefined
) {
  if (!tokenA || !tokenB || tokenA.chainId !== tokenB.chainId) return false;

  return tokenA.address.toLowerCase() === tokenB.address.toLowerCase();
}
