<template>
	<view class="goods-block">
		<sort-toolbar v-model="innerSort" @change="onSortChange" />
		<scroll-view
			class="goods-block__scroll"
			scroll-y
			:scroll-top="listScrollTop"
			:style="{ height: scrollHeight }"
			@scrolltolower="onLoadMore"
		>
			<view v-if="loading && !goodsList.length" class="goods-block__loading">
				<u-loading-icon mode="circle" />
			</view>
			<goods-grid v-else-if="goodsList.length" :list="goodsList" @item-click="onGoodsClick" />
			<view v-else class="goods-block__empty">
				<u-empty mode="list" :text="emptyText" icon-size="80" />
			</view>
			<view v-if="goodsList.length" class="goods-block__footer">
				<text v-if="loadingMore">加载中...</text>
				<text v-else-if="finished">没有更多了</text>
			</view>
		</scroll-view>
	</view>
</template>

<script setup>
import { ref, watch } from 'vue'
import { getCategoryGoods } from '@/api/category'
import { mapGoodsCardList } from '@/utils/goodsDisplay'
import { DEFAULT_SORT_BY } from '@/constants/categorySort'
import SortToolbar from '@/components/mall/SortToolbar.vue'
import GoodsGrid from '@/components/mall/GoodsGrid.vue'

const props = defineProps({
	categoryId: {
		type: [Number, String],
		default: ''
	},
	sortBy: {
		type: String,
		default: DEFAULT_SORT_BY
	},
	scrollHeight: {
		type: String,
		default: '600px'
	},
	/** Tab 切换时回顶（C1） */
	scrollTopKey: {
		type: Number,
		default: 0
	},
	pageSize: {
		type: Number,
		default: 10
	},
	emptyText: {
		type: String,
		default: '该分类下暂无商品'
	}
})

const emit = defineEmits(['update:sortBy', 'goods-click'])

const innerSort = ref(props.sortBy)
const goodsList = ref([])
const loading = ref(false)
const loadingMore = ref(false)
const finished = ref(false)
const pageNum = ref(1)
const listScrollTop = ref(0)
const loadFailed = ref(false)

watch(
	() => props.sortBy,
	(v) => {
		innerSort.value = v
	}
)

watch(
	() => [props.categoryId, props.scrollTopKey],
	() => {
		if (!props.categoryId) {
			goodsList.value = []
			return
		}
		reloadGoods(true)
	},
	{ immediate: true }
)

async function fetchPage(isReset) {
	if (!props.categoryId) return
	if (isReset) {
		loading.value = true
		loadFailed.value = false
		pageNum.value = 1
		finished.value = false
	} else {
		if (finished.value || loadingMore.value) return
		loadingMore.value = true
	}
	try {
		const res = await getCategoryGoods({
			categoryId: props.categoryId,
			sortBy: innerSort.value,
			pageNum: pageNum.value,
			pageSize: props.pageSize
		})
		const rows = mapGoodsCardList(res.rows || [])
		const total = Number(res.total) || 0
		if (isReset) {
			goodsList.value = rows
		} else {
			goodsList.value = goodsList.value.concat(rows)
		}
		finished.value =
			rows.length < props.pageSize || (total > 0 && goodsList.value.length >= total)
		if (!finished.value) {
			pageNum.value += 1
		}
	} catch (e) {
		loadFailed.value = true
		if (isReset) {
			goodsList.value = []
		}
	} finally {
		loading.value = false
		loadingMore.value = false
	}
}

function reloadGoods(resetScroll) {
	if (resetScroll) {
		listScrollTop.value = listScrollTop.value === 0 ? 0.1 : 0
	}
	pageNum.value = 1
	fetchPage(true)
}

function onSortChange(val) {
	emit('update:sortBy', val)
	reloadGoods(true)
}

function onLoadMore() {
	if (!loading.value && !loadingMore.value && !finished.value) {
		fetchPage(false)
	}
}

function onGoodsClick(item) {
	emit('goods-click', item)
}
</script>

<style lang="scss" scoped>
.goods-block {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-height: 0;
}
.goods-block__scroll {
	flex: 1;
}
.goods-block__loading {
	padding: 80rpx 0;
	display: flex;
	justify-content: center;
}
.goods-block__empty {
	padding: 60rpx 0;
}
.goods-block__footer {
	padding: 24rpx;
	text-align: center;
	font-size: 24rpx;
	color: #999;
}
</style>
