"use client";

import { useState, useMemo, useCallback } from "react";
import { useDebounce } from "@/presentation/hooks/use-debounce";
import type { PaginationQueryParams } from "@/shared/types";
import { PAGINATION_DEFAULT_PAGE_SIZE } from "@/shared/constants";

interface UseServerPaginationOptions {
  perPage?: number;
  orderBy?: string;
  order?: "ASC" | "DESC";
}

export function useServerPagination(options?: UseServerPaginationOptions) {
  const [page, setPage] = useState(1);
  const [perPage, setPerPage] = useState(options?.perPage ?? PAGINATION_DEFAULT_PAGE_SIZE);
  const [orderBy, setOrderBy] = useState(options?.orderBy ?? "created_at");
  const [order, setOrder] = useState<"ASC" | "DESC">(options?.order ?? "DESC");
  const [search, setSearchRaw] = useState("");
  const [filters, setFilters] = useState<Record<string, string | number | undefined>>({});

  const debouncedSearch = useDebounce(search, 300);

  const setSearch = useCallback((value: string) => {
    setSearchRaw(value);
    setPage(1);
  }, []);

  const setFilter = useCallback((key: string, value: string | number | undefined) => {
    setFilters((prev) => ({ ...prev, [key]: value }));
    setPage(1);
  }, []);

  const setSort = useCallback((newOrderBy: string, newOrder: "ASC" | "DESC") => {
    setOrderBy(newOrderBy);
    setOrder(newOrder);
    setPage(1);
  }, []);

  const params: PaginationQueryParams = useMemo(() => {
    const p: PaginationQueryParams = {
      page,
      per_page: perPage,
      order_by: orderBy,
      order,
    };
    if (debouncedSearch) p.search = debouncedSearch;
    for (const [key, value] of Object.entries(filters)) {
      if (value !== undefined && value !== "") {
        p[key] = value;
      }
    }
    return p;
  }, [page, perPage, orderBy, order, debouncedSearch, filters]);

  return {
    params,
    page,
    setPage,
    perPage,
    setPerPage,
    search,
    setSearch,
    setFilter,
    setSort,
    orderBy,
    order,
    filters,
  };
}
