import { useQuery } from "@tanstack/react-query";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useCategoryProductsData } from "./useProductsData";
import { Brand, Category } from "@/types/products.types";

export interface FilterState {
  selectedCategories: string[];
  priceRange: [number, number];
  inStockOnly: boolean;
  selectedBrand: string;
  wholeSale: boolean;
}

export interface UseFiltersDataProps {
  categoryUrl: string;
}

export const useFiltersData = ({ categoryUrl }: UseFiltersDataProps) => {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();

  // State management
  const [filterState, setFilterState] = useState<FilterState>({
    selectedCategories: [],
    priceRange: [0, 1000000], // Default values, will be updated from API
    inStockOnly: false,
    selectedBrand: "",
    wholeSale: false,
  });

  // Ref for debouncing price filter
  const priceFilterTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);

  // Get filter parameters from URL
  const filterParams = useMemo(
    () => ({
      page: 1,
      limit: 1,
      category: searchParams.get("category") || undefined,
      brand: searchParams.get("brand") || undefined,
      minPrice: searchParams.get("minPrice")
        ? Number(searchParams.get("minPrice"))
        : undefined,
      maxPrice: searchParams.get("maxPrice")
        ? Number(searchParams.get("maxPrice"))
        : undefined,
      stock: searchParams.get("stock") || undefined,
      wholeSale: searchParams.get("wholeSale") || undefined,
      rating: searchParams.get("rating")
        ? Number(searchParams.get("rating"))
        : undefined,
    }),
    [searchParams]
  );

  // Fetch data for filters
  const { data: productsData, isLoading } = useCategoryProductsData(
    categoryUrl,
    filterParams
  );

  // Extract categories and brands from API response
  const categories: Category[] = useMemo(() => {
    return productsData?.results?.category?.children ?? [];
  }, [productsData]);

  const brands: Brand[] = useMemo(() => {
    return productsData?.results?.brands ?? [];
  }, [productsData]);

  // Extract price range from API response
  const apiPriceRange = useMemo(() => {
    return productsData?.results?.filters?.priceRange;
  }, [productsData]);

  // Update price range from API when data is available
  useEffect(() => {
    if (apiPriceRange) {
      setFilterState((prev) => ({
        ...prev,
        priceRange: [apiPriceRange.minPrice, apiPriceRange.maxPrice],
      }));
    }
  }, [apiPriceRange]);

  // Initialize state from URL parameters
  useEffect(() => {
    const qsCategories =
      searchParams.get("category")?.split(",").filter(Boolean) ?? [];
    const qsMin = searchParams.get("minPrice")
      ? Number(searchParams.get("minPrice"))
      : apiPriceRange?.minPrice ?? 0;
    const qsMax = searchParams.get("maxPrice")
      ? Number(searchParams.get("maxPrice"))
      : apiPriceRange?.maxPrice ?? 1000000;
    const qsStock = searchParams.get("stock") === "1";
    const qsBrand = searchParams.get("brand") ?? "";
    const qsWholeSale = searchParams.get("wholeSale") === "1";

    setFilterState({
      selectedCategories: qsCategories,
      priceRange: [qsMin, qsMax],
      inStockOnly: qsStock,
      selectedBrand: qsBrand,
      wholeSale: qsWholeSale,
    });
  }, [searchParams, apiPriceRange]);

  // Update URL parameters
  const updateUrlParams = useCallback(
    (updates: Partial<Record<string, string | null>>) => {
      const params = new URLSearchParams(searchParams.toString());

      Object.entries(updates).forEach(([key, value]) => {
        if (value === null || value === "" || value === undefined) {
          params.delete(key);
        } else {
          params.set(key, value);
        }
      });

      router.push(`${pathname}?${params.toString()}`);
    },
    [searchParams, pathname, router]
  );

  // Apply price filter with debouncing
  const applyPriceFilter = useCallback(
    (range: [number, number]) => {
      if (priceFilterTimeoutRef.current) {
        clearTimeout(priceFilterTimeoutRef.current);
      }

      priceFilterTimeoutRef.current = setTimeout(() => {
        const updates: Partial<Record<string, string | null>> = {};

        if (range[0] > 0) {
          updates.minPrice = range[0].toString();
        } else {
          updates.minPrice = null;
        }

        const maxPrice = apiPriceRange?.maxPrice ?? 1000000;
        if (range[1] < maxPrice) {
          updates.maxPrice = range[1].toString();
        } else {
          updates.maxPrice = null;
        }

        updateUrlParams(updates);
      }, 1000);
    },
    [updateUrlParams, apiPriceRange]
  );

  // Apply category filter
  const applyCategoryFilter = useCallback(
    (categoryId: string | null) => {
      const newCategories = categoryId ? [categoryId] : [];
      setFilterState((prev) => ({
        ...prev,
        selectedCategories: newCategories,
      }));

      updateUrlParams({
        category: newCategories.length > 0 ? newCategories.join(",") : null,
      });
    },
    [updateUrlParams]
  );

  // Apply stock filter
  const applyStockFilter = useCallback(
    (inStock: boolean) => {
      setFilterState((prev) => ({ ...prev, inStockOnly: inStock }));
      updateUrlParams({ stock: inStock ? "1" : null });
    },
    [updateUrlParams]
  );

  // Apply brand filter
  const applyBrandFilter = useCallback(
    (brandId: string) => {
      setFilterState((prev) => ({ ...prev, selectedBrand: brandId }));
      updateUrlParams({ brand: brandId });
    },
    [updateUrlParams]
  );

  // Clear brand filter
  const clearBrandFilter = useCallback(() => {
    setFilterState((prev) => ({ ...prev, selectedBrand: "" }));
    updateUrlParams({ brand: null });
  }, [updateUrlParams]);

  // Apply wholesale filter
  const applyWholesaleFilter = useCallback(
    (wholesale: boolean) => {
      setFilterState((prev) => ({ ...prev, wholeSale: wholesale }));
      updateUrlParams({ wholeSale: wholesale ? "1" : null });
    },
    [updateUrlParams]
  );

  // Clear all filters
  const clearAllFilters = useCallback(() => {
    const defaultMinPrice = apiPriceRange?.minPrice ?? 0;
    const defaultMaxPrice = apiPriceRange?.maxPrice ?? 1000000;

    setFilterState({
      selectedCategories: [],
      priceRange: [defaultMinPrice, defaultMaxPrice],
      inStockOnly: false,
      selectedBrand: "",
      wholeSale: false,
    });

    const params = new URLSearchParams(searchParams.toString());
    const filterKeys = [
      "category",
      "minPrice",
      "maxPrice",
      "stock",
      "brand",
      "wholeSale",
    ];
    filterKeys.forEach((key) => params.delete(key));

    router.push(`${pathname}?${params.toString()}`);
  }, [searchParams, pathname, router, apiPriceRange]);

  // Update price range in state
  const updatePriceRange = useCallback(
    (range: [number, number]) => {
      setFilterState((prev) => ({ ...prev, priceRange: range }));
      applyPriceFilter(range);
    },
    [applyPriceFilter]
  );

  return {
    // State
    filterState,
    categories,
    brands,
    isLoading,
    priceMinMaxRange: apiPriceRange
      ? ([apiPriceRange.minPrice, apiPriceRange.maxPrice] as [number, number])
      : ([0, 1000000] as [number, number]),

    // Actions
    applyCategoryFilter,
    updatePriceRange,
    applyStockFilter,
    applyBrandFilter,
    clearBrandFilter,
    applyWholesaleFilter,
    clearAllFilters,
  };
};
