import "./style.pcss";

import {
  useCallback,
  useEffect,
  useMemo,
  useState,
} from "react";
import type {
  FC, MouseEvent, ChangeEvent, ReactElement,
} from "react";
import { getWindow } from "ssr-window";
import type { IPagination, IPaginationItem } from "./config/types";
import { PaginationContext } from "./context";
import { PaginationItem } from "./ui/PaginationItem";
import type { IComponentBaseProps } from "../../types/components";
import { useCN } from "../../utils/react/useCN";
import type { IInputStateActions } from "../input/config/types";

/**
 * Компонент пагинации
 * @returns {ReactElement}
 */
const Pagination: FC<IPagination & IComponentBaseProps> = ({
  baseClass = "pagination",
  name,
  form = null,
  children = null,
  items = [],
  extraClasses = {},
  extraAttrs = {},
  separator = "...",
  onClick = null,
  onChange = null,
}): ReactElement => {

  const { getCN } = useCN(baseClass);

  const [ pages, setPages ] = useState(items);
  useEffect(() => {
    setPages(items);
  }, [ items ]);

  const handleChange = useCallback((
    e: { event: ChangeEvent; data: IPaginationItem; stateActions: IInputStateActions; }
  ) => {
    if (typeof onChange === "function") {
      onChange({ ...e, pages, setPages });
    } else {
      const { stateActions, data } = e;
      stateActions.setInputCheckedState(true);
      setPages((prevPagesState) => {
        return prevPagesState.map((item) => ({
          ...item,
          isActive: data.page === item.page,
        }));
      });
    }
  }, [ pages, onChange ]);

  const handleClick = useCallback((
    { event, data }:
    { event: MouseEvent; data: IPaginationItem; }
  ) => {
    if (typeof onClick === "function") {
      onClick({
        event, data, pages, setPages,
      });
    } else if (data.href) {
      event.preventDefault();
      getWindow().location.href = data.href;
    }
  }, [ pages, onClick ]);

  const ctx = useMemo(() => ({
    getCN, pages, form, separator, name, handleChange, handleClick,
  }), [ pages, form, separator, name, handleChange, handleClick ]);

  return (
    <PaginationContext value={ctx}>
      <nav>
        <ul className={getCN("", extraClasses)} {...extraAttrs}>
          {!!pages.length && pages.map((page) => {
            const key = page.name || page.href || page.label || `page_${page.page ?? "separator"}`;
            return <PaginationItem key={key} {...page} />;
          })}
          {children && (
            <li className={getCN("item", { isExtra: true })}>
              {children}
            </li>
          )}
        </ul>
      </nav>
    </PaginationContext>
  );
};

export type {
  IPagination,
  IPaginationItem,
};
export { Pagination };
