"use client";

import Icon from "@/shared/ui/icon";
import { Input } from "@/shared/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/ui/select";
import { HelpCircle, Search } from "lucide-react";
import React, {
  Suspense,
  useDeferredValue,
  useEffect,
  useMemo,
  useRef,
  useState,
  type ComponentType,
  type LazyExoticComponent,
} from "react";
import { useTranslation } from "react-i18next";

// 🔹 Lazy icon faqat tanlangan icon uchun
const LazyIcon: React.FC<{ name: string }> = ({ name }) => {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const IconComp: LazyExoticComponent<ComponentType<any>> = React.lazy(
    async () => {
      const icons = await import("lucide-react");
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      return { default: (icons as any)[name] || HelpCircle };
    },
  );

  return (
    <Suspense fallback={<div className="w-4 h-4" />}>
      <IconComp className="w-4 h-4" />
    </Suspense>
  );
};

interface IconSelectProps {
  selectedIcon?: string;
  setSelectedIcon: (value: string) => void;
}

const IconSelect: React.FC<IconSelectProps> = ({
  selectedIcon,
  setSelectedIcon,
}) => {
  const [icons, setIcons] = useState<string[]>([]);
  const { t } = useTranslation();
  const [visibleIcons, setVisibleIcons] = useState<string[]>([]);
  const [chunkSize] = useState(100);
  const [index, setIndex] = useState(1);
  const [containerEl, setContainerEl] = useState<HTMLDivElement | null>(null);
  const [isOpen, setIsOpen] = useState(false);
  const [searchTerm, setSearchTerm] = useState("");

  const loaderRef = useRef<HTMLDivElement | null>(null);
  const deferredSearch = useDeferredValue(searchTerm);

  useEffect(() => {
    if (!isOpen) return;
    const loadIcons = async () => {
      const mod = await import("lucide-react");
      const allIcons = Object.keys(mod).filter((k) => /^[A-Z]/.test(k));
      setIcons(allIcons);
      setVisibleIcons(allIcons.slice(0, chunkSize));
      setIndex(1);
    };
    loadIcons();
  }, [isOpen, chunkSize]);

  useEffect(() => {
    if (!containerEl || !loaderRef.current || !isOpen) return;

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) {
          const start = index * chunkSize;
          const end = start + chunkSize;
          const next = icons.slice(start, end);
          if (next.length > 0) {
            setVisibleIcons((p) => [...p, ...next]);
            setIndex((p) => p + 1);
          }
        }
      },
      { root: containerEl, threshold: 1.0 },
    );

    observer.observe(loaderRef.current);
    return () => observer.disconnect();
  }, [containerEl, icons, index, chunkSize, isOpen]);

  const filteredIcons = useMemo(() => {
    const term = deferredSearch.trim().toLowerCase();
    if (!term) return visibleIcons;
    return icons.filter((n) => n.toLowerCase().includes(term));
  }, [icons, visibleIcons, deferredSearch]);

  const handleOpenChange = (open: boolean) => {
    setIsOpen(open);
    if (!open) {
      setVisibleIcons([]);
      setIcons([]);
      setIndex(1);
      setSearchTerm("");
    }
  };

  return (
    <Select
      value={selectedIcon}
      onValueChange={setSelectedIcon}
      onOpenChange={handleOpenChange}
    >
      <SelectTrigger className="!h-12 w-[220px] text-md">
        <SelectValue placeholder={t("Ikonka tanlang")}>
          {selectedIcon ? (
            <div className="flex items-center gap-2">
              <LazyIcon name={selectedIcon} />
              {selectedIcon}
            </div>
          ) : (
            t("Ikonka tanlang")
          )}
        </SelectValue>
      </SelectTrigger>

      <SelectContent ref={setContainerEl} className="max-h-80 overflow-y-auto">
        <div className="sticky top-0 bg-white dark:bg-neutral-900 z-10 p-2 border-b flex items-center gap-2">
          <Search className="w-4 h-4 text-gray-500" />
          <Input
            placeholder="Qidiruv..."
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
            className="h-8 text-sm"
          />
        </div>

        {filteredIcons.map((iconName) => (
          <SelectItem key={iconName} value={iconName}>
            <div className="flex items-center gap-2 text-sm">
              <Icon name={iconName} />
              {iconName}
            </div>
          </SelectItem>
        ))}

        {!searchTerm && isOpen && (
          <div ref={loaderRef} className="h-6 flex justify-center items-center">
            {visibleIcons.length < icons.length && (
              <span className="text-xs text-gray-400">
                {t("Yuklanmoqda...")}
              </span>
            )}
          </div>
        )}
      </SelectContent>
    </Select>
  );
};

export default IconSelect;
