"use client";
import { useSearchParams, useRouter, usePathname } from "next/navigation";
import { useState, useEffect, useCallback, useMemo, useRef } from "react";
import { useDebounce } from "./useDebounce";
import {
  parseFiltersFromUrl,
  serializeFiltersToUrl,
  getDefaultFilterValues,
  countActiveFilters,
  buildFilterUrl as buildUrl
} from "./useUrlFilters.utils";
function useUrlFilters(schema, options = {}) {
  const {
    debounceMs = 300,
    scroll = false
  } = options;
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const isUpdatingFromUrl = useRef(false);
  const schemaKeys = useMemo(() => Object.keys(schema).sort().join(","), [schema]);
  const prevSchemaKeysRef = useRef(schemaKeys);
  const hasUserInteracted = useRef(false);
  const [filters, setFiltersState] = useState(
    () => parseFiltersFromUrl(schema, searchParams)
  );
  const debouncedFilters = useDebounce(filters, debounceMs);
  useEffect(() => {
    if (prevSchemaKeysRef.current !== schemaKeys) {
      const urlFilters = parseFiltersFromUrl(schema, searchParams);
      isUpdatingFromUrl.current = true;
      setFiltersState(urlFilters);
      prevSchemaKeysRef.current = schemaKeys;
    }
  }, [schemaKeys, schema, searchParams]);
  useEffect(() => {
    if (isUpdatingFromUrl.current) {
      isUpdatingFromUrl.current = false;
      return;
    }
    if (!hasUserInteracted.current) {
      return;
    }
    const newParams = serializeFiltersToUrl(schema, debouncedFilters);
    const newUrl = `${pathname}${newParams ? `?${newParams}` : ""}`;
    const currentUrl = `${pathname}${searchParams.toString() ? `?${searchParams.toString()}` : ""}`;
    if (newUrl !== currentUrl) {
      router.replace(newUrl, { scroll });
    }
  }, [debouncedFilters, pathname, router, schema, scroll, searchParams]);
  const prevSearchParamsRef = useRef(searchParams.toString());
  useEffect(() => {
    const currentSearchParams = searchParams.toString();
    if (prevSearchParamsRef.current !== currentSearchParams) {
      prevSearchParamsRef.current = currentSearchParams;
      const urlFilters = parseFiltersFromUrl(schema, searchParams);
      isUpdatingFromUrl.current = true;
      setFiltersState(urlFilters);
    }
  }, [searchParams, schema]);
  const setFilter = useCallback((key, value) => {
    hasUserInteracted.current = true;
    setFiltersState((prev) => ({ ...prev, [key]: value }));
  }, []);
  const setFilters = useCallback((values) => {
    hasUserInteracted.current = true;
    setFiltersState((prev) => ({ ...prev, ...values }));
  }, []);
  const clearFilter = useCallback((key) => {
    hasUserInteracted.current = true;
    const defaults = getDefaultFilterValues(schema);
    setFiltersState((prev) => ({
      ...prev,
      [key]: defaults[key]
    }));
  }, [schema]);
  const clearAllFilters = useCallback(() => {
    hasUserInteracted.current = true;
    setFiltersState(getDefaultFilterValues(schema));
  }, [schema]);
  const hasActiveFilters2 = useMemo(
    () => countActiveFilters(schema, filters) > 0,
    [schema, filters]
  );
  const activeFilterCount = useMemo(
    () => countActiveFilters(schema, filters),
    [schema, filters]
  );
  const buildFilterUrl2 = useCallback(
    (baseUrl, overrides) => buildUrl(baseUrl, schema, filters, overrides),
    [filters, schema]
  );
  useEffect(() => {
    return () => {
      isUpdatingFromUrl.current = false;
      hasUserInteracted.current = false;
    };
  }, []);
  return {
    filters,
    setFilter,
    setFilters,
    clearFilter,
    clearAllFilters,
    hasActiveFilters: hasActiveFilters2,
    activeFilterCount,
    buildFilterUrl: buildFilterUrl2
  };
}
export * from "./useUrlFilters.types";
import {
  parseFiltersFromUrl as parseFiltersFromUrl2,
  serializeFiltersToUrl as serializeFiltersToUrl2,
  getDefaultFilterValues as getDefaultFilterValues2,
  countActiveFilters as countActiveFilters2,
  hasActiveFilters,
  buildFilterUrl
} from "./useUrlFilters.utils";
export {
  buildFilterUrl,
  countActiveFilters2 as countActiveFilters,
  getDefaultFilterValues2 as getDefaultFilterValues,
  hasActiveFilters,
  parseFiltersFromUrl2 as parseFiltersFromUrl,
  serializeFiltersToUrl2 as serializeFiltersToUrl,
  useUrlFilters
};
