<template>
	<div class="pagination" v-if="!hideOnSinglePage ? true : total !== 1">
		<span>{{ showTotal(totalNum) }}</span>
		<a-button
			type="link"
			style="padding: 0; font-size: 14px"
			:disabled="isDisabled('leftOutLined')"
			@click="previousPage"
		>
			<template #icon><leftOutlined class="icon" /></template>
		</a-button>
		<span
			v-for="pageIndex in pageRangeArr"
			:title="pageIndex"
			:key="pageIndex"
			class="pageIndex"
			@click="jumpCurrentPage(pageIndex)"
			:class="{ active: totalNum && pageIndex === currentPage }"
		>
			{{ pageIndex }}
		</span>
		<a-button type="link" :disabled="isDisabled('rightOutlined')" style="padding: 0; font-size: 14px" @click="nextPage">
			<template #icon><rightOutlined class="icon" /></template>
		</a-button>
		<a-select
			class="sizeChanger"
			v-model:value="pageSize"
			:size="size"
			@change="handleSizeChange"
			v-if="isShowSizeChanger"
		>
			<a-select-option v-for="item in pageSizeOptions" :key="item"> {{ item }}条/页 </a-select-option>
		</a-select>
		<span v-if="totalPage > 1 && showQuickJumper" class="jumpPage"
			>跳至<a-input
				v-model:value="inputIndex"
				:size="size"
				class="toInputIndex"
				@blur="() => quickJumpPage(inputIndex)"
				@keyup.enter="quickJumpPage(inputIndex)"
			/>页</span
		>
	</div>
</template>

<script setup>
	import { ref, computed, watch } from 'vue'
	import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue'
	const props = defineProps({
		total: {
			type: Number,
			required: true,
			default: 0
		},
		pageSize: {
			type: Number,
			default: 10
		},
		current: {
			type: Number,
			default: 1
		},
		pageSizeOptions: {
			type: Array,
			default: () => ['10', '20', '30', '40', '50', '200', '500']
		},
		showQuickJumper: {
			type: Boolean,
			default: false
		},
		showSizeChanger: {
			type: Boolean
		},
		hideOnSinglePage: {
			type: Boolean,
			default: false
		},
		showTotal: {
			type: Function,
			default: () => ''
		},
		size: {
			type: String,
			default: ''
		}
	})

	const emit = defineEmits(['change', 'showSizeChange'])
	const currentPage = ref(props.current)
	const pageSize = ref(String(props.pageSize))
	const totalNum = ref(props.total)
	const inputIndex = ref('')
	const isShowSizeChanger = ref(false)

	const pageRangeStart = ref(1)

	const isDisabled = (type) => {
		switch (type) {
			case 'leftOutLined':
				return currentPage.value === 1
			case 'rightOutlined':
				return currentPage.value === totalPage.value
			default:
				break
		}
	}

	const handleSizeChange = (size) => {
		pageRangeStart.value = 1
		currentPage.value = 1
		emit('showSizeChange', currentPage.value, Number(size))
	}

	watch(
		() => props.total,
		(val) => {
			totalNum.value = val
			isShowSizeChanger.value = props.showSizeChanger ? true : val > 50
		},
		{ immediate: true }
	)

	watch(
		() => props.pageSize,
		(val) => {
			pageSize.value = String(val)
		}
	)

	watch(
		() => props.current,
		(val) => {
			if (val === 1) {
				quickJumpPage(1)
			}
		}
	)

	const pageRangeEnd = computed(() => Math.min(pageRangeStart.value + 9, totalPage.value))

	const pageRangeArr = computed(() => {
		const start = pageRangeStart.value
		const end = pageRangeEnd.value
		const pages = []
		for (let i = start; i <= end; i++) {
			pages.push(i)
		}
		return pages
	})

	const totalPage = computed(() => {
		return !totalNum.value ? 1 : Math.ceil(totalNum.value / pageSize.value)
	})

	// 点击页码
	const jumpCurrentPage = (page) => {
		// 不重复请求
		if (page === currentPage.value) return
		if (page === totalPage.value) {
			currentPage.value = page
			emit('change', currentPage.value)
		} else {
			if (page >= 1 && page < totalPage.value) {
				currentPage.value = page
				if ((page <= pageRangeStart.value && page !== 1) || page >= pageRangeEnd.value) {
					pageRangeStart.value = Math.max(1, page - 5)
				}
				emit('change', currentPage.value)
			}
		}
	}
	// 上一页
	const previousPage = () => {
		if (currentPage.value > 1) {
			currentPage.value--
			if (currentPage.value < pageRangeStart.value) {
				pageRangeStart.value = Math.max(1, currentPage.value - 5)
			}
			emit('change', currentPage.value)
		}
	}
	// 下一页
	const nextPage = () => {
		if (currentPage.value < totalPage.value) {
			currentPage.value++
			if (currentPage.value > pageRangeEnd.value && currentPage.value !== totalNum.value) {
				pageRangeStart.value = Math.max(1, currentPage.value - 5)
			}
			emit('change', currentPage.value)
		}
	}

	// 快速跳转
	const quickJumpPage = (pageIndex) => {
		let index = Number(pageIndex)
		let isInteger = Number.isInteger(index)
		if (!index || !isInteger) {
			inputIndex.value = ''
			return
		} else {
			pageRangeStart.value = 1
			if (index >= 1 && index < totalPage.value) {
				pageRangeStart.value = Math.max(1, index - 5)
				currentPage.value = index
			} else {
				if (index >= totalPage.value) {
					if (totalPage.value < 10) {
						pageRangeStart.value = 1
					} else {
						pageRangeStart.value = totalPage.value - (totalPage.value % 10) - 4
					}
					currentPage.value = totalPage.value
				} else if (index < 1) {
					pageRangeStart.value = 1
					currentPage.value = 1
				}
			}
			inputIndex.value = ''
		}
		emit('change', currentPage.value)
	}
</script>
<style scoped lang="less">
	.pagination {
		user-select: none;
		display: flex;
		align-items: center;
		flex-wrap: wrap;
	}
	.icon {
		font-size: 12px;
	}

	.ant-btn-link {
		color: #212325;
		font-size: 12px;
		&:hover {
			color: #4458fe;
		}
	}
	.ant-btn-link[disabled],
	.ant-btn-link[disabled]:hover,
	.ant-btn-link[disabled]:focus,
	.ant-btn-link[disabled]:active {
		color: rgba(0, 0, 0, 0.25);
	}
	.pagination span.active {
		color: #4458fe;
	}
	:deep(.ant-select select) {
		border-radius: 6px;
	}
	.pageIndex {
		display: inline-block;
		min-width: 32px;
		height: 30px;
		line-height: 30px;
		text-align: center;
		cursor: pointer;
		border-radius: 6px;
		font-size: 14px;
		padding: 0 6px;
	}
	.pageIndex:hover {
		color: #4458fe;
	}
	.sizeChanger {
		margin-left: 8px;
	}
	.jumpPage {
		margin-left: 8px;
	}
	.toInputIndex {
		width: 48px;
		margin: 0 8px;
	}
	.disabledBgc {
		color: rgba(0, 0, 0, 0.25);
		cursor: not-allowed;
	}
</style>
