<template>
	<view class="message-list-page">
		<scroll-view
			class="message-list-scroll"
			scroll-y
			:style="{ height: scrollHeight }"
			refresher-enabled
			:refresher-triggered="refreshing"
			@refresherrefresh="onPullRefresh"
			@scrolltolower="onLoadMore"
		>
			<view v-if="loading && !list.length" class="message-list-state">
				<u-loading-icon mode="circle" />
			</view>

			<view v-else-if="loadFailed && !list.length" class="message-list-state">
				<u-empty mode="list" text="加载失败" icon-size="80" />
				<text class="message-list-retry" @click="reloadList(true)">点击重试</text>
			</view>

			<view v-else-if="!list.length" class="message-list-state">
				<u-empty mode="list" :text="emptyText" icon-size="80" />
				<text class="message-list-tip">{{ emptyTip }}</text>
			</view>

			<template v-else>
				<message-list-item
					v-for="item in list"
					:key="item.messageId"
					:item="item"
					@click="onItemClick"
				/>
				<view class="message-list-footer">
					<text v-if="loadingMore">加载中...</text>
					<text v-else-if="finished">没有更多了</text>
				</view>
			</template>
		</scroll-view>
	</view>
</template>

<script setup>
import { ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { listMessages } from '@/api/message'
import { mapMessageList } from '@/utils/messageDisplay'
import { goMessageDetail } from '@/utils/messageNav'
import { ensureApiToken } from '@/utils/apiAuth'
import {
	MESSAGE_PAGE_SIZE,
	MESSAGE_EMPTY_TEXT,
	MESSAGE_EMPTY_TIP
} from '@/constants/message'
import MessageListItem from '@/components/message/MessageListItem.vue'

const list = ref([])
const loading = ref(false)
const loadingMore = ref(false)
const finished = ref(false)
const loadFailed = ref(false)
const refreshing = ref(false)
const pageNum = ref(1)
const scrollHeight = ref('600px')
const emptyText = MESSAGE_EMPTY_TEXT
const emptyTip = MESSAGE_EMPTY_TIP

function calcScrollHeight() {
	try {
		const sys = uni.getSystemInfoSync()
		scrollHeight.value = `${sys.windowHeight || 600}px`
	} catch (e) {
		scrollHeight.value = '600px'
	}
}

async function fetchPage(isReset) {
	if (isReset) {
		loading.value = true
		loadFailed.value = false
		pageNum.value = 1
		finished.value = false
	} else if (finished.value || loadingMore.value) {
		return
	} else {
		loadingMore.value = true
	}
	try {
		const res = await listMessages({
			pageNum: pageNum.value,
			pageSize: MESSAGE_PAGE_SIZE
		})
		const rows = mapMessageList(res.rows || [])
		const total = Number(res.total) || 0
		if (isReset) {
			list.value = rows
		} else {
			list.value = list.value.concat(rows)
		}
		finished.value = list.value.length >= total || rows.length < MESSAGE_PAGE_SIZE
		if (!finished.value) {
			pageNum.value += 1
		}
	} catch (e) {
		if (isReset) {
			loadFailed.value = true
		}
	} finally {
		loading.value = false
		loadingMore.value = false
		refreshing.value = false
	}
}

function reloadList(isReset) {
	return fetchPage(isReset !== false)
}

function onPullRefresh() {
	refreshing.value = true
	reloadList(true)
}

function onLoadMore() {
	reloadList(false)
}

function onItemClick(item) {
	if (item && item.messageId) {
		goMessageDetail(item.messageId)
	}
}

onShow(() => {
	if (!ensureApiToken(false)) return
	calcScrollHeight()
	reloadList(true)
})
</script>

<style lang="scss" scoped>
.message-list-page {
	min-height: 100vh;
	background: #f5f6f8;
}
.message-list-scroll {
	box-sizing: border-box;
}
.message-list-state {
	padding: 120rpx 48rpx;
	display: flex;
	flex-direction: column;
	align-items: center;
}
.message-list-retry {
	margin-top: 24rpx;
	font-size: 28rpx;
	color: #2e7d32;
}
.message-list-tip {
	margin-top: 16rpx;
	font-size: 26rpx;
	color: #999;
	text-align: center;
}
.message-list-footer {
	padding: 24rpx;
	text-align: center;
	font-size: 24rpx;
	color: #999;
}
</style>
