import { SvelteComponentTyped } from "svelte";
import type { SvelteHTMLElements } from "svelte/elements";

type $RestProps = SvelteHTMLElements["div"];

type $Props = {
  /**
   * Specify the current page index.
   * @default 1
   */
  page?: number;

  /**
   * Specify the total number of items
   * @default 0
   */
  totalItems?: number;

  /**
   * If `totalItems` is a large number, it can affect the
   * rendering performance of this component since its value
   * is used to calculate the number of pages in the native
   * select dropdown. This value creates a small window of
   * pages rendered around the current page. By default,
   * a maximum of 1000 select items are rendered.
   * @default 1000
   */
  pageWindow?: number;

  /**
   * Set to `true` to disable the pagination
   * @default false
   */
  disabled?: boolean;

  /**
   * Specify the forward button text
   * @default "Next page"
   */
  forwardText?: string;

  /**
   * Specify the backward button text
   * @default "Previous page"
   */
  backwardText?: string;

  /**
   * Specify the items per page text
   * @default "Items per page:"
   */
  itemsPerPageText?: string;

  /**
   * Override the item text.
   */
  itemText?: (min: number, max: number) => string;

  /**
   * Override the item range text.
   */
  itemRangeText?: (min: number, max: number, total: number) => string;

  /**
   * Set to `true` to disable the page input
   * @default false
   */
  pageInputDisabled?: boolean;

  /**
   * Set to `true` to disable the page size input
   * @default false
   */
  pageSizeInputDisabled?: boolean;

  /**
   * Specify the number of items to display in a page.
   * @default 10
   */
  pageSize?: number;

  /**
   * Specify the available page sizes.
   * @default [10]
   */
  pageSizes?: ReadonlyArray<number>;

  /**
   * Set to `true` to dynamically filter page sizes based on total items.
   * Page sizes larger than needed to display all items on a single page are hidden.
   * @example
   *  <Pagination totalItems={9} pageSizes={[5, 10, 15]} dynamicPageSizes />
   *  <!-- renders [5, 10] -->
   * @default false
   */
  dynamicPageSizes?: boolean;

  /**
   * Set to `true` if the number of pages is unknown
   * @default false
   */
  pagesUnknown?: boolean;

  /**
   * Override the disabled state of the forward (next page) button.
   * Intended for use with `pagesUnknown` (controlled), where the consumer
   * knows when there is no more data to load.
   * @default undefined
   */
  forwardButtonDisabled?: boolean | undefined;

  /**
   * Override the disabled state of the backward (previous page) button.
   * Intended for use with `pagesUnknown` (controlled), where the consumer
   * manages page bounds.
   * @default undefined
   */
  backButtonDisabled?: boolean | undefined;

  /**
   * Override the page text.
   */
  pageText?: (page: number) => string;

  /**
   * Override the page range text.
   */
  pageRangeText?: (current: number, total: number) => string;

  /**
   * Set an id for the top-level element
   * @default `ccs-${Math.random().toString(36)}`
   */
  id?: string;

  /**
   * Specify the size of the pagination.
   * @default "md"
   */
  size?: "xs" | "sm" | "md" | "lg";

  [key: `data-${string}`]: unknown;
};

export type PaginationProps = Omit<$RestProps, keyof $Props> & $Props;

export default class Pagination extends SvelteComponentTyped<
  PaginationProps,
  {
    /** Dispatched when the user changes the page or page size through any interaction. */
    change: CustomEvent<{
        page?: number;
        pageSize?: number;
      }>;
    "click:button--next": CustomEvent<{
        page: number;
      }>;
    "click:button--previous": CustomEvent<{
        page: number;
      }>;
    update: CustomEvent<{
        pageSize: number;
        page: number;
      }>;
  },
  Record<string, never>
> {}
