<template>
	<view class="sl-page">
		<view class="sl-hd" :style="{ paddingTop: statusBar + 'px' }">
			<view class="sl-nav-row">
				<view class="sl-back" @tap="goBack">
					<text class="sl-back-icon">←</text>
				</view>
				<text class="sl-nav-title">{{ copy.listTitle }}</text>
				<view class="sl-nav-placeholder" />
			</view>

			<scroll-view scroll-x class="sl-tabs-scroll" :show-scrollbar="false">
				<view class="sl-tabs">
					<view
						v-for="cat in categories"
						:key="cat.id"
						class="sl-tab"
						:class="{ 'sl-tab--on': String(activeCateId) === String(cat.id) }"
						@tap="onCateTap(cat)"
					>
						<text class="sl-tab-text">{{ cat.name }}</text>
					</view>
				</view>
			</scroll-view>
		</view>

		<scroll-view
			scroll-y
			class="sl-scroll"
			:style="{ height: scrollHeight + 'px' }"
			:lower-threshold="120"
			:refresher-enabled="true"
			:refresher-triggered="refreshing"
			@refresherrefresh="onRefresh"
			@refresherrestore="onRefreshEnd"
			@refresherabort="onRefreshEnd"
			@scrolltolower="onLoadMore"
		>
			<view class="sl-body" :style="{ paddingBottom: safeBottom + 'px' }">
				<view v-if="loading && !items.length" class="sl-state">
					<text class="sl-state-txt">{{ copy.loading }}</text>
				</view>

				<empty
					v-else-if="loaded && !items.length"
					src="find_default3x"
					:text="copy.empty"
				/>

				<view v-else class="sl-list">
					<view
						v-for="item in items"
						:key="item.id"
						class="sl-card"
						@tap="onItemTap(item)"
					>
						<view class="sl-card-cover-wrap">
							<image
								v-if="item.image"
								class="sl-card-cover"
								:src="item.image"
								mode="aspectFill"
							/>
							<view v-else class="sl-card-cover sl-card-cover--ph" />
						</view>
						<view class="sl-card-body">
							<text class="sl-card-title">{{ item.title }}</text>
							<text v-if="item.address" class="sl-card-addr">{{ item.address }}</text>
							<text class="sl-card-views">{{ copy.views }} {{ item.views }}</text>
						</view>
					</view>
				</view>

				<uni-load-more
					v-if="items.length"
					:status="loadStatus"
					:content-text="loadMoreText"
				/>
			</view>
		</scroll-view>
	</view>
</template>

<script>
import { pullScenicCategories, pullScenicAreaPage } from '@/features/scenic/scenic-gateway'

export default {
	data() {
		return {
			statusBar: 0,
			scrollHeight: 600,
			safeBottom: 0,
			categories: [],
			activeCateId: '',
			items: [],
			page: 1,
			lastPage: 1,
			loading: false,
			loaded: false,
			refreshing: false,
			loadStatus: 'more',
			/** 来自路由 query：cate_id / cateId / tab */
			initialCateId: ''
		}
	},
	computed: {
		copy() {
			const t = this.$t.bind(this)
			return {
				listTitle: t('scenic.listTitle'),
				loading: t('home.loading'),
				loadFailed: t('home.loadFailed'),
				empty: t('scenic.empty'),
				views: t('scenic.views')
			}
		},
		loadMoreText() {
			const t = this.$t.bind(this)
			return {
				contentdown: t('home.loadMore'),
				contentrefresh: t('home.loading'),
				contentnomore: t('home.noMore')
			}
		}
	},
	onLoad(query) {
		this.initialCateId = (query && (query.cate_id || query.cateId || query.tab)) || ''
		this.initLayout()
		this.bootstrap()
	},
	methods: {
		initLayout() {
			try {
				const info = uni.getSystemInfoSync()
				this.statusBar = info.statusBarHeight || 0
				this.safeBottom = (info.safeAreaInsets && info.safeAreaInsets.bottom) || 0
				const navH = this.statusBar + uni.upx2px(88) + uni.upx2px(72)
				this.scrollHeight = (info.windowHeight || info.screenHeight || 600) - navH
			} catch (_) {}
		},
		goBack() {
			uni.navigateBack({
				fail: () => uni.switchTab({ url: '/pages/index/index' })
			})
		},
		async bootstrap() {
			try {
				const cats = await pullScenicCategories()
				this.categories = cats
				if (cats.length) {
					this.activeCateId = this.resolveInitialCateId(cats)
					await this.reload()
				} else {
					this.loaded = true
				}
			} catch (err) {
				this.loaded = true
				this.$appKit && this.$appKit.msg((err && err.message) || this.copy.loadFailed)
			}
		},
		resolveInitialCateId(cats) {
			const preset = String(this.initialCateId || '').trim()
			if (!preset) return cats[0].id
			const byId = cats.find((c) => String(c.id) === preset)
			if (byId) return byId.id
			const decoded = decodeURIComponent(preset)
			const byName = cats.find((c) => c.name === decoded || c.name === preset)
			if (byName) return byName.id
			return cats[0].id
		},
		onCateTap(cat) {
			if (!cat || cat.id == null) return
			if (String(this.activeCateId) === String(cat.id)) return
			this.activeCateId = cat.id
			this.reload()
		},
		async reload() {
			this.page = 1
			this.lastPage = 1
			this.loadStatus = 'more'
			this.loaded = false
			this.items = []
			await this.loadPage(true)
		},
		onRefresh() {
			this.refreshing = true
			this.reload().finally(() => this.onRefreshEnd())
		},
		onRefreshEnd() {
			this.refreshing = false
		},
		onLoadMore() {
			if (this.loadStatus === 'loading' || this.loadStatus === 'noMore') return
			this.loadPage(false)
		},
		async loadPage(reset) {
			if (this.loading) return
			if (!this.activeCateId && this.activeCateId !== 0) return
			if (!reset && this.page >= this.lastPage) {
				this.loadStatus = 'noMore'
				return
			}
			const nextPage = reset ? 1 : this.page + 1
			this.loading = true
			this.loadStatus = 'loading'
			try {
				const pack = await pullScenicAreaPage({
					cateId: this.activeCateId,
					page: nextPage
				})
				this.page = pack.currentPage
				this.lastPage = pack.lastPage
				if (reset) {
					this.items = pack.rows
				} else {
					this.items = this.items.concat(pack.rows)
				}
				this.loadStatus =
					pack.currentPage >= pack.lastPage || !pack.rows.length ? 'noMore' : 'more'
				this.loaded = true
			} catch (err) {
				this.loadStatus = 'more'
				if (reset) this.items = []
				this.$appKit && this.$appKit.msg((err && err.message) || this.copy.loadFailed)
				this.loaded = true
			} finally {
				this.loading = false
			}
		},
		onItemTap(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}`
			})
		}
	}
}
</script>

<style scoped>
.sl-page {
	min-height: 100vh;
	background-color: #f7f8fc;
}

.sl-hd {
	background-color: #ffffff;
	border-bottom: 1rpx solid #eef1f6;
}

.sl-nav-row {
	display: flex;
	flex-direction: row;
	align-items: center;
	height: 88rpx;
	padding: 0 24rpx;
	box-sizing: border-box;
}

.sl-back {
	width: 64rpx;
	height: 64rpx;
	display: flex;
	align-items: center;
	justify-content: center;
}

.sl-back-icon {
	font-size: 40rpx;
	color: #1a1d26;
	line-height: 1;
}

.sl-nav-title {
	flex: 1;
	text-align: center;
	font-size: 32rpx;
	font-weight: 600;
	color: #1a1d26;
}

.sl-nav-placeholder {
	width: 64rpx;
}

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

.sl-tabs {
	display: flex;
	flex-direction: row;
	padding: 0 16rpx 16rpx;
	box-sizing: border-box;
}

.sl-tab {
	flex-shrink: 0;
	padding: 12rpx 28rpx;
	margin: 0 8rpx;
	border-radius: 999rpx;
	background-color: #f2f4f8;
}

.sl-tab--on {
	background: linear-gradient(135deg, #4a8cff 0%, #6ba0ff 100%);
}

.sl-tab-text {
	font-size: 26rpx;
	color: #4a4d5e;
	line-height: 1.2;
}

.sl-tab--on .sl-tab-text {
	color: #ffffff;
	font-weight: 600;
}

.sl-body {
	padding: 24rpx;
	box-sizing: border-box;
}

.sl-state {
	padding: 120rpx 0;
	text-align: center;
}

.sl-state-txt {
	font-size: 28rpx;
	color: #8a8d9e;
}

.sl-list {
	display: flex;
	flex-direction: column;
}

.sl-card {
	display: flex;
	flex-direction: row;
	align-items: stretch;
	background-color: #ffffff;
	border-radius: 18rpx;
	overflow: hidden;
	margin-bottom: 20rpx;
	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}

.sl-card-cover-wrap {
	width: 220rpx;
	min-height: 160rpx;
	flex-shrink: 0;
	overflow: hidden;
	background-color: #e6e8ef;
}

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

.sl-card-cover--ph {
	background: linear-gradient(135deg, #c1c8d6 0%, #8e96a6 100%);
}

.sl-card-body {
	flex: 1;
	padding: 20rpx 24rpx;
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-width: 0;
}

.sl-card-title {
	font-size: 28rpx;
	font-weight: 600;
	color: #1a1d26;
	line-height: 40rpx;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

.sl-card-addr {
	margin-top: 10rpx;
	font-size: 22rpx;
	color: #8a8d9e;
	line-height: 32rpx;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

.sl-card-views {
	margin-top: 12rpx;
	font-size: 22rpx;
	color: #4a8cff;
}
</style>
