<template>
	<view class="home">
		<!-- 顶部：城市选择 + 搜索框（固定，列表在 scroll-view 内滚动） -->
		<view class="hd" :style="{ paddingTop: (statusBar + 16) + 'px' }">
			<view class="hd-row">
				<view class="hd-region" @tap="onRegionTap">
					<text class="hd-region-name">{{ region.name }}</text>
					<text class="hd-region-arrow">▾</text>
				</view>
				<view class="hd-search" @tap="onSearchTap">
					<text class="hd-search-icon">🔍</text>
					<text class="hd-search-placeholder">{{ copy.searchPlaceholder }}</text>
				</view>
			</view>
		</view>

		<scroll-view class="home-scroll" scroll-y :style="{ height: scrollHeight + 'px' }" :show-scrollbar="false"
			:refresher-enabled="true" :refresher-triggered="refreshing" refresher-background="#f7f8fc"
			refresher-default-style="black" @refresherrefresh="onRefresherRefresh" @refresherrestore="onRefresherEnd"
			@refresherabort="onRefresherEnd">
			<view class="home-body">
				<!-- 5 圆形分类 -->
				<view class="cats">
					<scroll-view scroll-x class="cats-scroll" :show-scrollbar="false">
						<view class="cats-list">
							<view v-for="(cat, idx) in displayedCategories" :key="cat.id" class="cat" @tap="onCategoryTap(cat)">
								<view class="cat-circle" :style="{ background: catColor(idx) }">
									<image v-if="cat.icon" class="cat-icon" :src="cat.icon" mode="aspectFit" />
									<text v-else class="cat-emoji">{{ catEmoji(idx) }}</text>
								</view>
								<text class="cat-name">{{ cat.name }}</text>
							</view>
						</view>
					</scroll-view>
				</view>

				<!-- Banner 大图 -->
				<view class="banner">
					<swiper class="banner-swiper" :autoplay="true" :interval="3500" :duration="600" :circular="true"
						:indicator-dots="banners.length > 1" indicator-color="rgba(255,255,255,0.45)"
						indicator-active-color="#ffffff">
						<swiper-item v-for="b in banners" :key="b.id">
							<image class="banner-img" :src="b.image" mode="aspectFill" @tap="onBannerTap(b)" />
						</swiper-item>
					</swiper>
				</view>

				<!-- 服务入口（/other/menuData） -->
				<view v-if="displayedServices.length" class="services">
					<view v-for="(svc, idx) in displayedServices" :key="svc.id || idx" class="service" @tap="onServiceTap(svc)">
						<view class="service-icon-wrap" :style="{ background: svcColor(idx).bg }">
							<image v-if="svc.image" class="service-icon-img" :src="svc.image" mode="aspectFit" />
							<text v-else class="service-icon">{{ svc.icon || '•' }}</text>
						</view>
						<text class="service-name">{{ svc.name }}</text>
					</view>
				</view>

				<!-- 热门景区 -->
				<view v-if="hotScenics.length" class="section">
					<view class="section-hd">
						<text class="section-title-cn">{{ copy.sectionHotScenic }}</text>
						<text class="section-title-en">{{ copy.sectionHotScenicEn }}</text>
						<text class="section-more" @tap="onHotScenicMoreTap">{{ copy.more }}</text>
					</view>
					<scroll-view scroll-x enable-flex class="hot-scenic-scroll" :show-scrollbar="false">
						<view class="hot-scenic-list">
							<view v-for="(item, idx) in hotScenics" :key="'scenic-' + (item.id != null ? item.id : idx)"
								class="hot-scenic-card" @tap="onHotScenicTap(item)">
								<view v-if="item.image" class="hot-scenic-img"
									:style="{ backgroundImage: 'url(' + item.image + ')' }" />
								<view v-else class="hot-scenic-img hot-scenic-img--ph"
									:style="{ background: attractionGradient(idx) }" />
								<view class="hot-scenic-mask" />
								<view class="hot-scenic-name-wrap">
									<text class="hot-scenic-name">{{ scenicTitle(item) }}</text>
								</view>
							</view>
						</view>
					</scroll-view>
				</view>

				<!-- 热门景点（视频横滑，默认关闭，见 HOME_SHOW_HOT_ATTRACTIONS） -->
				<view v-if="showHotAttractions && attractions.length" class="section">
					<view class="section-hd">
						<text class="section-title-cn">{{ copy.sectionAttractions }}</text>
						<text class="section-title-en">{{ copy.sectionAttractionsEn }}</text>
					</view>
					<scroll-view scroll-x enable-flex class="attractions-scroll" :show-scrollbar="false">
						<view class="attractions">
							<view v-for="(a, idx) in attractions" :key="'attr-' + (a.id != null ? a.id : idx)" class="attraction"
								:class="{ 'attraction--first': idx === 0 }" @tap="onAttractionTap(a)">
								<view v-if="a.image" class="attraction-img" :style="{ backgroundImage: 'url(' + a.image + ')' }" />
								<view v-else class="attraction-placeholder" :style="{ background: attractionGradient(idx) }" />
								<view class="attraction-mask" />
								<view class="attraction-name-wrap">
									<view class="attraction-name-plate">
										<text class="attraction-name">{{ a.name || attractionName(a) }}</text>
									</view>
								</view>
							</view>
						</view>
					</scroll-view>
				</view>

				<!-- 推荐视频瀑布流 -->
				<view class="section">
					<view class="section-hd">
						<text class="section-title-cn">{{ copy.sectionHot }}</text>
						<text class="section-title-en">{{ copy.sectionHotEn }}</text>
						<text class="section-more" @tap="onMoreTap">{{ copy.more }}</text>
					</view>
					<view class="waterfall">
						<view class="waterfall-col">
							<view v-for="card in leftCol" :key="card.id" class="card" @tap="onCardTap(card)">
								<image v-if="card.cover" class="card-cover" :src="card.cover" mode="widthFix" />
								<view v-else class="card-cover-placeholder" :style="{ background: cardGradient(card.id) }" />
								<view class="card-body">
									<text class="card-title">{{ card.title }}</text>
									<view class="card-meta">
										<image v-if="card.avatar" class="card-avatar" :src="card.avatar" mode="aspectFill" />
										<view v-else class="card-avatar card-avatar-fallback" />
										<text class="card-user">{{ card.user }}</text>
										<text class="card-like">♡ {{ formatLikes(card.likes) }}</text>
									</view>
								</view>
							</view>
						</view>
						<view class="waterfall-col">
							<view v-for="card in rightCol" :key="card.id" class="card" @tap="onCardTap(card)">
								<image v-if="card.cover" class="card-cover" :src="card.cover" mode="widthFix" />
								<view v-else class="card-cover-placeholder" :style="{ background: cardGradient(card.id) }" />
								<view class="card-body">
									<text class="card-title">{{ card.title }}</text>
									<view class="card-meta">
										<image v-if="card.avatar" class="card-avatar" :src="card.avatar" mode="aspectFill" />
										<view v-else class="card-avatar card-avatar-fallback" />
										<text class="card-user">{{ card.user }}</text>
										<text class="card-like">♡ {{ formatLikes(card.likes) }}</text>
									</view>
								</view>
							</view>
						</view>
					</view>
					<view v-if="recommendations.length === 0 && !loading" class="empty-tip">
						<text class="empty-tip-text">{{ copy.emptyRecommend }}</text>
					</view>
				</view>

				<!-- 底部留白，避免被 tabbar 遮挡 -->
				<view class="bottom-safe" :style="{ height: bottomInset + 'px' }" />
			</view>
		</scroll-view>

		<!-- 全局自定义 tabbar -->
		<app-tabbar active="home" />
		<!-- #ifdef APP-PLUS -->
		<app-update-sheet />
		<!-- #endif -->
	</view>
</template>

<script>
import AppTabbar from '@/components/app-tabbar/app-tabbar.vue'
// #ifdef APP-PLUS
import AppUpdateSheet from '@/components/app-update-sheet/app-update-sheet.vue'
// #endif
import {
	pullHomeBanners,
	pullHomeCategories,
	pullHomeServices,
	pullHotAttractions,
	pullRecommendations
} from '@/features/travel/gateway'
import { pullHotScenicAreas } from '@/features/scenic/scenic-gateway'
import { videoDetailUrl } from '@/features/dynamics/post-media'
import { openJumpUrl, openExternalUrl, openInAppRoute, isExternalHttpUrl } from '@/core/nav/navigation'

const DEFAULT_CATEGORY_DEFS = [
	{ id: 'd1', nameKey: 'home.catHot', icon: '' },
	{ id: 'd2', nameKey: 'home.catTravel', icon: '' },
	{ id: 'd3', nameKey: 'home.catWater', icon: '' },
	{ id: 'd4', nameKey: 'home.catFamily', icon: '' },
	{ id: 'd5', nameKey: 'home.catFood', icon: '' }
]
const DEFAULT_ATTRACTION_DEFS = [
	{ id: 'a1', nameKey: 'home.attrCauseway', image: '' },
	{ id: 'a2', nameKey: 'home.attrHarbour', image: '' },
	{ id: 'a3', nameKey: 'home.attrAvenue', image: '' }
]
const REGION_CODES = ['HK', 'MO', 'SZ', 'GZ']

/** 首页「热门景点」视频横滑栏开关，改为 true 可恢复展示 */
const HOME_SHOW_HOT_ATTRACTIONS = false

const CAT_COLORS = [
	'linear-gradient(135deg, #ffb6c1 0%, #ff6b9d 100%)',
	'linear-gradient(135deg, #b9eed4 0%, #6dd4a8 100%)',
	'linear-gradient(135deg, #b6d4ff 0%, #6ba0ff 100%)',
	'linear-gradient(135deg, #ffd9a8 0%, #ff9a6b 100%)',
	'linear-gradient(135deg, #ffcde0 0%, #ff8eb4 100%)'
]
const CAT_EMOJIS = ['🏛️', '🗺️', '⛵', '👨‍👩‍👧', '🍱']
const SVC_COLORS = [
	{ bg: 'rgba(255, 107, 107, 0.12)' },
	{ bg: 'rgba(74, 140, 255, 0.12)' },
	{ bg: 'rgba(255, 184, 77, 0.12)' },
	{ bg: 'rgba(123, 196, 132, 0.12)' }
]
const ATTRACTION_GRADIENTS = [
	'linear-gradient(135deg, #4c5dc7 0%, #6b78ff 100%)',
	'linear-gradient(135deg, #2d4068 0%, #4a6797 100%)',
	'linear-gradient(135deg, #6a4a6e 0%, #a06b9f 100%)'
]
const TABBAR_H = 100

export default {
	// #ifdef APP-PLUS
	components: { AppTabbar, AppUpdateSheet },
	// #endif
	// #ifndef APP-PLUS
	components: { AppTabbar },
	// #endif
	data() {
		return {
			statusBar: 0,
			safeBottom: 0,
			windowHeight: 667,
			refreshing: false,
			loading: false,
			regionCode: 'HK',
			banners: [],
			categories: [],
			services: [],
			attractions: [],
			hotScenics: [],
			recommendations: [],
			// iOS 首次安装网络授权弹窗会打断首屏请求，需授权后自动重载
			_homeLoadFailed: false,
			_autoRetryTimer: null,
			_unsubscribeNetwork: null,
			_loadAllRunning: false
		}
	},
	computed: {
		copy() {
			const t = this.$t.bind(this)
			return {
				searchPlaceholder: t('home.searchPlaceholder'),
				sectionHot: t('home.sectionHot'),
				sectionHotEn: t('home.sectionHotEn'),
				sectionAttractions: t('home.sectionAttractions'),
				sectionAttractionsEn: t('home.sectionAttractionsEn'),
				sectionHotScenic: t('home.sectionHotScenic'),
				sectionHotScenicEn: t('home.sectionHotScenicEn'),
				more: t('home.more'),
				emptyRecommend: t('home.emptyRecommend'),
				loading: t('home.loading'),
				regionDefault: t('home.regionDefault'),
				regionHk: t('home.regionHk'),
				// regionMo: t('home.regionMo'),
				// regionSz: t('home.regionSz'),
				// regionGz: t('home.regionGz'),
				categoryUnavailable: t('home.categoryUnavailable'),
				categoryLoading: t('home.categoryLoading'),
				videoUnavailable: t('home.videoUnavailable'),
				video: t('home.video')
			}
		},
		region() {
			return {
				code: this.regionCode,
				name: this.regionName(this.regionCode)
			}
		},
		defaultCategories() {
			const t = this.$t.bind(this)
			return DEFAULT_CATEGORY_DEFS.map((item) => ({
				id: item.id,
				icon: item.icon,
				name: t(item.nameKey)
			}))
		},
		// 默认景点（/other/menuData）
		defaultAttractions() {
			const t = this.$t.bind(this)
			return DEFAULT_ATTRACTION_DEFS.map((item) => ({
				id: item.id,
				image: item.image,
				name: t(item.nameKey)
			}))
		},
		// 分类（/other/menuData）
		displayedCategories() {
			return this.categories.length ? this.categories : this.defaultCategories
		},
		// 服务入口（/other/menuData）
		displayedServices() {
			// return this.services
			// 本地注入的"商城"入口
			const localMall = {
				id: 'menu-4',
				name: '商城',
				image: '/static/imgs/icon/mall.png',
				link: '/pages/mall/index',
				type: '1'
			}

			// 保留后端返回的前 4 个，末尾加商城 → 一共 5 个
			return [...this.services.slice(0, 4), localMall]
		},
		showHotAttractions() {
			return HOME_SHOW_HOT_ATTRACTIONS
		},
		displayedAttractions() {
			return this.attractions.length ? this.attractions : this.defaultAttractions
		},
		leftCol() {
			return this.recommendations.filter((_, i) => i % 2 === 0)
		},
		rightCol() {
			return this.recommendations.filter((_, i) => i % 2 === 1)
		},
		tabbarPad() {
			return uni.upx2px(TABBAR_H)
		},
		headerHeight() {
			// 顶内边距 + 搜索行(约72rpx) + 底内边距24rpx
			return this.statusBar + 16 + uni.upx2px(96)
		},
		tabbarTotalHeight() {
			return this.tabbarPad + this.safeBottom
		},
		scrollHeight() {
			return Math.max(200, this.windowHeight - this.headerHeight - this.tabbarTotalHeight)
		},
		bottomInset() {
			return this.tabbarTotalHeight + uni.upx2px(24)
		}
	},
	onLoad() {
		try {
			const info = uni.getSystemInfoSync()
			this.statusBar = info.statusBarHeight || 0
			this.safeBottom = (info.safeAreaInsets && info.safeAreaInsets.bottom) || 0
			this.windowHeight = info.windowHeight || 667
		} catch (_) { }
		this.setupAutoReloadOnNetwork()
		this.loadAll()
	},
	onUnload() {
		if (this._autoRetryTimer) {
			clearTimeout(this._autoRetryTimer)
			this._autoRetryTimer = null
		}
		if (typeof this._unsubscribeNetwork === 'function') {
			try { this._unsubscribeNetwork() } catch (_) { }
			this._unsubscribeNetwork = null
		}
	},
	onShow() {
		// 授权弹窗关闭后回到前台：兜底重试一次首屏数据
		this.retryHomeLoad('onShow')
		// 每次 onShow 都强制 hide 系统 tabbar：
		//   1) 首次进入：藏掉系统 tabbar 给 AppTabbar 让位；
		//   2) 从 feed 切回来：feed 期间系统 tabbar 处于 show 状态，
		//      在 home 的 webview layout 阶段重新 hide，能正确触发 viewport 扩大，
		//      消除"AppTabbar 被抬高 + 下方一块黑色空白"的视觉。
		// setTimeout(0) 把 hide 推到下一个事件循环：避开页面首次渲染、
		// applicationDidBecomeActive 同步触发的时机冲突，规避白屏。
		setTimeout(() => {
			try { uni.hideTabBar({ animation: false }) } catch (_) { }
		}, 0)
	},
	methods: {
		onRefresherRefresh() {
			this.pullRefresh()
		},
		onRefresherEnd() {
			this.refreshing = false
		},
		async pullRefresh() {
			if (this.refreshing) return
			this.refreshing = true
			try {
				await this.loadAll({ keepContent: true })
			} finally {
				this.refreshing = false
			}
		},
		setupAutoReloadOnNetwork() {
			if (this._unsubscribeNetwork) return
			try {
				this._unsubscribeNetwork = uni.onNetworkStatusChange((res) => {
					if (res && res.isConnected) {
						this.retryHomeLoad('network-connected')
					}
				})
			} catch (_) { }
		},
		retryHomeLoad(reason = 'unknown') {
			if (!this._homeLoadFailed || this._loadAllRunning) return
			if (this._autoRetryTimer) {
				clearTimeout(this._autoRetryTimer)
				this._autoRetryTimer = null
			}
			this._autoRetryTimer = setTimeout(() => {
				this.loadAll()
			}, reason === 'onShow' ? 150 : 300)
		},
		markHomeLoadResult() {
			const apiOk = this.categories.length > 0 || this.recommendations.length > 0
			this._homeLoadFailed = !apiOk
		},
		async loadAll(options = {}) {
			const keepContent = options.keepContent === true
			if (this._loadAllRunning) return
			this._loadAllRunning = true
			if (!keepContent) this.loading = true
			try {
				const tasks = [
					this.fetchBanners(),
					this.fetchCategories(),
					this.fetchServices(),
					this.fetchHotScenics(),
					this.fetchRecommendations()
				]
				if (HOME_SHOW_HOT_ATTRACTIONS) {
					tasks.push(this.fetchAttractions())
				} else {
					this.attractions = []
				}
				await Promise.all(tasks)
				this.markHomeLoadResult()
			} catch (_) {
				this._homeLoadFailed = true
			} finally {
				this.loading = false
				this._loadAllRunning = false
			}
		},
		async fetchBanners() {
			try {
				const rows = await pullHomeBanners()
				if (rows.length) this.banners = rows
				else this.banners = this.placeholderBanners()
			} catch (_) {
				this.banners = this.placeholderBanners()
			}
		},
		placeholderBanners() {
			// 接口未配时的占位：单条空 banner，渲染为渐变色块
			return [{ id: 'ph1', image: '', link: '', title: '' }]
		},
		async fetchCategories() {
			try {
				const rows = await pullHomeCategories()
				if (rows.length) this.categories = rows
			} catch (_) { }
		},
		async fetchServices() {
			try {
				const rows = await pullHomeServices()
				if (rows.length) this.services = rows
			} catch (_) { }
		},
		async fetchHotScenics() {
			try {
				this.hotScenics = await pullHotScenicAreas({ page: 1, pageSize: 12 })
			} catch (_) {
				this.hotScenics = []
			}
		},
		async fetchAttractions() {
			try {
				this.attractions = await pullHotAttractions({ page: 1, pageSize: 12 })
			} catch (_) {
				this.attractions = []
			}
		},
		async fetchRecommendations() {
			try {
				const rows = await pullRecommendations({ page: 1, pageSize: 20, isHotDian: 1 })
				this.recommendations = rows.map((row) =>
					Object.assign({}, row, {
						listPage: 1,
						order_type: 1,
						is_hot_dian: 1
					})
				)
			} catch (_) {
				this.recommendations = []
			}
		},
		catColor(idx) {
			return CAT_COLORS[idx % CAT_COLORS.length]
		},
		catEmoji(idx) {
			return CAT_EMOJIS[idx % CAT_EMOJIS.length]
		},
		svcColor(idx) {
			return SVC_COLORS[idx % SVC_COLORS.length]
		},
		attractionGradient(idx) {
			return ATTRACTION_GRADIENTS[idx % ATTRACTION_GRADIENTS.length]
		},
		attractionName(item) {
			if (!item) return ''
			const direct = String(item.name || '').trim()
			if (direct) return direct
			const labelId = item.label_id
			if (labelId != null && labelId !== '' && this.categories.length) {
				const cat = this.categories.find((c) => String(c.id) === String(labelId))
				if (cat && cat.name) return cat.name
			}
			return ''
		},
		scenicTitle(item) {
			if (!item) return ''
			return String(item.title || item.name || '').trim()
		},
		cardGradient(seed) {
			const palette = [
				'linear-gradient(135deg, #f7d4b8 0%, #e8a87c 100%)',
				'linear-gradient(135deg, #c1c8d6 0%, #8e96a6 100%)',
				'linear-gradient(135deg, #f4c5d8 0%, #de8aae 100%)',
				'linear-gradient(135deg, #c5dcc4 0%, #8eb592 100%)'
			]
			const hash = String(seed).split('').reduce((a, c) => a + c.charCodeAt(0), 0)
			return palette[hash % palette.length]
		},
		formatLikes(n) {
			const v = Number(n) || 0
			if (v >= 10000) return (v / 10000).toFixed(1) + 'w'
			if (v >= 1000) return (v / 1000).toFixed(1) + 'k'
			return v
		},
		regionName(code) {
			const map = {
				HK: this.copy.regionHk,
				MO: this.copy.regionMo,
				SZ: this.copy.regionSz,
				GZ: this.copy.regionGz
			}
			return map[code] || this.copy.regionDefault
		},
		onRegionTap() {
			uni.showActionSheet({
				itemList: [
					this.copy.regionHk,
					this.copy.regionMo,
					this.copy.regionSz,
					this.copy.regionGz
				],
				success: (res) => {
					this.regionCode = REGION_CODES[res.tapIndex] || 'HK'
					this.loadAll()
				}
			})
		},
		onSearchTap() {
			uni.navigateTo({ url: '/pages/search/index?type=find' })
		},
		onCategoryTap(cat) {
			if (!cat || cat.id == null || cat.id === '') {
				uni.showToast({ title: this.copy.categoryUnavailable, icon: 'none' })
				return
			}
			const idStr = String(cat.id)
			if (/^d\d+$/.test(idStr)) {
				uni.showToast({ title: this.copy.categoryLoading, icon: 'none' })
				return
			}
			const title = encodeURIComponent(cat.name || this.copy.video)
			uni.navigateTo({
				url: `/pages/index/video-list?label_id=${encodeURIComponent(idStr)}&title=${title}`
			})
		},
		onBannerTap(b) {
			if (!b) return
			const target = b.jump_url || b.link
			if (target) {
				openJumpUrl(target, { title: b.title || '' })
			}
		},
		onServiceTap(svc) {
			if (!svc) return
			const type = String(svc.type != null ? svc.type : '')
			const link = String(svc.link || svc.jump_url || '').trim()
			const title = svc.name || ''

			if (type === '1') {
				if (!link) {
					uni.showToast({
						title: this.$t('home.devToast', { name: svc.name || '—' }),
						icon: 'none'
					})
					return
				}
				if (!openInAppRoute(link)) {
					uni.showToast({ title: '页面不存在', icon: 'none' })
				}
				return
			}

			if (!link) {
				uni.showToast({
					title: this.$t('home.devToast', { name: svc.name || '—' }),
					icon: 'none'
				})
				return
			}
			if (type === '0') {
				const href = link.startsWith('//') ? `https:${link}` : link
				if (isExternalHttpUrl(href)) {
					openExternalUrl(href)
					return
				}
				uni.showToast({
					title: this.$t('home.devToast', { name: svc.name || '—' }),
					icon: 'none'
				})
				return
			}
			if (type === '2') {
				openJumpUrl(link, { title })
				return
			}
			openJumpUrl(link, { title })
		},
		onHotScenicMoreTap() {
			uni.navigateTo({ url: '/pages/index/scenic-list' })
		},
		onHotScenicTap(item) {
			if (!item || item.id == null) return
			const title = encodeURIComponent(item.title || '')
			uni.navigateTo({
				url: `/pages/index/scenic-detail?id=${encodeURIComponent(item.id)}&title=${title}`
			})
		},
		onAttractionTap(a) {
			if (!a) return
			this.onCardTap({
				id: a.id,
				listPage: a.listPage || 1,
				raw: a.raw || { id: a.id }
			})
		},
		onCardTap(card) {
			if (!card) return
			const id = (card.raw && card.raw.id) || card.id
			if (id == null || id === '') {
				this.$appKit && this.$appKit.msg(this.copy.videoUnavailable)
				return
			}
			const orderType = card.order_type != null && card.order_type !== ''
				? card.order_type
				: (card.raw && card.raw.order_type)
			const isHotDian = card.is_hot_dian != null && card.is_hot_dian !== ''
				? card.is_hot_dian
				: (card.raw && card.raw.is_hot_dian)
			const payload = {
				id,
				type: 'video',
				page: card.listPage || 1,
				order_type: orderType,
				is_hot_dian: isHotDian
			}
			if (this.$appKit && typeof this.$appKit.onFind === 'function') {
				this.$appKit.onFind(payload)
				return
			}
			uni.navigateTo({
				url: videoDetailUrl(id, {
					page: payload.page,
					orderType: payload.order_type,
					isHotDian: payload.is_hot_dian
				})
			})
		},
		onMoreTap() {
			uni.navigateTo({
				url: `/pages/index/video-list?order_type=1&is_hot_dian=1&title=${encodeURIComponent(this.copy.sectionHot)}`
			})
		}
	}
}
</script>

<style>
page {
	background-color: #f7f8fc;
}

.home {
	height: 100vh;
	background-color: #f7f8fc;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.home-scroll {
	width: 100%;
	flex: 1;
}

.home-body {
	width: 100%;
}

/* ==== 顶部 ==== */
.hd {
	flex-shrink: 0;
	padding: 0 32rpx 24rpx;
	background-color: #ffffff;
	box-shadow: 0 2rpx 16rpx rgba(26, 29, 41, 0.06);
}

.hd-row {
	display: flex;
	flex-direction: row;
	align-items: center;
}

.hd-region {
	display: flex;
	flex-direction: row;
	align-items: center;
	padding-right: 24rpx;
	flex-shrink: 0;
}

.hd-region-name {
	font-size: 30rpx;
	font-weight: 600;
	color: #1a1d29;
	margin-right: 6rpx;
}

.hd-region-arrow {
	font-size: 24rpx;
	color: #1a1d29;
}

.hd-search {
	flex: 1;
	display: flex;
	flex-direction: row;
	align-items: center;
	background-color: #f0f1f5;
	border-radius: 36rpx;
	padding: 14rpx 24rpx;
}

.hd-search-icon {
	font-size: 26rpx;
	margin-right: 12rpx;
	opacity: 0.65;
}

.hd-search-placeholder {
	font-size: 24rpx;
	color: #8a8d9e;
	flex: 1;
}

/* ==== 圆形分类 ==== */
.cats {
	background-color: transparent;
	padding: 24rpx 0 8rpx;
}

.cats-scroll {
	white-space: nowrap;
}

.cats-list {
	display: inline-flex;
	flex-direction: row;
	padding: 0 32rpx;
}

.cat {
	display: flex;
	flex-direction: column;
	align-items: center;
	width: 130rpx;
	margin-right: 16rpx;
	flex-shrink: 0;
}

.cat-circle {
	width: 110rpx;
	height: 110rpx;
	border-radius: 28rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 10rpx;
	box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}

.cat-icon {
	width: 64rpx;
	height: 64rpx;
}

.cat-emoji {
	font-size: 48rpx;
}

.cat-name {
	font-size: 22rpx;
	color: #4a4d5e;
	text-align: center;
}

/* ==== Banner ==== */
.banner {
	padding: 16rpx 32rpx 8rpx;
}

.banner-swiper {
	width: 100%;
	height: 320rpx;
	border-radius: 24rpx;
	overflow: hidden;
}

.banner-img {
	width: 100%;
	height: 100%;
	background: linear-gradient(135deg, #4a8cff 0%, #6ba0ff 50%, #93c0ff 100%);
}

/* ==== 4 服务入口 ==== */
.services {
	display: flex;
	flex-direction: row;
	padding: 24rpx 32rpx 16rpx;
}

.service {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
}

.service-icon-wrap {
	width: 88rpx;
	height: 88rpx;
	border-radius: 22rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 10rpx;
}

.service-icon {
	font-size: 40rpx;
}

.service-icon-img {
	width: 52rpx;
	height: 52rpx;
}

.service-name {
	font-size: 22rpx;
	color: #4a4d5e;
}

/* ==== Section ==== */
.section {
	margin-top: 32rpx;
}

.section-hd {
	display: flex;
	flex-direction: row;
	align-items: baseline;
	padding: 0 32rpx 20rpx;
}

.section-title-cn {
	font-size: 32rpx;
	font-weight: 700;
	color: #1a1d29;
	margin-right: 12rpx;
}

.section-title-en {
	font-size: 20rpx;
	color: #8a8d9e;
	letter-spacing: 1rpx;
	flex: 1;
}

.section-more {
	font-size: 24rpx;
	color: #8a8d9e;
	flex-shrink: 0;
}

/* ==== 热门景区 ==== */
.hot-scenic-scroll {
	width: 100%;
	flex-direction: row;
}

.hot-scenic-list {
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
	padding-left: 32rpx;
	padding-right: 32rpx;
}

.hot-scenic-card {
	width: 280rpx;
	height: 180rpx;
	border-radius: 20rpx;
	overflow: hidden;
	position: relative;
	margin-right: 16rpx;
	flex-shrink: 0;
	background-color: #ddd;
}

.hot-scenic-img {
	width: 100%;
	height: 100%;
	position: absolute;
	left: 0;
	top: 0;
	z-index: 0;
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

.hot-scenic-img--ph {
	background-size: cover;
	background-position: center;
}

.hot-scenic-mask {
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	bottom: 0;
	z-index: 1;
	background: rgba(0, 0, 0, 0.28);
}

.hot-scenic-name-wrap {
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	bottom: 0;
	z-index: 2;
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: center;
	padding: 0 16rpx;
	box-sizing: border-box;
}

.hot-scenic-name {
	display: block;
	width: 100%;
	font-size: 28rpx;
	font-weight: 700;
	color: #ffffff;
	text-align: center;
	line-height: 40rpx;
	white-space: normal;
	word-break: break-all;
	text-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.35);
}

/* ==== 热门景点 ==== */
.attractions-scroll {
	width: 100%;
	flex-direction: row;
}

.attractions {
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
	padding-right: 32rpx;
}

.attraction {
	width: 240rpx;
	height: 280rpx;
	border-radius: 20rpx;
	overflow: hidden;
	position: relative;
	margin-right: 16rpx;
	flex-shrink: 0;
	background-color: #ddd;
}

.attraction--first {
	margin-left: 32rpx;
}

.attraction-img {
	width: 100%;
	height: 100%;
	position: absolute;
	left: 0;
	top: 0;
	z-index: 0;
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

.attraction-placeholder {
	width: 100%;
	height: 100%;
	position: absolute;
	left: 0;
	top: 0;
}

.attraction-mask {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 50%;
	z-index: 1;
	background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%);
}

.attraction-name-wrap {
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	bottom: 0;
	z-index: 2;
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: center;
	padding: 0 12rpx;
	box-sizing: border-box;
}

.attraction-name-plate {
	max-width: 100%;
	padding: 0;
	box-sizing: border-box;
}

.attraction-name {
	display: block;
	width: 100%;
	color: #ffffff;
	font-size: 26rpx;
	font-weight: 700;
	text-align: center;
	line-height: 38rpx;
	white-space: normal;
	word-break: break-all;
	text-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.35);
}

/* ==== 热点推荐瀑布流 ==== */
.waterfall {
	display: flex;
	flex-direction: row;
	padding: 0 24rpx;
}

.waterfall-col {
	flex: 1;
	display: flex;
	flex-direction: column;
	padding: 0 8rpx;
}

.card {
	background-color: #ffffff;
	border-radius: 18rpx;
	overflow: hidden;
	margin-bottom: 16rpx;
	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}

.card-cover {
	width: 100%;
	display: block;
}

.card-cover-placeholder {
	width: 100%;
	height: 320rpx;
}

.card-body {
	padding: 16rpx 18rpx 18rpx;
}

.card-title {
	font-size: 26rpx;
	color: #1a1d29;
	line-height: 36rpx;
	font-weight: 500;
}

.card-meta {
	display: flex;
	flex-direction: row;
	align-items: center;
	margin-top: 14rpx;
}

.card-avatar {
	width: 36rpx;
	height: 36rpx;
	border-radius: 18rpx;
	margin-right: 8rpx;
	background-color: #e6e8ef;
}

.card-avatar-fallback {
	background: linear-gradient(135deg, #4a8cff 0%, #6ba0ff 100%);
}

.card-user {
	font-size: 22rpx;
	color: #4a4d5e;
	flex: 1;
}

.card-like {
	font-size: 22rpx;
	color: #8a8d9e;
}

/* ==== 空态 ==== */
.empty-tip {
	padding: 60rpx 0;
	display: flex;
	align-items: center;
	justify-content: center;
}

.empty-tip-text {
	font-size: 24rpx;
	color: #8a8d9e;
}

.bottom-safe {
	width: 100%;
}
</style>
