/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
import { c as customElement } from "../../chunks/runtime.js";
import { keyed } from "lit/directives/keyed.js";
import { css, html, nothing } from "lit";
import { LitElement, createEvent, safeClassMap } from "@arcgis/lumina";
import { n as numberStringFormatter } from "../../chunks/locale.js";
import { c as createObserver } from "../../chunks/observers.js";
import { b as breakpoints } from "../../chunks/responsive.js";
import { g as getIconScale } from "../../chunks/component.js";
import { u as useT9n } from "../../chunks/useT9n.js";
import { u as useSetFocus } from "../../chunks/useSetFocus.js";
const CSS = {
  list: "list",
  listItem: "list-item",
  hiddenItem: "hidden-item",
  page: "page",
  selected: "selected",
  chevron: "chevron",
  disabled: "disabled",
  ellipsis: "ellipsis"
};
const ICONS = {
  next: "chevron-right",
  previous: "chevron-left",
  first: "chevron-start",
  last: "chevron-end"
};
const styles = css`:host{display:flex;writing-mode:horizontal-tb}.list{margin:0;display:flex;list-style-type:none;padding:0;column-gap:var(--calcite-spacing-base)}.list-item{margin:0;display:flex;padding:0}.hidden-item{display:none}:host([scale=s]) .chevron,:host([scale=s]) .page,:host([scale=s]) .ellipsis{block-size:1.5rem;padding-inline:.25rem;font-size:var(--calcite-font-size-relative-sm);line-height:var(--calcite-font-line-height-sm);min-inline-size:1.5rem}:host([scale=m]) .chevron,:host([scale=m]) .page,:host([scale=m]) .ellipsis{block-size:2rem;padding-inline:.5rem;font-size:var(--calcite-font-size-relative-base);line-height:var(--calcite-font-line-height-base);min-inline-size:2rem}:host([scale=l]) .chevron,:host([scale=l]) .page,:host([scale=l]) .ellipsis{block-size:2.75rem;font-size:var(--calcite-font-size-relative-md);line-height:var(--calcite-font-line-height-md);min-inline-size:2.75rem}:host([scale=l]) .chevron{padding-inline:var(--calcite-space-sm-plus)}:host([scale=l]) .page,:host([scale=l]) .ellipsis{padding-inline:.75rem}:host button{outline-color:transparent}:host button:focus{outline:var(--calcite-border-width-md) solid var(--calcite-color-focus, var(--calcite-ui-focus-color, var(--calcite-color-brand)));outline-offset:calc(calc(-1 * var(--calcite-spacing-base)) * calc(1 - (2*clamp(0,var(--calcite-offset-invert-focus),1))))}.chevron,.page,.ellipsis{margin:0;box-sizing:border-box;display:flex;align-items:center;justify-content:center;border-style:none;--tw-border-opacity: 0;background-color:transparent;padding:0;vertical-align:baseline;font-family:inherit;font-size:var(--calcite-font-size-relative-md);line-height:var(--calcite-font-line-height-md);color:var(--calcite-pagination-color, var(--calcite-color-text-3))}.chevron,.page{cursor:pointer;border-block:2px solid transparent}.chevron:hover,.page:hover{transition-property:background-color,block-size,border-color,box-shadow,color,inset-block-end,inset-block-start,inset-inline-end,inset-inline-start,inset-size,opacity,outline-color,transform;transition-duration:var(--calcite-animation-timing);transition-timing-function:ease-in-out;color:var(--calcite-pagination-color-hover, var(--calcite-color-text-1))}.chevron:active,.page:active{color:var(--calcite-pagination-color-hover, var(--calcite-color-text-1))}.page:hover{border-block-end-color:var(--calcite-pagination-color-border-hover, var(--calcite-color-border-2))}.page:active{background-color:var(--calcite-pagination-background-color, var(--calcite-color-foreground-3))}.page.selected{font-weight:var(--calcite-font-weight-medium);color:var(--calcite-pagination-color-hover, var(--calcite-color-text-1));border-block-end-color:var(--calcite-pagination-color-border-active, var(--calcite-color-brand))}.page.selected:focus{border-block-end-width:var(--calcite-spacing-xxs);padding-block-start:var(--calcite-spacing-base)}.chevron:hover{background-color:var(--calcite-pagination-icon-color-background-hover, var(--calcite-color-foreground-2))}.chevron:active{background-color:var(--calcite-pagination-background-color, var(--calcite-color-foreground-3))}.chevron.disabled{pointer-events:none;background-color:transparent}.chevron.disabled>calcite-icon{opacity:var(--calcite-opacity-disabled)}:host([hidden]){display:none}[hidden]{display:none}`;
const firstAndLastPageCount = 2;
const ellipsisCount = 2;
const maxItemBreakpoints = {
  large: 11,
  medium: 9,
  small: 7,
  xsmall: 5,
  xxsmall: 1
};
class Pagination extends LitElement {
  constructor() {
    super(...arguments);
    this.resizeHandler = ({ contentRect: { width } }) => this.setMaxItemsToBreakpoint(width);
    this.resizeObserver = createObserver("resize", (entries) => entries.forEach(this.resizeHandler));
    this.messages = useT9n();
    this.focusSetter = useSetFocus()(this);
    this.isXXSmall = false;
    this.lastStartItem = 1;
    this.maxItems = maxItemBreakpoints.xxsmall;
    this.totalPages = 1;
    this.groupSeparator = false;
    this.pageSize = 20;
    this.scale = "m";
    this.startItem = 1;
    this.totalItems = 0;
    this.calcitePaginationChange = createEvent({ cancelable: false });
  }
  static {
    this.properties = { isXXSmall: [16, {}, { state: true }], lastStartItem: [16, {}, { state: true }], maxItems: [16, {}, { state: true }], totalPages: [16, {}, { state: true }], groupSeparator: [7, {}, { reflect: true, type: Boolean }], messageOverrides: [0, {}, { attribute: false }], numberingSystem: 1, pageSize: [11, {}, { reflect: true, type: Number }], scale: [3, {}, { reflect: true }], startItem: [11, {}, { reflect: true, type: Number }], totalItems: [11, {}, { reflect: true, type: Number }] };
  }
  static {
    this.shadowRootOptions = { mode: "open", delegatesFocus: true };
  }
  static {
    this.styles = styles;
  }
  async goTo(page) {
    switch (page) {
      case "start":
        this.startItem = 1;
        break;
      case "end":
        this.startItem = this.lastStartItem;
        break;
      default: {
        if (page >= Math.ceil(this.totalPages)) {
          this.startItem = this.lastStartItem;
        } else if (page <= 0) {
          this.startItem = 1;
        } else {
          this.startItem = (page - 1) * this.pageSize + 1;
        }
      }
    }
  }
  async nextPage() {
    this.startItem = Math.min(this.lastStartItem, this.startItem + this.pageSize);
  }
  async previousPage() {
    this.startItem = Math.max(1, this.startItem - this.pageSize);
  }
  async setFocus(options) {
    return this.focusSetter(() => this.el, options);
  }
  connectedCallback() {
    super.connectedCallback();
    this.resizeObserver?.observe(this.el);
  }
  async load() {
    this.handleTotalPages();
    this.handleLastStartItemChange();
    this.handleIsXXSmall();
  }
  willUpdate(changes) {
    if (changes.has("totalItems") && (this.hasUpdated || this.totalItems !== 0) || changes.has("pageSize") && (this.hasUpdated || this.pageSize !== 20)) {
      this.handleTotalPages();
    }
    if (changes.has("totalItems") && (this.hasUpdated || this.totalItems !== 0) || changes.has("pageSize") && (this.hasUpdated || this.pageSize !== 20) || changes.has("totalPages")) {
      this.handleLastStartItemChange();
    }
    if (changes.has("maxItems") && (this.hasUpdated || this.maxItems !== maxItemBreakpoints.xxsmall)) {
      this.handleIsXXSmall();
    }
    if (changes.has("messages")) {
      this.effectiveLocaleChange();
    }
  }
  loaded() {
    this.setMaxItemsToBreakpoint(this.el.clientWidth);
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this.resizeObserver?.disconnect();
  }
  handleTotalPages() {
    this.pageSize = Math.max(1, this.pageSize);
    this.totalPages = Math.max(1, this.totalItems / this.pageSize);
  }
  effectiveLocaleChange() {
    numberStringFormatter.numberFormatOptions = {
      locale: this.messages._lang,
      numberingSystem: this.numberingSystem,
      useGrouping: this.groupSeparator
    };
  }
  handleLastStartItemChange() {
    const { totalItems, pageSize } = this;
    this.lastStartItem = Math.max(1, Math.floor((totalItems - 1) / pageSize) * pageSize + 1);
  }
  handleIsXXSmall() {
    this.isXXSmall = this.maxItems === maxItemBreakpoints.xxsmall;
  }
  setMaxItemsToBreakpoint(width) {
    if (!breakpoints || !width) {
      return;
    }
    if (width >= breakpoints.width.medium) {
      this.maxItems = maxItemBreakpoints.large;
      return;
    }
    if (width >= breakpoints.width.small) {
      this.maxItems = maxItemBreakpoints.medium;
      return;
    }
    if (width >= breakpoints.width.xsmall) {
      this.maxItems = maxItemBreakpoints.small;
      return;
    }
    if (width >= breakpoints.width.xxsmall) {
      this.maxItems = maxItemBreakpoints.xsmall;
      return;
    }
    this.maxItems = maxItemBreakpoints.xxsmall;
  }
  firstClicked() {
    this.startItem = 1;
    this.emitUpdate();
  }
  lastClicked() {
    this.startItem = this.lastStartItem;
    this.emitUpdate();
  }
  async previousClicked() {
    await this.previousPage();
    this.emitUpdate();
  }
  async nextClicked() {
    await this.nextPage();
    this.emitUpdate();
  }
  showStartEllipsis() {
    return this.totalPages > this.maxItems && Math.floor(this.startItem / this.pageSize) > this.maxItems - firstAndLastPageCount - ellipsisCount;
  }
  showEndEllipsis() {
    return this.totalPages > this.maxItems && (this.totalItems - this.startItem) / this.pageSize > this.maxItems - firstAndLastPageCount - (ellipsisCount - 1);
  }
  emitUpdate() {
    this.calcitePaginationChange.emit();
  }
  handlePageClick(event) {
    const target = event.target;
    this.startItem = parseInt(target.value);
    this.emitUpdate();
  }
  renderEllipsis(type) {
    return keyed(type, html`<span class=${safeClassMap(CSS.ellipsis)}>&hellip;</span>`);
  }
  renderItems() {
    const { totalItems, pageSize, startItem, maxItems, totalPages, lastStartItem, isXXSmall } = this;
    const items = [];
    if (isXXSmall) {
      items.push(this.renderPage(startItem));
      return items;
    }
    const renderFirstPage = totalItems > pageSize;
    const renderStartEllipsis = this.showStartEllipsis();
    const renderEndEllipsis = this.showEndEllipsis();
    if (renderFirstPage) {
      items.push(this.renderPage(1));
    }
    if (renderStartEllipsis) {
      items.push(this.renderEllipsis("start"));
    }
    const remainingItems = maxItems - firstAndLastPageCount - (renderEndEllipsis ? 1 : 0) - (renderStartEllipsis ? 1 : 0);
    let end;
    let nextStart;
    if (totalPages - 1 <= remainingItems) {
      nextStart = 1 + pageSize;
      end = lastStartItem - pageSize;
    } else {
      if (startItem / pageSize < remainingItems) {
        nextStart = 1 + pageSize;
        end = 1 + remainingItems * pageSize;
      } else {
        if (startItem + remainingItems * pageSize >= totalItems) {
          nextStart = lastStartItem - remainingItems * pageSize;
          end = lastStartItem - pageSize;
        } else {
          nextStart = startItem - pageSize * ((remainingItems - 1) / 2);
          end = startItem + pageSize * ((remainingItems - 1) / 2);
        }
      }
    }
    for (let i = 0; i < remainingItems && nextStart <= end; i++) {
      items.push(this.renderPage(nextStart));
      nextStart = nextStart + pageSize;
    }
    if (renderEndEllipsis) {
      items.push(this.renderEllipsis("end"));
    }
    items.push(this.renderPage(lastStartItem));
    return items;
  }
  renderPage(start) {
    const { pageSize } = this;
    const page = Math.floor(start / pageSize) + (pageSize === 1 ? 0 : 1);
    numberStringFormatter.numberFormatOptions = {
      locale: this.messages._lang,
      numberingSystem: this.numberingSystem,
      useGrouping: this.groupSeparator
    };
    const displayedPage = numberStringFormatter.localize(page.toString());
    const selected = start === this.startItem;
    return html`<li class=${safeClassMap(CSS.listItem)}><button .ariaCurrent=${selected ? "page" : "false"} class=${safeClassMap({
      [CSS.page]: true,
      [CSS.selected]: selected
    })} @click=${this.handlePageClick} value=${start ?? nothing}>${displayedPage}</button></li>`;
  }
  renderPreviousChevron() {
    const { pageSize, startItem, messages } = this;
    const disabled = pageSize === 1 ? startItem <= pageSize : startItem < pageSize;
    return keyed("previous", html`<button .ariaLabel=${messages.previous} class=${safeClassMap({
      [CSS.chevron]: true,
      [CSS.disabled]: disabled
    })} .disabled=${disabled} @click=${this.previousClicked}><calcite-icon flip-rtl .icon=${ICONS.previous} .scale=${getIconScale(this.scale)}></calcite-icon></button>`);
  }
  renderNextChevron() {
    const { totalItems, pageSize, startItem, messages } = this;
    const disabled = pageSize === 1 ? startItem + pageSize > totalItems : startItem + pageSize > totalItems;
    return keyed("next-button", html`<button .ariaLabel=${messages.next} class=${safeClassMap({
      [CSS.chevron]: true,
      [CSS.disabled]: disabled
    })} .disabled=${disabled} @click=${this.nextClicked}><calcite-icon flip-rtl .icon=${ICONS.next} .scale=${getIconScale(this.scale)}></calcite-icon></button>`);
  }
  renderFirstChevron() {
    const { messages, startItem, isXXSmall } = this;
    const disabled = startItem === 1;
    return isXXSmall ? keyed("first-button", html`<button .ariaLabel=${messages.first} class=${safeClassMap({
      [CSS.chevron]: true,
      [CSS.disabled]: disabled
    })} .disabled=${disabled} @click=${this.firstClicked}><calcite-icon flip-rtl .icon=${ICONS.first} .scale=${getIconScale(this.scale)}></calcite-icon></button>`) : null;
  }
  renderLastChevron() {
    const { messages, startItem, isXXSmall, lastStartItem } = this;
    const disabled = startItem === lastStartItem;
    return isXXSmall ? keyed("last-button", html`<button .ariaLabel=${messages.last} class=${safeClassMap({
      [CSS.chevron]: true,
      [CSS.disabled]: disabled
    })} .disabled=${disabled} @click=${this.lastClicked}><calcite-icon flip-rtl .icon=${ICONS.last} .scale=${getIconScale(this.scale)}></calcite-icon></button>`) : null;
  }
  render() {
    const firstChevron = this.renderFirstChevron();
    const lastChevron = this.renderLastChevron();
    return html`<ul class=${safeClassMap(CSS.list)}><li class=${safeClassMap({
      [CSS.listItem]: true,
      [CSS.hiddenItem]: !firstChevron
    })}>${firstChevron}</li><li class=${safeClassMap(CSS.listItem)}>${this.renderPreviousChevron()}</li>${this.renderItems()}<li class=${safeClassMap(CSS.listItem)}>${this.renderNextChevron()}</li><li class=${safeClassMap({
      [CSS.listItem]: true,
      [CSS.hiddenItem]: !lastChevron
    })}>${lastChevron}</li></ul>`;
  }
}
customElement("calcite-pagination", Pagination);
export {
  Pagination
};
