<template>
	<view class="page-b">
		<search-entry />

		<view v-if="level1Name" class="cat-panel">
			<!-- 手风琴标题：一级分类，点击展开/收起二级 -->
			<view class="l1-hero" @click="toggleAccordion">
				<image class="l1-hero__pic" :src="level1DisplayPic" mode="aspectFill" />
				<view class="l1-hero__info">
					<view class="l1-hero__title-row">
						<text class="l1-hero__name">{{ level1Name }}</text>
						<text v-if="level1IsHot" class="l1-hero__hot">热门</text>
					</view>
					<text class="l1-hero__sub">{{ level1SubText }}</text>
				</view>
				<view class="l1-hero__arrow" :class="{ 'l1-hero__arrow--open': accordionOpen }">
					<u-icon name="arrow-down" color="#689f38" size="14" />
				</view>
			</view>

			<!-- 手风琴内容：二级分类宫格 -->
			<view
				class="accordion-body"
				:class="{ 'accordion-body--open': accordionOpen }"
			>
				<view class="accordion-body__inner">
					<view v-if="tabsLoading" class="cat-panel__hint">
						<u-loading-icon mode="circle" size="20" />
					</view>
					<view v-else-if="!tabList.length" class="cat-panel__hint">
						<u-empty mode="list" :text="tabsFailed ? '分类加载失败' : '暂无子分类'" icon-size="64" />
					</view>
					<view v-else class="l2-grid">
						<view
							v-for="(tab, index) in tabList"
							:key="tab.categoryId"
							class="l2-item"
							:class="{ 'l2-item--active': activeTabIndex === index }"
							@click.stop="onTabChange(index)"
						>
							<view class="l2-item__pic-wrap">
								<image class="l2-item__pic" :src="tab.displayPic" mode="aspectFill" />
								<text v-if="tab.isHot" class="l2-item__hot">热</text>
							</view>
							<text class="l2-item__name">{{ tab.categoryName }}</text>
						</view>
					</view>
				</view>
			</view>
		</view>

		<goods-list-block
			v-if="activeCategoryId"
			:category-id="activeCategoryId"
			:sort-by="sortBy"
			:scroll-top-key="scrollTopKey"
			:scroll-height="goodsScrollHeight"
			@update:sort-by="sortBy = $event"
			@goods-click="onGoodsClick"
		/>
	</view>
</template>

<script setup>
import { ref, computed } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { getCategoryTree, getLevel2Tabs } from '@/api/category'
import { mapCategoryTree, mapLevel2Tabs } from '@/utils/categoryDisplay'
import { resolveFileUrl } from '@/utils/image'
import { DEFAULT_SORT_BY } from '@/constants/categorySort'
import SearchEntry from '@/components/mall/SearchEntry.vue'
import GoodsListBlock from '@/components/category/GoodsListBlock.vue'
import { goGoodsDetail } from '@/utils/goodsDetail'

const CATEGORY_PLACEHOLDER = '/static/logo.png'

const level1Id = ref('')
const level1Name = ref('')
const level1Pic = ref('')
const level1IsHot = ref(false)
const tabList = ref([])
const activeTabIndex = ref(0)
const tabsLoading = ref(true)
const tabsFailed = ref(false)
const sortBy = ref(DEFAULT_SORT_BY)
const scrollTopKey = ref(0)
const goodsScrollHeight = ref('500px')
/** 手风琴默认展开 */
const accordionOpen = ref(true)

const activeCategoryId = computed(() => {
	const tab = tabList.value[activeTabIndex.value]
	return tab ? tab.categoryId : ''
})

const level1DisplayPic = computed(
	() => resolveFileUrl(level1Pic.value) || CATEGORY_PLACEHOLDER
)

const activeTabName = computed(() => {
	const tab = tabList.value[activeTabIndex.value]
	return tab ? tab.categoryName : ''
})

const level1SubText = computed(() => {
	if (tabsLoading.value) return '子分类加载中…'
	if (tabsFailed.value) return '子分类加载失败'
	if (!tabList.value.length) return '暂无子分类'
	if (!accordionOpen.value && activeTabName.value) {
		return `当前：${activeTabName.value} · 点击展开子分类`
	}
	const n = tabList.value.length
	return `共 ${n} 个子分类，点击选择`
})

function calcScrollHeight() {
	try {
		const sys = uni.getSystemInfoSync()
		const h = sys.windowHeight || 600
		// 搜索 + 手风琴面板（展开更高）+ 排序栏
		const panelPx = accordionOpen.value ? 300 : 170
		goodsScrollHeight.value = `${h - panelPx}px`
	} catch (e) {
		goodsScrollHeight.value = '500px'
	}
}

function toggleAccordion() {
	accordionOpen.value = !accordionOpen.value
	calcScrollHeight()
}

/** 补全一级分类图标（路由未带图时从分类树读取） */
async function loadLevel1Meta() {
	if (!level1Id.value) return
	if (level1Pic.value && level1Name.value) return
	try {
		const res = await getCategoryTree()
		const tree = mapCategoryTree(res.data || [])
		const node = tree.find((n) => String(n.categoryId) === String(level1Id.value))
		if (!node) return
		if (!level1Name.value) level1Name.value = node.categoryName
		if (!level1Pic.value) level1Pic.value = node.categoryPic || ''
		if (!level1IsHot.value) level1IsHot.value = node.isHot
	} catch (e) {
		// 静默失败，保留路由传入的名称
	}
}

async function loadTabs() {
	if (!level1Id.value) return
	tabsLoading.value = true
	tabsFailed.value = false
	try {
		const res = await getLevel2Tabs(level1Id.value)
		tabList.value = mapLevel2Tabs(res.data || [])
		if (activeTabIndex.value >= tabList.value.length) {
			activeTabIndex.value = 0
		}
	} catch (e) {
		tabsFailed.value = true
		tabList.value = []
	} finally {
		tabsLoading.value = false
	}
}

function onTabChange(index) {
	if (activeTabIndex.value === index) return
	activeTabIndex.value = index
	// C1：列表回顶并重新加载（由 scrollTopKey 触发子组件 watch）
	scrollTopKey.value += 1
}

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

onLoad((options) => {
	level1Id.value = options.level1Id || ''
	level1Name.value = decodeURIComponent(options.level1Name || '')
	level1Pic.value = options.level1Pic ? decodeURIComponent(options.level1Pic) : ''
	level1IsHot.value = options.level1Hot === '1'
	if (level1Name.value) {
		uni.setNavigationBarTitle({ title: level1Name.value })
	}
	calcScrollHeight()
})

onShow(() => {
	loadLevel1Meta()
	loadTabs()
})
</script>

<style lang="scss" scoped>
.page-b {
	display: flex;
	flex-direction: column;
	height: calc(100vh - 88rpx);
	background: #f5f6f8;
}
/* 一二级分类合并面板 */
.cat-panel {
	margin: 16rpx 24rpx 0;
	background: #fff;
	border-radius: 16rpx;
	overflow: hidden;
	box-shadow: 0 4rpx 20rpx rgba(46, 125, 50, 0.08);
}
.l1-hero {
	display: flex;
	align-items: center;
	padding: 20rpx 24rpx;
	background: linear-gradient(135deg, #e8f5e9 0%, #f9fdf9 55%, #fff 100%);
}
.l1-hero__pic {
	width: 80rpx;
	height: 80rpx;
	border-radius: 18rpx;
	background: #fff;
	flex-shrink: 0;
	box-shadow: 0 4rpx 12rpx rgba(46, 125, 50, 0.12);
}
.l1-hero__info {
	flex: 1;
	min-width: 0;
	margin-left: 24rpx;
}
.l1-hero__title-row {
	display: flex;
	align-items: center;
	gap: 12rpx;
}
.l1-hero__name {
	flex: 1;
	min-width: 0;
	font-size: 32rpx;
	font-weight: 700;
	color: #1b5e20;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.l1-hero__arrow {
	flex-shrink: 0;
	margin-left: 12rpx;
	width: 40rpx;
	height: 40rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: rgba(104, 159, 56, 0.12);
	transition: transform 0.25s ease;
}
.l1-hero__arrow--open {
	transform: rotate(180deg);
}
.l1-hero__hot {
	flex-shrink: 0;
	padding: 4rpx 14rpx;
	font-size: 20rpx;
	color: #fff;
	background: linear-gradient(90deg, #ff9800, #f57c00);
	border-radius: 20rpx;
}
.l1-hero__sub {
	display: block;
	margin-top: 10rpx;
	font-size: 24rpx;
	color: #689f38;
	line-height: 1.4;
}
.cat-panel__hint {
	padding: 24rpx;
	display: flex;
	justify-content: center;
}
/* 手风琴展开区 */
.accordion-body {
	max-height: 0;
	overflow: hidden;
	transition: max-height 0.28s ease;
	border-top: 0 solid #f0f0f0;
}
.accordion-body--open {
	max-height: 1200rpx;
	border-top-width: 1rpx;
}
.accordion-body__inner {
	background: #fafbfa;
}
/* 二级分类：手风琴内四列小图标宫格 */
.l2-grid {
	display: flex;
	flex-wrap: wrap;
	padding: 16rpx 8rpx 12rpx;
}
.l2-item {
	width: 25%;
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 10rpx 6rpx 14rpx;
	box-sizing: border-box;
}
.l2-item__pic-wrap {
	position: relative;
	width: 72rpx;
	height: 72rpx;
	border-radius: 16rpx;
	overflow: hidden;
	background: #f0f2f0;
	border: 2rpx solid transparent;
	box-sizing: border-box;
}
.l2-item--active .l2-item__pic-wrap {
	border-color: #2e7d32;
	background: #e8f5e9;
}
.l2-item--active .l2-item__name {
	color: #2e7d32;
	font-weight: 600;
}
.l2-item__pic {
	width: 100%;
	height: 100%;
}
.l2-item__hot {
	position: absolute;
	top: 0;
	right: 0;
	padding: 0 6rpx;
	font-size: 16rpx;
	color: #fff;
	background: #ff9800;
	border-radius: 0 0 0 6rpx;
	line-height: 1.3;
}
.l2-item__name {
	margin-top: 8rpx;
	width: 100%;
	font-size: 22rpx;
	color: #333;
	text-align: center;
	line-height: 1.3;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
</style>
