import { useEffect } from "react";
import { IPagination } from "#lib/pagination";
import { parseInt } from "#lib/numbers";
import { DescriptionList, DescriptionSection } from "#components/lists";
import {
  ButtonSubmit,
  FormClient,
  FormSection,
  type ISubmitEvent,
} from "#components/forms";
import { FormSectionInteger } from "#components/forms/sections";
import { Button } from "#components/buttons";

import * as styles from "./local.module.scss";

interface IProps {
  pagination: IPagination;

  formID: string;
  onPageChange: (nextPage: number) => Promise<void>;
}

/**
 * Pagination for lists which do not incur navigation.
 */
export function PaginationLocal({ pagination, onPageChange, formID }: IProps) {
  const { total_pages, current_page } = pagination;
  const previousPage = Math.max(current_page - 1, 1);
  const nextPage = Math.min(current_page + 1, total_pages);

  return (
    <div className={styles.block}>
      <ul className={styles.list}>
        <li className={styles.current}>
          {total_pages === 1 ? (
            <DescriptionList className={styles.single}>
              <DescriptionSection
                dKey="Current page"
                dValue={current_page}
                isValuePreformatted
              />
            </DescriptionList>
          ) : (
            <CurrentPage
              pagination={pagination}
              formID={formID}
              onPageChange={onPageChange}
            />
          )}
        </li>

        <li className={styles.previous}>
          <Button
            className={styles.page}
            disabled={current_page === 1}
            onClick={async () => await onPageChange(previousPage)}
          >
            Previous
          </Button>
        </li>

        <li className={styles.next}>
          <Button
            className={styles.page}
            disabled={current_page === total_pages}
            onClick={async () => await onPageChange(nextPage)}
          >
            Next
          </Button>
        </li>

        <li className={styles.first}>
          <Button
            className={styles.page}
            disabled={current_page === 1}
            onClick={async () => await onPageChange(1)}
          >
            First
          </Button>
        </li>

        <li className={styles.last}>
          <Button
            className={styles.page}
            disabled={current_page === total_pages}
            onClick={async () => await onPageChange(total_pages)}
          >
            Last
          </Button>
        </li>
      </ul>
    </div>
  );
}

interface ICurrentPageProps
  extends Pick<IProps, "pagination" | "onPageChange" | "formID"> {}

function CurrentPage({ pagination, formID, onPageChange }: ICurrentPageProps) {
  const { current_page, total_pages } = pagination;

  // change the value of uncontrolled input
  // without going through whole controlled input setup
  useEffect(() => {}, [current_page]);

  async function handlePageChange(event: ISubmitEvent) {
    const nextPageValue = event.currentTarget.elements["page"]?.value.trim();

    if (!nextPageValue) {
      return;
    }

    const nextPage = parseInt(nextPageValue);

    if (nextPage === current_page) {
      return;
    }

    await onPageChange(nextPage);
  }

  return (
    <FormClient
      className={styles.form}
      statusSection={null}
      onSubmit={handlePageChange}
    >
      {(state) => (
        <>
          <FormSectionInteger
            key={current_page}
            id={`${formID}-page`}
            className={styles.number}
            name="page"
            label="Current page"
            min={1}
            max={total_pages}
            defaultValue={current_page}
          />

          <FormSection className={styles.submit}>
            <ButtonSubmit disabled={state !== "idle"}>Go</ButtonSubmit>
          </FormSection>
        </>
      )}
    </FormClient>
  );
}
