"use client";

import React, { useEffect, useMemo, useState } from "react";
import styles from "@/components/ui/Pagination/pagination.module.css";
import { usePathname, useSearchParams } from "next/navigation";

/**
 * @type {React.FC <{
 *    currentPage: number;
 *    totalPage: number;
 *    limit: number;
 *    sort?: object;
 *    getData: Function; // must have argument ({page, limit}, sort)
 *    setData: Function;
 *    getIsLoading: Function;
 *    sort: object;
 *    search?: string | null;
 * }>}
 * @returns {JSX.Element}
 */
const Pagination = (props) => {
  // expected [1,...,7,8,9,...,totalPage], 8 is current page
  const [currentPage, setCurrentPage] = useState(props.currentPage);
  const [isLoading, setIsLoading] = useState(false);

  const pathname = usePathname();
  const searchParams = useSearchParams();

  const sort = useMemo(() => {
    try {
      const SORT = Object.fromEntries(searchParams.entries())?.sort;
      return JSON.parse(SORT);
    } catch (error) {
      return props.sort;
    }
  }, [searchParams, props]);
  const search = useMemo(() => {
    try {
      const SEARCH = Object.fromEntries(searchParams.entries())?.search;
      return SEARCH;
    } catch (error) {
      return props?.search || null;
    }
  }, [searchParams, props]);

  useEffect(() => {
    const params = Object.fromEntries(searchParams.entries());
    if (!params.page) setCurrentPage(1);
  }, [searchParams]);

  const page = useMemo(() => {
    // role = array max length is 7
    const { totalPage } = props;
    const length = totalPage >= 7 ? 7 : totalPage;
    const isMoreThanRole = totalPage > 7;
    const init = Array(length).fill();
    const decoration = [
      isMoreThanRole && currentPage > 4 ? 1 : undefined,
      isMoreThanRole && currentPage < totalPage - 3 ? 5 : undefined,
    ].filter((v) => v);
    // [2,3,4] is navigation index on array
    const nav = [2, 3, 4];

    return init.map((_, index) => {
      // default
      let num = index + 1;

      // if currentPage more than 4 and less than totalPage - 3
      if (4 < currentPage && currentPage < totalPage - 3 && nav.includes(index))
        num = currentPage - 3 + index;
      // if currentPage more than totalPage - 4 (approch last page)
      if (isMoreThanRole && currentPage > totalPage - 4 && currentPage > 4)
        num = totalPage - 6 + index;

      // on index is decoration
      if (decoration.includes(index)) num = "_";

      // static index
      if (index === 6) num = totalPage;
      if (index === 0) num = 1;

      return num;
    });
  }, [props, currentPage]);

  const handleSetLoading = (status) => {
    if (props.getIsLoading && typeof props.getIsLoading === "function")
      props.getIsLoading(status);

    setIsLoading(status);
  };

  return (
    <div className={styles.container}>
      {page.map((item, index) => (
        <button
          key={index}
          disabled={isLoading}
          className={`${styles.button} ${
            item === currentPage && styles.active
          } ${item === "_" && styles.disabled}`}
          onClick={async () => {
            if (item === "_" || item === currentPage) return;

            setCurrentPage(item);
            handleSetLoading(true);

            const params = new URLSearchParams(searchParams);

            const data = await props.getData(
              {
                page: item,
                limit: props.limit,
              },
              sort || { createdAt: -1 },
              search
            );

            if (item !== 1) params.set("page", item);
            else params.delete("page");

            const newUrl = `${pathname}?${params.toString()}`;
            window.history.replaceState({}, "", newUrl);

            if (props.setData && typeof props.setData === "function")
              props.setData(data);

            handleSetLoading(false);
          }}>
          {item}
        </button>
      ))}
    </div>
  );
};

export default Pagination;
