import { ArrowLeftIcon, ArrowRightIcon } from "@heroicons/react/24/outline";
import { Button, IconButton } from "@material-tailwind/react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import React, { useCallback, useEffect, useMemo } from "react";

export type TablePaginationComponentProps = {
  totalPage: number;
  total?: number;
  currentPage: number;
  limit: number;
  fetchOrders: ({
    page,
    limit,
    keyword,
  }: {
    page: number;
    limit: number;
    keyword?: string;
  }) => Promise<any>;
};

const MAX_VISIBLE_PAGES = 6;

export function TablePaginationComponent({
  totalPage,
  total,
  limit,
  fetchOrders,
}: TablePaginationComponentProps) {
  const searchParams = useSearchParams();
  const [active, setActive] = React.useState(1);
  const { push } = useRouter();
  const pathname = usePathname();

  useEffect(() => {
    const page = parseInt(`${searchParams.get("page") ?? 1}`);
    (async () => await setActive(page))();
  }, [searchParams, setActive]);

  // Remove the separate useEffect for fetching and handle it in the pagination actions
  const handlePaginate = useCallback(
    async (page: number) => {
      push(`${pathname}?page=${page}`);
      await fetchOrders({ page, limit });
    },
    [pathname, push, fetchOrders, limit],
  );

  const getItemProps = useCallback(
    (index: number) =>
      ({
        variant: active === index ? "filled" : "text",
        color: "gray",
        onClick: () => handlePaginate(index),
      }) as any,
    [active, handlePaginate],
  );

  const next = useCallback(async () => {
    if (active === totalPage) return;
    const nextPage = active + 1;
    setActive(nextPage);
    await handlePaginate(nextPage);
  }, [active, totalPage, handlePaginate]);

  const prev = useCallback(async () => {
    if (active === 1) return;
    const prevPage = active - 1;
    setActive(prevPage);
    await handlePaginate(prevPage);
  }, [active, handlePaginate]);

  const renderBtn = useMemo(() => {
    const totalPages = total ? Math.ceil(total / limit) : totalPage;
    const startPage = Math.max(
      1,
      (active == totalPages ? active - 1 : active) -
        Math.floor(MAX_VISIBLE_PAGES / 2),
    );
    const endPage = Math.min(totalPages, startPage - 1 + MAX_VISIBLE_PAGES - 1);

    const items = [];

    // Always show the first page
    items.push(
      <IconButton key={1} {...getItemProps(1)}>
        1
      </IconButton>,
    );

    if (active != 1) {
      // Show ellipsis if necessary
      if (startPage > 2) {
        items.push(<span key="ellipsis">...</span>);
      }
    }

    // Render the visible page numbers
    for (let i = startPage + 1; i <= endPage; i++) {
      if (i == totalPages) continue;
      items.push(
        <IconButton key={i} {...getItemProps(i)}>
          {i}
        </IconButton>,
      );
    }

    if (active != totalPages) {
      // Show ellipsis if necessary
      if (endPage < totalPages - 1) {
        items.push(<span key="ellipsis">...</span>);
      }
    }

    if (totalPages > 1) {
      // Always show the last page
      items.push(
        <IconButton key={totalPages} {...getItemProps(totalPages)}>
          {totalPages}
        </IconButton>,
      );
    }

    return items;
  }, [total, totalPage, limit, active, getItemProps]);

  return (
    <div className="w-full overflow-x-auto overflow-y-hidden py-2">
      <div className="flex items-center gap-4 my-5">
        <Button
          variant="text"
          className="flex items-center gap-2"
          onClick={prev}
          disabled={active === 1}
        >
          <ArrowLeftIcon strokeWidth={2} className="h-4 w-4" /> Previous
        </Button>
        <div className="flex items-center gap-2">{renderBtn}</div>
        <Button
          variant="text"
          className="flex items-center gap-2"
          onClick={next}
          disabled={active === totalPage}
        >
          Next
          <ArrowRightIcon strokeWidth={2} className="h-4 w-4" />
        </Button>
      </div>
    </div>
  );
}
