import { FC, useCallback, useMemo, useState } from "react";
import { GoChevronLeft, GoChevronRight } from "react-icons/go";
import Select from "react-select";
import Button from "@/components/generics/button/Button";
import { PaginationType } from "@/api/documents/types";
import "./Pagination.scss";
import Input from "@/components/generics/input/Input";

interface PageSizeOption {
  value: number;
  label: string;
}

export type PaginationProps = PaginationType & {
  setPage: React.Dispatch<React.SetStateAction<number>>;
  setPageSize: React.Dispatch<React.SetStateAction<number>>;
};

const pageSizeOptions: PageSizeOption[] = [
  { value: 10, label: "10 / стр." },
  { value: 20, label: "20 / стр." },
  { value: 50, label: "50 / стр." },
  { value: 100, label: "100 / стр." },
];

export const Pagination: FC<PaginationProps> = ({ total, pageNumber, pageSize, setPage, setPageSize }) => {
  const [searchPage, setSearchPage] = useState<string | null>(null);
  const totalPages = Math.ceil(total / pageSize);

  const handleChange = useCallback(
    (page: number) => {
      setPage(page);
    },
    [setPage]
  );

  const handlePageSizeChange = (selectedOption: PageSizeOption | null) => {
    if (selectedOption) {
      setPageSize(selectedOption.value);
      setPage(0);
    }
  };

  const pages = useMemo(() => {
    let startPage = 1;
    let endPage = totalPages;

    if (totalPages > 5) {
      if (pageNumber + 1 <= 3) {
        endPage = 5;
      } else if (pageNumber + 3 >= totalPages) {
        startPage = totalPages - 4;
      } else {
        startPage = pageNumber - 1;
        endPage = pageNumber + 3;
      }
    }

    const pageNumbers = [];
    if (startPage > 1) {
      pageNumbers.push(
        <Button
          key={1}
          name={`${1}`}
          onClick={() => {
            handleChange(0);
          }}
          className={`item ${pageNumber + 1 === 1 ? "active" : ""}`}
        />
      );

      if (startPage > 2) {
        pageNumbers.push(<span key="ellipsis-start">...</span>);
      }
    }
    for (let i = startPage; i <= endPage; i++) {
      pageNumbers.push(
        <Button
          key={i}
          name={`${i}`}
          onClick={() => {
            handleChange(i - 1);
          }}
          className={`item ${pageNumber + 1 === i ? "active" : ""}`}
        />
      );
    }
    if (endPage < totalPages) {
      if (endPage < totalPages - 1) {
        pageNumbers.push(<span key="ellipsis-end">...</span>);
      }
      pageNumbers.push(
        <Button
          key={totalPages}
          name={`${totalPages}`}
          onClick={() => {
            handleChange(totalPages - 1);
          }}
          className={`item ${pageNumber + 1 === totalPages ? "active" : ""}`}
        />
      );
    }

    return pageNumbers;
  }, [handleChange, pageNumber, totalPages]);

  const handleEnterPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.key === "Enter" && searchPage) {
      const pageNumberToGo = Number(searchPage);
      if (pageNumberToGo >= 1 && pageNumberToGo <= totalPages) {
        setPage(pageNumberToGo - 1);
      }
    }
  };

  return (
    <div className="pagination">
      <Button
        onClick={() => {
          handleChange(pageNumber - 1);
        }}
        icon={<GoChevronLeft />}
        buttonType="link"
        disabled={pageNumber === 0}
      />
      {pages}
      <Button
        onClick={() => {
          handleChange(pageNumber + 1);
        }}
        icon={<GoChevronRight />}
        buttonType="link"
        disabled={pageNumber === totalPages - 1}
      />
      <div className="page-actions">
        <Input
          name=""
          type="number"
          max={totalPages.toString()}
          min="0"
          step="1"
          placeholder="Номер страницы"
          value={searchPage?.toString()}
          onSetValue={(value) => setSearchPage(value)}
          onKeyDown={handleEnterPress}
          extra={
            <Button
              disabled={!searchPage}
              icon={<GoChevronRight style={{ width: "18px", height: "18px" }} />}
              onClick={() => (Number(searchPage) && Number(searchPage) >= 1 ? setPage(Number(searchPage) - 1) : null)}
              buttonType="link"
            />
          }
        />
        <Select
          options={pageSizeOptions}
          value={pageSizeOptions.find((option) => option.value === pageSize)}
          onChange={handlePageSizeChange}
          isSearchable={false}
          classNamePrefix="react-select"
          theme={(theme) => ({
            ...theme,
            colors: {
              ...theme.colors,
              text: "orangered",
              primary25: "var(--primary-color)",
              primary50: "var(--primary-color)",
              primary: "var(--secondary-color)",
            },
          })}
        />
      </div>
    </div>
  );
};
