<template>
  <FlexRow center>
    <slot v-if="showNextPrev" name="prev" :onClick="onPrevPress" :touchable="canPrev">
      <PaginationItem
        v-bind="$props"
        :text="prevText"
        :touchable="canPrev"
        :active="false"
        @click="onPrevPress"
      />
    </slot>
    <slot v-if="simple" name="simple" :text="`${currentPage + 1}/${props.pageCount}`"">
      <PaginationItem
        v-if="showFirstAndLast"
        v-bind="$props"
        :text="firstText"
        :touchable="canPrev"
        :active="false"
        @click="onFirstPress"
      />
      <text :style="themeStyles.simpleText.value">{{ `${currentPage + 1}/${props.pageCount}` }}</text>
      <PaginationItem
        v-if="showFirstAndLast"
        v-bind="$props"
        :text="lastText"
        :touchable="canNext"
        :active="false"
        @click="onLastPress"
      />
    </slot>
    <slot v-else name="items" :items="items" :currentPage="currentPage" :onChange="emitChange">
      <template v-for="index in items" :key="index">
        <!-- #ifndef MP -->
        <slot
          name="item"
          :text="(index + 1).toString()"
          :index="index"
          :active="index === currentPage"
          :onClick="() => emitChange(index)"
        >
        <!-- #endif -->
          <PaginationItem
            v-bind="$props"
            :key="index"
            :text="(index + 1).toString()"
            :active="index === currentPage"
            :touchable="true"
            @click="() => emitChange(index)"
          />
        <!-- #ifndef MP -->
        </slot>
        <!-- #endif -->
      </template>
    </slot>
    <slot v-if="showNextPrev" name="next" :onClick="onNextPress" :touchable="canNext">
      <PaginationItem 
        v-bind="$props"
        :text="nextText"
        :touchable="canNext"
        :active="false"
        @click="onNextPress"
      />
    </slot>
  </FlexRow>
</template>

<script setup lang="ts">
import { computed } from 'vue';
import { DynamicSize2 } from '../theme/ThemeTools';
import { propGetThemeVar, useTheme, type TextStyle, type ViewStyle } from '../theme/ThemeDefine';
import FlexRow from '../layout/FlexRow.vue';
import PaginationItem from './PaginationItem.vue';

export interface PaginationProps {

  /**
   * 当前的页码
   */
  currentPage: number;
  /**
   * 总共有的页数
   */
  pageCount: number;
  /**
   * 是否显示上一页下一页按钮，默认是
   * @default true
   */
  showNextPrev?: boolean;
  /**
   * 是否显示第一页和最后一页按钮，默认是
   * @default true
   */
  showFirstAndLast?: boolean;
  /**
   * 同时显示的页面按钮数量
   * @default 5
   */
  showPageCount?: number;
  /**
   * 是否简单模式，默认否
   */
  simple?: boolean;
  /**
   * 上一页按钮文字
   * @default '上一页'
   */
  prevText?: string;
  /**
   * 下一页按钮文字
   * @default '下一页'
   */
  nextText?: string;
  /**
   * 第一页按钮文字，仅在 simple 模式下显示
   * @default '首页'
   */
  firstText?: string;
  /**
   * 最后一页按钮文字，仅在 simple 模式下显示
   * @default '末页'
   */
  lastText?: string;
  /**
   * 按钮按下颜色
   */
  pressedColor?: string;
  /**
   * 按钮按下时文字的颜色
   */
  pressedTextColor?: string;
  /**
   * 按钮激活时（为当前页码）颜色
   */
  activeColor?: string;
  /**
   * 按钮为非当前页码下颜色
   */
  deactiveColor?: string;
  /**
   * 按钮激活时（为当前页码）文字颜色
   */
  activeTextColor?: string;
  /**
   * 按钮为非当前页码下文字颜色
   */
  deactiveTextColor?: string;
  /**
   * 自定义按钮样式
   */
  buttonStyle?: ViewStyle;
  /**
   * 自定义文字样式
   */
  textStyle?: TextStyle;
}

const props = withDefaults(defineProps<PaginationProps>(), {
  currentPage: 1,
  pageCount: 1,
  showNextPrev: true,
  showPageCount: 5,
  simple: false,
  prevText: '上一页',
  nextText: '下一页',
  firstText: '首页',
  lastText: '末页',
  showFirstAndLast: true,
  pressedColor: () => propGetThemeVar('PaginationPressedColor', 'pressed.white'),
  pressedTextColor: () => propGetThemeVar('PaginationPressedTextColor', 'text.second'),
  activeColor: () => propGetThemeVar('PaginationActiveColor', 'primary'),
  deactiveColor: () => propGetThemeVar('PaginationDeactiveColor', 'white'),
  activeTextColor: () => propGetThemeVar('PaginationActiveTextColor', 'white'),
  deactiveTextColor: () => propGetThemeVar('PaginationDeactiveTextColor', 'text.content'),
});
const emit = defineEmits([ 'update:currentPage' ]);

const canNext = computed(() => props.currentPage < props.pageCount - 1);
const canPrev = computed(() => props.currentPage > 0);
const items = computed(() => {
  let startOverAdd = 0;
  let start = props.currentPage - Math.floor(props.showPageCount / 2);
  if (start < 0) {
    startOverAdd += -start;
    start = 0;
  }
  let end = props.currentPage + Math.ceil(props.showPageCount / 2) + startOverAdd;
  if (end > props.pageCount) {
    const endOverAdd = props.pageCount - end;
    if (start - endOverAdd >= 0) start += endOverAdd;
    end = props.pageCount;
  }
  const result : number[] = [];
  for (let index = start; index < end; index++)
    result.push(index);
  return result
});

function emitChange(num: number) {
  num = Math.min(props.pageCount - 1, Math.max(num, 0));
  emit('update:currentPage', num);
}
const onPrevPress = () => emitChange(props.currentPage - 1);
const onNextPress = () => emitChange(props.currentPage + 1);
const onFirstPress = () => emitChange(0);
const onLastPress = () => emitChange(props.pageCount - 1);

const themeContext = useTheme();
const themeStyles = themeContext.useThemeStyles({
  simpleText: {
    display: 'flex',
    padding: DynamicSize2('PaginationSimpleTextPaddingVertical', 'PaginationSimpleTextPaddingHorizontal', 10, 20),
    flexGrow: 1,
    justifyContent: 'center',
    alignContent: 'center',
    textAlign: 'center',
  },
});

</script>
