import { createTextVNode as _createTextVNode, createVNode as _createVNode } from "vue";
import "./styles/pagination.css";
import { computed, nextTick, ref } from "vue";
import { createRange, keyValues } from "@veno-ui/utils";
import { defineComponent } from "../../utils";
import { Button } from "../button";
import { Select } from "../select";
import { Input } from "../input";
import { makePaperProps, usePaper } from "../../composables/paper";
import { useResizeObserver } from "../../composables/resize-observer";
import { useRefs } from "../../composables/refs";
import { useProxiedModel } from "../../composables/proxied-model";
const Pagination = defineComponent({
  name: "VePagination",
  props: {
    /**
     * @zh 激活时的颜色
     */
    activeColor: {
      type: String,
      default: "primary"
    },
    /**
     * @zh 导航的无障碍标签值
     */
    ariaLabel: {
      type: String,
      default: "\u5206\u9875\u5BFC\u822A"
    },
    /**
     * @zh 当前页的无障碍标签值
     */
    currentPageAriaLabel: {
      type: String,
      default: "\u5F53\u524D\u9875 {0}"
    },
    /**
     * @zh 是否禁用
     */
    disabled: Boolean,
    /**
     * @zh 省略值
     */
    ellipsis: {
      type: String,
      default: "..."
    },
    /**
     * @zh 第一页的无障碍标签值
     */
    firstAriaLabel: {
      type: String,
      default: "\u9996\u9875"
    },
    /**
     * @zh 第一页初始值
     */
    firstPage: {
      type: [Number, String],
      default: 1
    },
    /**
     * @zh 第一页的按钮图标
     */
    firstIcon: {
      type: String,
      default: "$first"
    },
    /**
     * @zh 最后一页的无障碍标签值
     */
    lastAriaLabel: {
      type: String,
      default: "\u6700\u540E\u9875"
    },
    /**
     * @zh 最后一页的按钮图标
     */
    lastIcon: {
      type: String,
      default: "$last"
    },
    /**
     * @zh 当前页
     */
    modelValue: {
      type: [Number, String],
      default: (props) => props.firstPage,
      validator: (val) => val % 1 === 0
    },
    /**
     * @zh 下一页的无障碍标签值
     */
    nextAriaLabel: {
      type: String,
      default: "\u4E0B\u4E00\u9875"
    },
    /**
     * @zh 下一页的按钮图标
     */
    nextIcon: {
      type: String,
      default: "$next"
    },
    /**
     * @zh 上一页的按钮图标
     */
    prevIcon: {
      type: String,
      default: "$prev"
    },
    /**
     * @zh 页面的无障碍标签值
     */
    pageAriaLabel: {
      type: String,
      default: "\u8F6C\u5230\u9875\u9762 {0}"
    },
    /**
     * @zh 每页条数
     */
    perPage: {
      type: [Number, String],
      default: 10,
      validator: (val) => val % 1 === 0
    },
    /**
     * @zh 每页条数可选项
     */
    perPageOptions: {
      type: Array,
      default: () => [10, 20, 50, 100]
    },
    /**
     * @zh 上一页的无障碍标签值
     */
    previousAriaLabel: {
      type: String,
      default: "\u4E0A\u4E00\u9875"
    },
    /**
     * @zh 显示首页和最后一页
     */
    showFirstLastPage: Boolean,
    /**
     * @zh 显示快速跳跃
     */
    showQuickJumper: Boolean,
    /**
     * @zh 显示每页条数选择器
     */
    showPerPageSelect: Boolean,
    /**
     * @zh 总条数
     */
    total: {
      type: [Number, String],
      default: 0,
      validator: (val) => val % 1 === 0
    },
    /**
     * @zh 总显示页数
     */
    totalVisible: {
      type: [Number, String],
      validator: (val) => val % 1 === 0
    },
    ...makePaperProps({
      tag: "nav",
      variant: "text",
      shape: "rounded-sm"
    })
  },
  emits: {
    "update:modelValue": (_modelValue) => true,
    "update:perPage": (_perPage) => true,
    "first": (_value) => true,
    "prev": (_value) => true,
    "next": (_value) => true,
    "last": (_value) => true
  },
  setup(props, {
    slots,
    emit
  }) {
    const internalPage = ref();
    const {
      paperClasses,
      paperStyles
    } = usePaper(props);
    const page = useProxiedModel(props, "modelValue", props.modelValue, (v) => parseInt(v ?? 1, 10));
    const perPage = useProxiedModel(props, "perPage", props.perPage, (v) => parseInt(v ?? 10, 10));
    const total = computed(() => parseInt(props.total, 10));
    const firstPage = computed(() => parseInt(props.firstPage, 10));
    const lastPage = computed(() => Math.ceil(total.value / perPage.value));
    const maxButtons = ref(-1);
    const {
      resizeRef
    } = useResizeObserver((entries) => {
      if (!entries.length)
        return;
      const {
        target,
        contentRect
      } = entries[0];
      const firstItem = target.querySelector(".ve-pagination__wrapper > *");
      if (!firstItem)
        return;
      let totalWidth = contentRect.width - 96;
      if (props.showPerPageSelect)
        totalWidth -= 100;
      if (props.showQuickJumper)
        totalWidth -= 100;
      const itemWidth = firstItem.getBoundingClientRect().width + 10;
      maxButtons.value = Math.max(0, Math.floor(totalWidth / itemWidth));
    });
    const totalVisible = computed(() => {
      if (props.totalVisible)
        return Math.min(parseInt(props.totalVisible, 10), lastPage.value);
      if (maxButtons.value >= 0)
        return maxButtons.value;
      return Math.min(7, lastPage.value);
    });
    const range = computed(() => {
      if (lastPage.value <= 0)
        return [];
      if (totalVisible.value === 1)
        return [Math.min(Math.max(firstPage.value, page.value), firstPage.value + lastPage.value)];
      if (lastPage.value <= totalVisible.value)
        return createRange(lastPage.value, firstPage.value);
      const middle = Math.ceil(totalVisible.value / 2);
      const left = middle;
      const right = lastPage.value - middle;
      if (page.value < left) {
        return [...createRange(Math.max(1, totalVisible.value - 2), firstPage.value), props.ellipsis, lastPage.value];
      }
      if (page.value > right) {
        const rangeLength2 = totalVisible.value - 2;
        const rangeStart2 = lastPage.value - rangeLength2 + firstPage.value;
        return [firstPage.value, props.ellipsis, ...createRange(rangeLength2, rangeStart2)];
      }
      const rangeLength = Math.max(1, totalVisible.value - 4);
      const rangeStart = rangeLength === 1 ? page.value : page.value - Math.ceil(rangeLength / 2) + firstPage.value;
      return [firstPage.value, props.ellipsis, ...createRange(rangeLength, rangeStart), props.ellipsis, lastPage.value];
    });
    function setValue(e, value, event) {
      e.preventDefault();
      page.value = value;
      event && emit(event, value);
    }
    const {
      refs,
      updateRef
    } = useRefs();
    const items = computed(() => {
      const sharedProps = {
        density: props.density,
        shape: props.shape,
        size: props.size
      };
      return range.value.map((item, index) => {
        const ref2 = (e) => updateRef(e, index);
        if (typeof item === "string") {
          return {
            isActive: false,
            page: item,
            props: {
              ...sharedProps,
              ref: ref2,
              ellipsis: true,
              icon: true,
              disabled: true,
              variant: props.variant,
              border: props.border
            }
          };
        } else {
          const isActive = item === page.value;
          return {
            isActive,
            page: item,
            props: {
              ...sharedProps,
              ref: ref2,
              ellipsis: false,
              icon: true,
              disabled: props.disabled || lastPage.value < 2,
              elevation: props.elevation,
              variant: isActive ? "outlined" : props.variant,
              border: props.border,
              color: isActive ? props.activeColor : void 0,
              ariaCurrent: isActive,
              ariaLabel: isActive ? props.currentPageAriaLabel : props.pageAriaLabel,
              onClick: (e) => setValue(e, item)
            }
          };
        }
      });
    });
    const controls = computed(() => {
      const sharedProps = {
        color: void 0,
        density: props.density,
        shape: props.shape,
        size: props.size,
        variant: "outlined",
        border: props.border
      };
      const prevDisabled = props.disabled || page.value <= firstPage.value;
      const nextDisabled = props.disabled || page.value >= firstPage.value + lastPage.value - 1;
      return {
        first: props.showFirstLastPage ? {
          ...sharedProps,
          icon: props.firstIcon,
          onClick: (e) => setValue(e, firstPage.value, "first"),
          disabled: prevDisabled,
          ariaLabel: props.firstAriaLabel,
          ariaDisabled: prevDisabled
        } : void 0,
        prev: {
          ...sharedProps,
          icon: props.prevIcon,
          onClick: (e) => setValue(e, page.value - 1, "prev"),
          disabled: prevDisabled,
          ariaLabel: props.previousAriaLabel,
          ariaDisabled: prevDisabled
        },
        next: {
          ...sharedProps,
          icon: props.nextIcon,
          onClick: (e) => setValue(e, page.value + 1, "next"),
          disabled: nextDisabled,
          ariaLabel: props.nextAriaLabel,
          ariaDisabled: nextDisabled
        },
        last: props.showFirstLastPage ? {
          ...sharedProps,
          icon: props.lastIcon,
          onClick: (e) => setValue(e, firstPage.value + lastPage.value - 1, "last"),
          disabled: nextDisabled,
          ariaLabel: props.lastAriaLabel,
          ariaDisabled: nextDisabled
        } : void 0
      };
    });
    function updateFocus() {
      const currentIndex = page.value - firstPage.value;
      refs.value[currentIndex]?.$el.focus();
    }
    function onKeydown({
      key
    }) {
      if (key === keyValues.left && !props.disabled && page.value > firstPage.value) {
        page.value = page.value - 1;
        nextTick(updateFocus);
      } else if (key === keyValues.right && !props.disabled && page.value < firstPage.value + lastPage.value - 1) {
        page.value = page.value + 1;
        nextTick(updateFocus);
      }
    }
    return () => _createVNode(props.tag, {
      "ref": resizeRef,
      "class": ["ve-pagination", paperClasses.value],
      "style": paperStyles.value,
      "role": "navigation",
      "aria-label": props.ariaLabel,
      "onKeydown": onKeydown
    }, {
      default: () => [_createVNode("ul", {
        "class": "ve-pagination__wrapper"
      }, [props.showFirstLastPage && _createVNode("li", {
        "class": "ve-pagination__first"
      }, [slots.first?.(controls.value.first) ?? _createVNode(Button, controls.value.first, null)]), _createVNode("li", {
        "class": "ve-pagination__prev"
      }, [slots.prev?.(controls.value.prev) ?? _createVNode(Button, controls.value.prev, null)]), items.value.map((item, index) => _createVNode("li", {
        "key": `${index}_${item.page}`,
        "class": ["ve-pagination__item", {
          "ve-pagination__item--is-active": item.isActive
        }]
      }, [slots.item?.(item) ?? _createVNode(Button, item.props, {
        default: () => [item.page]
      })])), _createVNode("li", {
        "class": "ve-pagination__next"
      }, [slots.next?.(controls.value.next) ?? _createVNode(Button, controls.value.next, null)]), props.showFirstLastPage && _createVNode("li", {
        "class": "ve-pagination__last"
      }, [slots.last?.(controls.value.last) ?? _createVNode(Button, controls.value.last, null)]), props.showPerPageSelect && _createVNode("li", {
        "class": "ve-pagination__per-page"
      }, [_createVNode(Select, {
        "hide-details": true,
        "width": "95",
        "modelValue": perPage.value,
        "onUpdate:modelValue": ($event) => perPage.value = $event,
        "items": props.perPageOptions.map((v) => ({
          text: `${v} / \u9875`,
          value: parseInt(v, 10)
        }))
      }, null)]), props.showQuickJumper && _createVNode("li", {
        "class": "ve-pagination__quick-jumper"
      }, [_createVNode(Input, {
        "hide-details": true,
        "width": "60",
        "modelValue": internalPage.value,
        "onUpdate:modelValue": ($event) => internalPage.value = $event,
        "type": "number",
        "onKeydown": ({
          key
        }) => {
          if (key === keyValues.enter && internalPage.value && internalPage.value > 0 && internalPage.value <= lastPage.value) {
            page.value = internalPage.value;
            internalPage.value = void 0;
          }
        },
        "onBlur": () => {
          if (internalPage.value && internalPage.value > 0 && internalPage.value <= lastPage.value) {
            page.value = internalPage.value;
            internalPage.value = void 0;
          }
        }
      }, {
        prepend: () => _createVNode("span", null, [_createTextVNode("\u8DF3\u81F3")])
      })])])]
    });
  }
});
export {
  Pagination
};
//# sourceMappingURL=pagination.mjs.map
