"use client";
import { useRouter, useSearchParams } from "next/navigation";
import { useState, useRef, useEffect, FormEvent, useMemo, useCallback } from "react";
import { BaseLibrary } from "@/app/components/library/LibraryType";
import { LibraryChip } from "@/app/components/chips";
import HorizontalDropdownScroller from "../components/common/HorizontalDropdownScroller";
import FabricCard from "../components/library/FabricCard";
import SilhouetteCard from "../components/library/SilhouetteCard";
import TechniqueCard from "../components/library/TechniqueCard";
import ArtworkCard from "../components/library/ArtworkCard";
import { usePersistentScroll } from "@/app/hook/usePersistentScroll";

// Request cache to prevent duplicate API calls
const requestCache = new Map<string, { data: any; timestamp: number }>();
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes

interface Option {
  value: string;
  label: string;
  checked: boolean;
}
interface LibraryFilter {
  id: string;
  name: string;
  options: Option[];
}

const FabricFilters: LibraryFilter[] = [
  {
    id: "1",
    name: "GSM",
    options: [
      { label: "50-100", value: "50-100", checked: false },
      { label: "100-150", value: "100-150", checked: false },
      { label: "150-200", value: "150-200", checked: false },
      { label: "200-250", value: "200-250", checked: false },
      { label: "250+", value: "250+", checked: false },
    ],
  },
  {
    id: "2",
    name: "Ideal For",
    options: [
      { label: "Tops", value: "14", checked: false },
      { label: "Bottoms", value: "12", checked: false },
      { label: "Co-ord Sets", value: "13", checked: false },
      { label: "Suits", value: "22", checked: false },
      { label: "One-Pieces", value: "27", checked: false },
      { label: "Outerwear", value: "17", checked: false },
      { label: "Bags", value: "26", checked: false },
      { label: "Activewear", value: "21", checked: false },
    ],
  },
  {
    id: "3",
    name: "Finish",
    options: [
      { label: "Ready for Dye", value: "Ready for Dye", checked: false },
      { label: "Greige", value: "Greige", checked: false },
      {
        label: "Azo Free Yarn Dyed",
        value: "Azo Free Yarn Dyed",
        checked: false,
      },
      {
        label: "Azo Free Piece Dyed",
        value: "Azo Free Piece Dyed",
        checked: false,
      },
      { label: "Digital Printed", value: "Digital Printed", checked: false },
      { label: "Eco Printed", value: "Eco Printed", checked: false },
      { label: "Block Printed", value: "Block Printed", checked: false },
      { label: "Screen Printed", value: "Screen Printed", checked: false },
    ],
  },
  {
    id: "4",
    name: "Seasonality",
    options: [
      { label: "Spring", value: "1", checked: false },
      { label: "Summer", value: "2", checked: false },
      { label: "Fall", value: "3", checked: false },
      { label: "Winter", value: "4", checked: false },
    ],
  },
  {
    id: "5",
    name: "Color",
    options: [
      { label: "Red", value: "1", checked: false },
      { label: "Orange", value: "2", checked: false },
      { label: "Yellow", value: "3", checked: false },
      { label: "Green", value: "4", checked: false },
      { label: "Blue", value: "5", checked: false },
      { label: "Purple", value: "6", checked: false },
      { label: "Pink", value: "7", checked: false },
      { label: "Natural", value: "8", checked: false },
      { label: "Black", value: "9", checked: false },
      { label: "White", value: "10", checked: false },
      { label: "Grey", value: "11", checked: false },
      { label: "Brown", value: "12", checked: false },
    ],
  },
];

const SilhouetteFilters: LibraryFilter[] = [
  {
    id: "2",
    name: "Category",
    options: [
      { label: "Tops", value: "14", checked: false },
      { label: "Bottoms", value: "12", checked: false },
      { label: "Co-ord Sets", value: "13", checked: false },
      { label: "Suits", value: "22", checked: false },
      { label: "One-Pieces", value: "27", checked: false },
      { label: "Outerwear", value: "17", checked: false },
      { label: "Bags", value: "26", checked: false },
      { label: "Activewear", value: "21", checked: false },
    ],
  },
  {
    id: "1",
    name: "Gender",
    options: [
      { value: "masculine", label: "Masculine", checked: false },
      { value: "feminine", label: "Feminine", checked: false },
      { value: "neutral", label: "Neutral", checked: true },
    ],
  },
  {
    id: "3",
    name: "Vibe",
    options: [
      { value: "66", label: "Bougie", checked: false },
      { value: "69", label: "Coastal", checked: false },
      { value: "64", label: "Eclectic", checked: false },
      { value: "60", label: "Earthy", checked: false },
      { value: "67", label: "Eastern", checked: false },
      { value: "58", label: "Essentials", checked: false },
      { value: "65", label: "Formal", checked: false },
      { value: "61", label: "Lounge", checked: false },
      { value: "62", label: "Movement", checked: false },
      { value: "63", label: "Psychedelic", checked: false },
      { value: "59", label: "Retro", checked: false },
      { value: "68", label: "Utility", checked: false },
    ],
  },
];

const TechniqueFilters: LibraryFilter[] = [
  {
    id: "1",
    name: "category",
    options: [
      { value: "13", label: "Deconstruction", checked: false },
      { value: "12", label: "Digital Printing", checked: false },
      { value: "11", label: "Hand Paint", checked: false },
      { value: "8", label: "Eco-Print", checked: false },
      { value: "7", label: "Plant Based Dyeing", checked: false },
      { value: "6", label: "Tie Dye", checked: false },
      { value: "4", label: "Machine Embroidery", checked: false },
      { value: "3", label: "Hand Embroidery", checked: false },
    ],
  },
  {
    id: "2",
    name: "complexity",
    options: [
      { value: "High", label: "High", checked: false },
      { value: "Medium", label: "Medium", checked: false },
      { value: "Low", label: "low", checked: false },
    ],
  },
];

const ArtworkFilters: LibraryFilter[] = [
  {
    id: "1",
    name: "art style",
    options: [
      { value: "34", label: "Anand Mohapatra Collection", checked: false },
      { value: "37", label: "Clau's Archives", checked: false },
      { value: "6", label: "Eco-Print", checked: false },
      { value: "35", label: "Nature Inspired", checked: false },
      { value: "36", label: "Hand Block Printing", checked: false },
      { value: "32", label: "Ikat", checked: false },
      { value: "22", label: "Kasuti", checked: false },
      { value: "1", label: "Mughal", checked: false },
      { value: "25", label: "Phulkari", checked: false },
      { value: "2", label: "Nordic Folklore", checked: false },
      { value: "27", label: "Warli", checked: false },
      { value: "5", label: "Egyptian Hieroglyphic", checked: false },
    ],
  },
  {
    id: "2",
    name: "artist",
    options: [
      { value: "Hardik Tuteja", label: "Hardik Tuteja", checked: false },
      { value: "Clau", label: "Clau", checked: false },
      { value: "Shaurya Dhingra", label: "Shaurya Dhingra", checked: false },
      { value: "Mohammad Khatri", label: "Mohammad Khatri", checked: false },
    ],
  },
];

export default function LibraryClient() {
  const router = useRouter();
  const searchParams = useSearchParams();

  const [query, setQuery] = useState("");
  const [clearSignal, setClearSignal] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const [fabricList, setFabricsList] = useState<BaseLibrary[]>([]);
  const [libraryData, setLibraryData] = useState<BaseLibrary[]>([]);
  const [loading, setLoading] = useState(false);
  const [isMounted, setIsMounted] = useState(false);
  const abortControllerRef = useRef<AbortController | null>(null);

  usePersistentScroll("library");
  
  const activeChipType = (searchParams.get("type") ?? "fabrics") as
    | "fabrics"
    | "silhouettes"
    | "techniques"
    | "artworks"
    | "";

  const handleChipChange = (
    value: "fabrics" | "silhouettes" | "techniques" | "artworks",
  ) => {
    // Clear search input
    setQuery("");

    // Create new URL params with only type
    const params = new URLSearchParams();
    params.set("type", value);

    // Replace URL with only type param
    router.replace(`?${params.toString()}`, { scroll: false });
  };

  useEffect(() => {
    setIsMounted(true);
    inputRef.current?.focus();
  }, []);

  // Debounced search effect
  useEffect(() => {
    const timeoutId = setTimeout(() => {
      const params = new URLSearchParams(searchParams.toString());

      if (query.length > 2) {
        params.set("q", query.trim());
      } else {
        params.delete("q");
      }

      router.replace(`/library?${params.toString()}`, { scroll: false });
    }, 300); // 300ms debounce

    return () => clearTimeout(timeoutId);
  }, [query, searchParams, router]);

  function handleLibrarySearchSubmit(e: FormEvent) {
    e.preventDefault();
    if (!query.trim()) return;

    const params = new URLSearchParams(searchParams.toString());
    params.set("q", query.trim());
    router.replace(`/library?${params.toString()}`, { scroll: false });
  }

  const currentFilters: LibraryFilter[] = useMemo(() => {
    switch (activeChipType) {
      case "fabrics":
        return FabricFilters;
      case "silhouettes":
        return SilhouetteFilters;
      case "techniques":
        return TechniqueFilters;
      case "artworks":
        return ArtworkFilters;
      default:
        return [];
    }
  }, [activeChipType]);

  const transformedFilters = useMemo(
    () =>
      currentFilters.map((filter, index) => ({
        id: index + 1,
        label: filter.name,
        name: filter.name.toLowerCase(),
        value: filter.name,
        options: filter.options.map((opt) => ({
          value: opt.value,
          label: opt.label,
        })),
      })),
    [currentFilters],
  );
  const appliedFilters = useMemo(
    () => ({
      q: searchParams.get("q")?.toLowerCase() || "",
      type: searchParams.get("type") || "",
      color: searchParams.get("color")?.split(",") || [],
      category: searchParams.get("category")?.split(",") || [],
      complexity: searchParams.get("complexity")?.split(",") || [],
    }),
    [searchParams],
  );

  const filteredData = useMemo(() => {
    const typeMap: Record<string, string> = {
      fabrics: "fabric",
      silhouettes: "silhouette",
      techniques: "technique",
      artworks: "artwork",
    };

    return libraryData.filter((item) => {
      if (appliedFilters.type) {
        const expected = typeMap[appliedFilters.type] || appliedFilters.type;
        if (item.type && item.type?.toLowerCase() !== expected?.toLowerCase()) {
          return false;
        }
      }
      return true;
      if (appliedFilters.q) {
        const title = item.title?.toLowerCase() || "";
        if (!title.includes(appliedFilters.q)) {
          return false;
        }
      }
      if (
        appliedFilters.color.length > 0 &&
        !appliedFilters.color.some((c) =>
          (item.attribute3 || "").toLowerCase().includes(c.toLowerCase()),
        )
      ) {
        return false;
      }
      return true;
      // For silhouettes, the API already filters by category; skip client-side category matching
      if (
        activeChipType !== "silhouettes" &&
        activeChipType !== "techniques" &&
        activeChipType !== "artworks"
      ) {
        if (
          appliedFilters.category.length > 0 &&
          !appliedFilters.category.some((cat) =>
            (item.attribute2 || "").toLowerCase().includes(cat.toLowerCase()),
          )
        ) {
          return false;
        }
      }
      if (
        appliedFilters.complexity.length > 0 &&
        !appliedFilters.complexity.some((comp) =>
          (item.attribute1 || "").toLowerCase().includes(comp.toLowerCase()),
        )
      ) {
        return false;
      }
      return true;
    });
  }, [appliedFilters, libraryData, activeChipType]);

  const buildLibraryUrl = useCallback((path: string) => {
    const params = new URLSearchParams();
    const q = searchParams.get("q");
    const color = searchParams.get("color");
    const category = searchParams.get("category");
    const complexity = searchParams.get("complexity");

    if (q) params.set("q", q);
    if (color) params.set("color", color);
    if (category) params.set("category", category);
    if (complexity) params.set("complexity", complexity);

    return `/api${path}${params.toString() ? `?${params.toString()}` : ""}`;
  }, [searchParams]);

  const getFabrics = useCallback(async () => {
    // Cancel previous request
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }
    
    try {
      setLoading(true);

      // Build query string from current URL search params
      const params = new URLSearchParams();
      const q = searchParams.get("q");
      const color = searchParams.get("color");
      const category = searchParams.get("ideal for");
      const finish = searchParams.get("finish");
      const gsm = searchParams.get("gsm");
      const seasonality = searchParams.get("seasonality");

      if (q) params.set("q", q);
      if (color) params.set("color", color);
      if (category) params.set("category", category);
      if (finish) params.set("finish", finish);
      if (gsm) params.set("gsm", gsm);
      if (seasonality) params.set("seasonality", seasonality);

      const url = `/api/library/fabric?${params.toString()}`;
      const cacheKey = `fabric_${params.toString()}`;

      // Check cache first
      const cached = requestCache.get(cacheKey);
      if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
        setFabricsList(cached.data.data || []);
        setLibraryData(cached.data.data || []);
        setLoading(false);
        return cached.data;
      }

      // Create new abort controller for this request
      abortControllerRef.current = new AbortController();

      const response = await fetch(url, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
        },
        signal: abortControllerRef.current.signal,
      });

      if (!response.ok) {
        throw new Error(`Error: ${response.status} - ${response.statusText}`);
      }

      const data = await response.json();
      
      // Cache the response
      requestCache.set(cacheKey, { data, timestamp: Date.now() });
      
      setFabricsList(data.data || []);
      setLibraryData(data.data || []);

      return data;
    } catch (error: any) {
      if (error.name === 'AbortError') {
        console.log('Fabric request cancelled');
        return;
      }
      console.error("Error fetching fabric list:", error);
    } finally {
      setLoading(false);
    }
  }, [searchParams]);

  const getSilhouettes = useCallback(async () => {
    // Cancel previous request
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }
    
    try {
      setLoading(true);

      const params = new URLSearchParams();
      const q = query;
      const vibe = searchParams.get("vibe");
      const category = searchParams.get("category");
      const gender = searchParams.get("gender");

      if (q) params.set("q", q);
      if (vibe) params.set("vibe", vibe);
      if (category) params.set("category", category);
      if (gender) params.set("gender", gender);

      const url = `/api/library/silhouette?${params.toString()}`;
      const cacheKey = `silhouette_${params.toString()}`;

      // Check cache first
      const cached = requestCache.get(cacheKey);
      if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
        setLibraryData(cached.data.data || []);
        setLoading(false);
        return cached.data.data;
      }

      // Create new abort controller
      abortControllerRef.current = new AbortController();

      const response = await fetch(url, {
        method: "GET",
        headers: { "Content-Type": "application/json" },
        signal: abortControllerRef.current.signal,
      });

      if (!response.ok) {
        throw new Error(`Error: ${response.status} - ${response.statusText}`);
      }

      const data = await response.json();
      
      // Cache the response
      requestCache.set(cacheKey, { data, timestamp: Date.now() });
      
      setLibraryData(data.data || []);

      return data.data;
    } catch (error: any) {
      if (error.name === 'AbortError') {
        console.log('Silhouette request cancelled');
        return;
      }
      console.error("Error fetching silhouette list:", error);
    } finally {
      setLoading(false);
    }
  }, [query, searchParams]);

  const getArtworks = useCallback(async () => {
    // Cancel previous request
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }
    
    try {
      setLoading(true);

      const params = new URLSearchParams();
      const q = searchParams.get("q");
      const art_style = searchParams.get("art style");
      const artist = searchParams.get("artist");

      if (q) params.set("q", q);
      if (art_style) params.set("art style", art_style);
      if (artist) params.set("artist", artist);

      const url = `/api/library/artwork?${params.toString()}`;
      const cacheKey = `artwork_${params.toString()}`;

      // Check cache first
      const cached = requestCache.get(cacheKey);
      if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
        setLibraryData(cached.data.data || []);
        setLoading(false);
        return cached.data;
      }

      // Create new abort controller
      abortControllerRef.current = new AbortController();

      const response = await fetch(url, {
        method: "GET",
        headers: { "Content-Type": "application/json" },
        signal: abortControllerRef.current.signal,
      });

      if (!response.ok) {
        throw new Error(`Error: ${response.status} - ${response.statusText}`);
      }

      const data = await response.json();
      
      // Cache the response
      requestCache.set(cacheKey, { data, timestamp: Date.now() });
      
      setLibraryData(data.data || []);

      return data;
    } catch (error: any) {
      if (error.name === 'AbortError') {
        console.log('Artwork request cancelled');
        return;
      }
      console.error("Error fetching artwork list:", error);
    } finally {
      setLoading(false);
    }
  }, [searchParams]);

  const getTechniques = useCallback(async () => {
    // Cancel previous request
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }
    
    try {
      setLoading(true);

      const params = new URLSearchParams();
      const q = searchParams.get("q");
      const category = searchParams.get("category");
      const complexity = searchParams.get("complexity");

      if (q) params.set("q", q);
      if (complexity) params.set("complexity", complexity);
      if (category) params.set("category", category);

      const url = `/api/library/technique?${params.toString()}`;
      const cacheKey = `technique_${params.toString()}`;

      // Check cache first
      const cached = requestCache.get(cacheKey);
      if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
        setLibraryData(cached.data.data || []);
        setLoading(false);
        return cached.data;
      }

      // Create new abort controller
      abortControllerRef.current = new AbortController();

      const response = await fetch(url, {
        method: "GET",
        headers: { "Content-Type": "application/json" },
        signal: abortControllerRef.current.signal,
      });

      if (!response.ok) {
        throw new Error(`Error: ${response.status} - ${response.statusText}`);
      }

      const data = await response.json();
      
      // Cache the response
      requestCache.set(cacheKey, { data, timestamp: Date.now() });
      
      setLibraryData(data.data || []);

      return data;
    } catch (error: any) {
      if (error.name === 'AbortError') {
        console.log('Technique request cancelled');
        return;
      }
      console.error("Error fetching technique list:", error);
    } finally {
      setLoading(false);
    }
  }, [searchParams]);

  useEffect(() => {
    // Re-fetch when active type changes or search params change (so filters in URL are applied)
    if (activeChipType === "fabrics") {
      getFabrics();
    } else if (activeChipType === "silhouettes") {
      getSilhouettes();
    } else if (activeChipType === "techniques") {
      getTechniques();
    } else if (activeChipType === "artworks") {
      getArtworks();
    }

    // Cleanup: abort any pending requests when component unmounts or dependencies change
    return () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  }, [activeChipType, getFabrics, getSilhouettes, getTechniques, getArtworks, searchParams]);

  if (!isMounted) {
    return null; // or loading skeleton
  }

  // debug: activeChipType (removed in production)
  return (
    <div className="relative">
      <div className="mob-noise absolute top-0 left-0 h-full w-full pointer-events-none" />
      <div className="relative py-12">
        <div className="mob-noise sticky top-12 z-10 bg-gray-100 py-2">
          <div className="wrapper">
            <div className="mx-auto flex w-full flex-col items-center justify-center align-middle md:w-2/3">
              {/* Radio Chips */}
              <div className="flex w-full overflow-hidden items-center justify-center">
                <div className="scrollbar-hide flex gap-0.5 sm:gap-1 overflow-x-auto py-2 whitespace-nowrap">
                  {["fabrics", "silhouettes", "techniques", "artworks"].map(
                    (chip) => (
                      <LibraryChip
                        key={chip}
                        id={`search_chip_${chip}`}
                        name="search_chip_type"
                        label={chip.charAt(0).toUpperCase() + chip.slice(1)}
                        checked={activeChipType === chip}
                        onChange={() =>
                          handleChipChange(
                            chip as
                              | "fabrics"
                              | "silhouettes"
                              | "techniques"
                              | "artworks",
                          )
                        }
                      />
                    ),
                  )}
                </div>
              </div>

              {/* Search bar */}
              <div className="w-full">
                <form
                  onSubmit={handleLibrarySearchSubmit}
                  className="relative mt-1 flex flex-col gap-2 border-1 border-dashed p-2 md:p-4"
                  autoComplete="off"
                >
                  <input
                    ref={inputRef}
                    type="search"
                    id="site_search"
                    name="site_search"
                    value={query}
                    onChange={(e) => setQuery(e.target.value)}
                    placeholder="Search Morni ..."
                    className="search-cancel:appearance md:placeholder:text-md w-full pl-0 text-xl font-medium placeholder:text-sm md:pl-1 md:text-xl"
                  />
                </form>
              </div>
              <div className="grid grid-cols-2 items-center justify-between gap-1 align-middle md:grid-cols-6">
                {/* Div 2 */}
                <div className="col-span-2 md:order-2 md:col-span-4">
                  <HorizontalDropdownScroller
                    items={transformedFilters}
                    showLabels={false}
                    showPrevArrow={false}
                    clearSignal={clearSignal}
                    showNextArrow={false}
                    showBorder={false}
                  />
                </div>

                {/* Div 1 */}
                <div className="order-2 text-left md:order-1">
                  <div className="text-xs">
                    {loading ? "Loading..." : `${filteredData.length} results`}
                  </div>
                </div>

                {/* Div 3 */}
                <div className="order-3 text-right md:order-3">
                  <button
                    type="button"
                    onClick={() => {
                      setClearSignal((s) => !s);
                      setQuery(""); // Clear the input
                      // Remove all query params except type
                      const params = new URLSearchParams();
                      params.set("type", activeChipType);
                      router.replace(`/library?${params.toString()}`, {
                        scroll: false,
                      });
                    }}
                    className="text-xs underline"
                  >
                    Clear
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* Cards */}
        <div className="relative z-5">
          <div className="wrapper py-4">
            {loading ? (
              <div className="flex w-full flex-col items-center justify-center py-16 align-middle text-gray-950">
                <svg
                  className="h-8 w-8 animate-spin text-gray-700"
                  viewBox="0 0 24 24"
                  fill="none"
                >
                  <circle
                    className="opacity-25"
                    cx="12"
                    cy="12"
                    r="10"
                    stroke="currentColor"
                    strokeWidth="4"
                  ></circle>
                  <path
                    className="opacity-75"
                    fill="currentColor"
                    d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"
                  ></path>
                </svg>
                <span className="mt-4">Loading...</span>
              </div>
            ) : filteredData.length === 0 ? (
              <div className="flex w-full flex-col items-center justify-center py-16 align-middle text-gray-950">
                <span>
                  No results found
                  {activeChipType
                    ? ` for ${activeChipType.charAt(0).toUpperCase() + activeChipType.slice(1)}`
                    : ""}
                </span>
                {activeChipType && (
                  <h4 className="capitalize">{activeChipType}</h4>
                )}
              </div>
            ) : (
              <div
                className={`grid grid-cols-2 gap-4 md:grid-cols-3 md:gap-15 ${activeChipType === "silhouettes" ? "lg:grid-cols-5" : "lg:grid-cols-4"} `}
              >
                {(() => {
                  switch (activeChipType) {
                    case "fabrics":
                      return filteredData.map((fabric, index) => (
                        <FabricCard
                          key={`${fabric.id}-fabric-${index}`}
                          library={fabric}
                        />
                      ));
                    case "silhouettes":
                      return filteredData.map((silhouette, index) => (
                        <SilhouetteCard
                          key={`${silhouette.id}-silhouette-${index}`}
                          library={silhouette}
                        />
                      ));
                    case "techniques":
                      return filteredData.map((technique, index) => (
                        <TechniqueCard
                          key={`${technique.id}-technique-${index}`}
                          library={technique}
                        />
                      ));
                    case "artworks":
                      return filteredData.map((artwork, index) => (
                        <ArtworkCard
                          key={`${artwork.id}-artwork-${index}`}
                          library={artwork}
                        />
                      ));
                    default:
                      return null;
                  }
                })()}
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
