<template>
	<view class="home-page">
		<!-- ① 顶部：品牌 + 搜索（吸顶） -->
		<view class="home-header" :style="{ paddingTop: statusBarHeight + 'px' }">
			<view class="header-inner">
				<view class="brand-row">
					<text class="brand-name">巴青农资商城</text>
				</view>
				<view class="search-bar" @click="onSearchTap">
					<u-icon name="search" color="#999" size="18" />
					<text class="search-placeholder">搜索兽药、饲料、店铺</text>
				</view>
			</view>
		</view>
		<view class="header-placeholder" :style="{ height: headerTotalHeight + 'px' }" />

		<scroll-view
			class="home-scroll"
			scroll-y
			:style="{ height: scrollHeight + 'px' }"
			:scroll-top="scrollTop"
			@scroll="onScroll"
		>
			<!-- ② Banner 轮播 -->
			<view v-if="bannerList.length" class="section banner-section">
				<swiper
					class="banner-swiper"
					:indicator-dots="bannerList.length > 1"
					indicator-color="rgba(255,255,255,0.5)"
					indicator-active-color="#ffffff"
					:autoplay="bannerList.length > 1"
					:circular="bannerList.length > 1"
					interval="4000"
					duration="500"
				>
					<swiper-item v-for="(item, index) in bannerList" :key="item.bannerId || index">
						<image
							class="banner-img"
							:src="item.bannerImage"
							mode="aspectFill"
							@click="onBannerPreview(index)"
						/>
					</swiper-item>
				</swiper>
			</view>

			<!-- ③ 平台一级类目 + 更多 -->
			<view class="section category-section">
				<scroll-view class="category-scroll" scroll-x enable-flex show-scrollbar="false">
					<view class="category-list">
						<view
							v-for="item in categoryList"
							:key="item.categoryId"
							class="category-item"
							@click="onCategoryTap(item)"
						>
							<image
								class="category-icon"
								:src="item.displayPic"
								mode="aspectFill"
								@error="onCategoryImgError(item)"
							/>
							<text class="category-name">{{ item.categoryName }}</text>
						</view>
						<view class="category-item" @click="onMoreCategoryTap">
							<view class="category-icon category-more-icon">
								<u-icon name="grid" color="#2E7D32" size="28" />
							</view>
							<text class="category-name">更多</text>
						</view>
					</view>
				</scroll-view>
				<view v-if="categoryLoadFailed && !categoryList.length" class="module-hint">
					<text>分类加载失败</text>
				</view>
			</view>

			<!-- ④ 热销商品 -->
			<view class="section hot-section">
				<view class="section-head">
					<view class="section-title-wrap">
						<view class="title-bar" />
						<text class="section-title">热销商品</text>
					</view>
					<text class="section-sub">全平台精选</text>
				</view>

				<view v-if="hotLoading" class="hot-skeleton">
					<view v-for="n in 4" :key="n" class="skeleton-card" />
				</view>

				<view v-else-if="hotGoodsList.length" class="hot-grid">
					<view
						v-for="item in hotGoodsList"
						:key="item.goodsId"
						class="hot-card"
						@click="onGoodsTap(item)"
					>
						<image class="hot-pic" :src="item.displayPic" mode="aspectFill" />
						<view class="hot-info">
							<text class="hot-name">{{ item.goodsName }}</text>
							<view class="hot-meta">
								<text class="hot-price">
									<text class="price-symbol">¥</text>
									<text class="price-num">{{ item.priceText }}</text>
								</text>
							</view>
							<text class="hot-shop">{{ item.shopName || '—' }}</text>
						</view>
					</view>
				</view>

				<view v-else class="empty-block">
					<u-empty mode="list" text="暂无热销商品" icon-size="80" />
				</view>
			</view>

			<view class="safe-bottom" />
		</scroll-view>
	</view>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { listHomeBanners, listHomeCategories, listHomeHotGoods } from '@/api/home'
import { resolveFileUrl } from '@/utils/image'
import { formatPrice } from '@/utils/format'
import { goGoodsDetail } from '@/utils/goodsDetail'
import { PAGE_SEARCH_INDEX, PAGE_CATEGORY_LEVEL1, PAGE_CATEGORY_TAB } from '@/utils/pageRoute'

const CATEGORY_PLACEHOLDER = '/static/logo.png'
const GOODS_PLACEHOLDER = '/static/logo.png'

const statusBarHeight = ref(20)
const headerContentHeight = 100
const scrollHeight = ref(600)
const scrollTop = ref(0)
const savedScrollTop = ref(0)

const hotLoading = ref(true)
const bannerList = ref([])
const categoryList = ref([])
const hotGoodsList = ref([])
const categoryLoadFailed = ref(false)

const headerTotalHeight = computed(() => statusBarHeight.value + headerContentHeight)

/** 并行拉取三接口，各模块独立渲染（HM14） */
function loadHomeData() {
	hotLoading.value = true
	Promise.all([
		fetchModule(listHomeBanners, mapBanners).then((res) => {
			bannerList.value = res.data
		}),
		fetchModule(listHomeCategories, mapCategories).then((res) => {
			categoryLoadFailed.value = !res.ok
			categoryList.value = res.data
		}),
		fetchModule(listHomeHotGoods, mapHotGoods)
			.then((res) => {
				hotGoodsList.value = res.data
			})
			.finally(() => {
				hotLoading.value = false
			})
	])
}

async function fetchModule(apiFn, mapper) {
	try {
		const res = await apiFn()
		const list = Array.isArray(res.data) ? res.data : []
		return { ok: true, data: mapper(list) }
	} catch (e) {
		return { ok: false, data: [] }
	}
}

/** Banner：过滤无效图（BN13） */
function mapBanners(list) {
	return list
		.map((row) => {
			const url = resolveFileUrl(row.bannerImage)
			return {
				bannerId: row.bannerId,
				bannerImage: url,
				sortNo: row.sortNo
			}
		})
		.filter((item) => !!item.bannerImage)
}

function mapCategories(list) {
	return list.map((row) => ({
		categoryId: row.categoryId,
		categoryName: row.categoryName,
		categoryPic: row.categoryPic,
		displayPic: resolveFileUrl(row.categoryPic) || CATEGORY_PLACEHOLDER,
		sortNo: row.sortNo
	}))
}

function mapHotGoods(list) {
	return list.map((row) => ({
		goodsId: row.goodsId,
		goodsSn: row.goodsSn,
		goodsName: row.goodsName,
		mainPic: row.mainPic,
		displayPic: resolveFileUrl(row.mainPic) || GOODS_PLACEHOLDER,
		salePrice: row.salePrice,
		priceText: formatPrice(row.salePrice),
		shopId: row.shopId,
		shopName: row.shopName
	}))
}

function initLayout() {
	try {
		const sys = uni.getSystemInfoSync()
		statusBarHeight.value = sys.statusBarHeight || 20
		const windowH = sys.windowHeight || sys.screenHeight || 600
		// 减去自定义顶栏与底部 tabBar（约 50px）
		const tabBarH = 20
		scrollHeight.value = windowH - statusBarHeight.value - headerContentHeight - tabBarH
	} catch (e) {
		statusBarHeight.value = 20
		scrollHeight.value = 500
	}
}

function onScroll(e) {
	savedScrollTop.value = e.detail.scrollTop || 0
}

function onSearchTap() {
	uni.navigateTo({ url: PAGE_SEARCH_INDEX })
}

function onBannerPreview(index) {
	const urls = bannerList.value.map((b) => b.bannerImage).filter(Boolean)
	if (!urls.length) return
	uni.previewImage({ urls, current: urls[index] || urls[0] })
}

function onCategoryTap(item) {
	uni.navigateTo({
		url:
			`${PAGE_CATEGORY_LEVEL1}?level1Id=${item.categoryId}` +
			`&level1Name=${encodeURIComponent(item.categoryName || '')}` +
			`&level1Pic=${encodeURIComponent(item.categoryPic || '')}`
	})
}

function onMoreCategoryTap() {
	uni.switchTab({ url: PAGE_CATEGORY_TAB })
}

function onCategoryImgError(item) {
	item.displayPic = CATEGORY_PLACEHOLDER
}

function onGoodsTap(item) {
	goGoodsDetail(item.goodsId)
}

onMounted(() => {
	initLayout()
})

/** 进入页 / 切回 Tab 重新拉数；从子页返回时恢复滚动（§7.2、§7.3） */
onShow(() => {
	const pages = getCurrentPages()
	const fromSubPage = pages.length > 1
	loadHomeData()
	if (fromSubPage && savedScrollTop.value > 0) {
		setTimeout(() => {
			scrollTop.value = savedScrollTop.value
		}, 80)
	}
})
</script>

<style lang="scss" scoped>
$primary: #2e7d32;
$primary-light: #4caf50;

.home-page {
	min-height: 100vh;
	background: #f5f6f8;
}

.home-header {
	position: fixed;
	left: 0;
	right: 0;
	top: 0;
	z-index: 100;
	background: linear-gradient(135deg, $primary 0%, $primary-light 100%);
	box-shadow: 0 4rpx 16rpx rgba(46, 125, 50, 0.25);
}

.header-inner {
	padding: 12rpx 24rpx 20rpx;
}

.brand-row {
	margin-bottom: 16rpx;
}

.brand-name {
	font-size: 34rpx;
	font-weight: 700;
	color: #fff;
	letter-spacing: 2rpx;
}

.search-bar {
	display: flex;
	align-items: center;
	height: 72rpx;
	padding: 0 24rpx;
	background: #fff;
	border-radius: 36rpx;
	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
}

.search-placeholder {
	margin-left: 12rpx;
	font-size: 28rpx;
	color: #999;
}

.home-scroll {
	box-sizing: border-box;
}

.section {
	margin: 0 24rpx 24rpx;
	background: #fff;
	border-radius: 16rpx;
	overflow: hidden;
}

.banner-section {
	margin-top: 16rpx;
	padding: 0;
	background: transparent;
	overflow: visible;
}

.banner-swiper {
	height: 300rpx;
	border-radius: 16rpx;
	overflow: hidden;
}

.banner-img {
	width: 100%;
	height: 300rpx;
	display: block;
}

.category-section {
	padding: 24rpx 0 16rpx;
}

.category-scroll {
	width: 100%;
	white-space: nowrap;
}

.category-list {
	display: inline-flex;
	flex-direction: row;
	padding: 0 16rpx;
}

.category-item {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	width: 128rpx;
	margin: 0 8rpx;
	flex-shrink: 0;
}

.category-icon {
	width: 96rpx;
	height: 96rpx;
	border-radius: 50%;
	background: #f0f4f0;
}

.category-more-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	border: 2rpx dashed #c8e6c9;
	background: #f1f8f1;
}

.category-name {
	margin-top: 12rpx;
	font-size: 24rpx;
	color: #333;
	text-align: center;
	width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.module-hint {
	padding: 8rpx 24rpx 0;
	font-size: 24rpx;
	color: #999;
	text-align: center;
}

.hot-section {
	padding: 24rpx;
}

.section-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 24rpx;
}

.section-title-wrap {
	display: flex;
	align-items: center;
}

.title-bar {
	width: 8rpx;
	height: 32rpx;
	margin-right: 12rpx;
	border-radius: 4rpx;
	background: $primary;
}

.section-title {
	font-size: 32rpx;
	font-weight: 700;
	color: #222;
}

.section-sub {
	font-size: 24rpx;
	color: #999;
}

.hot-grid {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
}

.hot-card {
	width: 48%;
	margin-bottom: 20rpx;
	background: #fafafa;
	border-radius: 12rpx;
	overflow: hidden;
}

.hot-pic {
	width: 100%;
	height: 320rpx;
	background: #eee;
	display: block;
}

.hot-info {
	padding: 16rpx;
}

.hot-name {
	font-size: 26rpx;
	color: #333;
	line-height: 1.4;
	height: 72rpx;
	overflow: hidden;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

.hot-meta {
	margin-top: 8rpx;
}

.hot-price {
	color: #e53935;
	font-weight: 600;
}

.price-symbol {
	font-size: 22rpx;
}

.price-num {
	font-size: 34rpx;
}

.hot-shop {
	display: block;
	margin-top: 8rpx;
	font-size: 22rpx;
	color: #999;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.hot-skeleton {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
}

.skeleton-card {
	width: 48%;
	height: 420rpx;
	margin-bottom: 20rpx;
	border-radius: 12rpx;
	background: linear-gradient(90deg, #f0f0f0 25%, #e8e8e8 50%, #f0f0f0 75%);
	background-size: 200% 100%;
	animation: shimmer 1.2s infinite;
}

@keyframes shimmer {
	0% {
		background-position: 100% 0;
	}
	100% {
		background-position: -100% 0;
	}
}

.empty-block {
	padding: 40rpx 0;
}

.safe-bottom {
	height: 24rpx;
}
</style>
