<script lang="ts">
  import { ChevronLeft24, ChevronRight24 } from '@mozaic-ds/icons-svelte';
  import Button from '../button/Button.svelte';
  import IconButton from '../iconbutton/IconButton.svelte';
  /**
   * Pagination is a navigation component that allows users to browse through large sets of content by dividing it into discrete pages. It typically includes previous and next buttons, numeric page selectors, or dropdowns to jump between pages efficiently. Pagination improves usability and performance in content-heavy applications such as tables, search results, and articles by preventing long scrolls and reducing page load times.
   */
  interface Props {
    [key: string]: any;
    /**
     * A unique identifier for the pagination.
     */
    id: string;
    /**
     * The current value of the selected page.
     */
    value: number;
    /**
     * If `true`, display a compact version without the select.
     */
    compact?: boolean;
    /**
     * Total number of pages.
     */
    total?: number;
    /**
     * Accessible label for the select of the pagination.
     */
    selectLabel?: string;
    /**
     * Word displayed before the current page number.
     */
    prefixlabel?: string;
    /**
     * Word displayed between the current page number and total page number.
     */
    pagelabel?: string;
  }

  let {
    id,
    value = $bindable(1),
    total = 10,
    compact,
    selectLabel = 'Page selector',
    prefixlabel = 'Page',
    pagelabel = 'of',
    class: className,
    ...attrs
  }: Props = $props();

  const isFirstPage = $derived(() => value <= 1);
  const isLastPage = $derived(() => value >= total);

  const pages = $state(() => Array.from({ length: total }, (_, i) => i + 1));

  function updateValue(newValue: number) {
    value = newValue;
  }

  function previous() {
    if (!isFirstPage()) {
      updateValue(Number(value) - 1);
    }
  }

  function next() {
    if (!isLastPage()) {
      updateValue(Number(value) + 1);
    }
  }

  function onSelectChange(event: Event) {
    const newValue = (event.target as HTMLSelectElement).value;
    updateValue(Number(newValue));
  }
</script>

<nav class={['mc-pagination', className]} aria-label="pagination" {...attrs}>
  {#if !compact}
    <Button
      iconposition="only"
      aria-label="Previous page"
      disabled={isFirstPage()}
      onclick={previous}
    >
      <ChevronLeft24 slot="icon" />
    </Button>
  {:else}
    <IconButton outlined aria-label="Previous page" disabled={isFirstPage()} onclick={previous}>
      <ChevronLeft24 slot="icon" />
    </IconButton>
  {/if}

  {#if !compact}
    <div class="mc-pagination__field">
      <div class="mc-select mc-pagination__select">
        <select
          {id}
          class="mc-select__control"
          aria-label={selectLabel}
          disabled={total <= 1}
          bind:value
          onchange={onSelectChange}
        >
          {#each pages() as page, index (index)}
            <option value={Number(page)} selected={Number(page) == Number(value)}>
              {prefixlabel}
              {page}
              {pagelabel}
              {total}
            </option>
          {/each}
        </select>
      </div>
    </div>
  {:else}
    <span class="mc-pagination__label" aria-current="page">
      {prefixlabel}
      {value}
      {pagelabel}
      {total}
    </span>
  {/if}

  {#if !compact}
    <Button iconposition="only" aria-label="Next page" disabled={isLastPage()} onclick={next}>
      <ChevronRight24 slot="icon" />
    </Button>
  {:else}
    <IconButton outlined aria-label="Next page" disabled={isLastPage()} onclick={next}>
      <ChevronRight24 slot="icon" />
    </IconButton>
  {/if}
</nav>

<style>/**
 * Do not edit directly, this file was auto-generated.
 */
.mc-pagination {
  align-items: center;
  display: flex;
  justify-content: center;
  gap: 0.5rem;
}
.mc-pagination__label {
  height: 0;
  width: 0;
  overflow: hidden;
  position: absolute;
  top: -1000px;
  left: -1000px;
  text-align: left;
  opacity: 0;
}

/* stylelint-disable string-no-newline */
.mc-select {
  position: relative;
  display: block;
  width: 100%;
}
.mc-select::after {
  content: "";
  pointer-events: none;
  position: absolute;
  top: 50%;
  right: 1rem;
  transform: translateY(-50%);
  width: 1rem;
  height: 1rem;
  background-color: var(--forms-color-icon-interactive, #000000);
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='1rem' width='1rem' viewBox='0 0 16 16'%3E%3Cpath d='M8 11.5a1 1 0 01-.71-.29l-5-5a1 1 0 011.42-1.42L8 9.09l4.29-4.3a1 1 0 111.42 1.42l-5 5a1 1 0 01-.71.29z'/%3E%3C/svg%3E") no-repeat center/contain;
}
.mc-select__control {
  appearance: none;
  font-family: inherit;
  transition: box-shadow 200ms ease;
  font-size: var(--font-size-150, 1rem);
  line-height: var(--line-height-s, 1.3);
  height: 3rem;
  padding: 0 3rem 0 0.75rem;
  background-position: right 1rem center;
  border: var(--border-width-s, 0.0625rem) solid var(--forms-color-border-default, #666666);
  display: block;
  width: 100%;
  color: var(--forms-color-text-default, #000000);
  background-color: var(--forms-color-background-default, #ffffff);
  text-overflow: ellipsis;
  border-radius: var(--border-radius-s, 0.25rem);
}
.mc-select__control:hover {
  border-color: var(--forms-color-border-hover, #4d4d4d);
  box-shadow: 0 0 0 var(--border-width-s, 0.0625rem) var(--forms-color-border-hover, #4d4d4d);
}
.mc-select__control:focus {
  box-shadow: 0 0 0 0.125rem var(--focus-color-mid, var(--focus-color-outline-mid, #ffffff)), 0 0 0 0.25rem var(--focus-color-outer, var(--focus-color-outline-outer, #000000));
  outline: 0.125rem solid transparent;
  outline-offset: 0.125rem;
}
.mc-select__control:disabled {
  background-color: var(--forms-color-background-disabled, #d9d9d9);
  border-color: transparent;
  cursor: not-allowed;
  box-shadow: none;
  color: var(--forms-color-text-disabled, #737373);
}
.mc-select__control--readonly {
  border-color: var(--forms-color-border-read-only, #cccccc);
  pointer-events: none;
}
.mc-select__control.is-invalid {
  border-color: var(--forms-color-border-invalid, #ea302d);
  box-shadow: 0 0 0 var(--border-width-s, 0.0625rem) var(--forms-color-border-invalid, #ea302d);
}
.mc-select__control.is-invalid:hover {
  border-color: var(--forms-color-border-invalid-hover, #c61112);
  box-shadow: 0 0 0 var(--border-width-s, 0.0625rem) var(--forms-color-border-invalid-hover, #c61112);
}
.mc-select--s .mc-select__control {
  font-size: var(--font-size-100, 0.875rem);
  line-height: var(--line-height-s, 1.3);
  height: 2rem;
  padding: 0 2rem 0 0.5rem;
  background-position: right 0.5rem center;
}

/* stylelint-enable string-no-newline */</style>
