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

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

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

				<view v-else 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>

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

<script>
import { pullLabelVideoPage, pullRecommendVideoPage } from '@/features/travel/gateway'
import { videoDetailUrl } from '@/features/dynamics/post-media'

const CARD_GRADIENTS = [
	'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%)'
]

export default {
	data() {
		return {
			statusBar: 0,
			scrollHeight: 600,
			safeBottom: 0,
			labelId: '',
			orderType: '',
			isHotDian: '',
			pageTitle: '',
			cards: [],
			page: 1,
			lastPage: 1,
			loading: false,
			loaded: false,
			refreshing: false,
			loadStatus: 'more'
		}
	},
	computed: {
		copy() {
			const t = this.$t.bind(this)
			return {
				video: t('home.video'),
				sectionHot: t('home.sectionHot'),
				loading: t('home.loading'),
				loadFailed: t('home.loadFailed'),
				emptyVideos: t('home.emptyVideos')
			}
		},
		loadMoreText() {
			const t = this.$t.bind(this)
			return {
				contentdown: t('home.loadMore'),
				contentrefresh: t('home.loading'),
				contentnomore: t('home.noMore')
			}
		},
		leftCol() {
			return this.cards.filter((_, i) => i % 2 === 0)
		},
		rightCol() {
			return this.cards.filter((_, i) => i % 2 === 1)
		}
	},
	onLoad(query) {
		this.labelId = (query && query.label_id) != null ? String(query.label_id) : ''
		this.orderType = (query && query.order_type) != null ? String(query.order_type) : ''
		this.isHotDian = (query && query.is_hot_dian) != null ? String(query.is_hot_dian) : ''
		const title = (query && query.title) ? decodeURIComponent(query.title) : ''
		this.pageTitle = title || (this.orderType ? this.copy.sectionHot : this.copy.video)
		this.initLayout()
		this.reload()
	},
	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)
				this.scrollHeight = (info.windowHeight || info.screenHeight || 600) - navH
			} catch (_) { }
		},
		goBack() {
			uni.navigateBack({
				fail: () => uni.switchTab({ url: '/pages/index/index' })
			})
		},
		cardGradient(seed) {
			const hash = String(seed).split('').reduce((a, c) => a + c.charCodeAt(0), 0)
			return CARD_GRADIENTS[hash % CARD_GRADIENTS.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
		},
		async reload() {
			this.page = 1
			this.lastPage = 1
			this.loadStatus = 'more'
			this.loaded = false
			this.cards = []
			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 (!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 = this.orderType
					? await pullRecommendVideoPage({
						page: nextPage,
						orderType: this.orderType,
						isHotDian: this.isHotDian !== '' ? this.isHotDian : undefined
					})
					: await pullLabelVideoPage({
						labelId: this.labelId,
						page: nextPage
					})
				this.page = pack.currentPage
				this.lastPage = pack.lastPage
				if (reset) {
					this.cards = pack.rows.map((row) =>
						Object.assign({}, row, { listPage: pack.currentPage })
					)
				} else {
					this.cards = this.cards.concat(
						pack.rows.map((row) =>
							Object.assign({}, row, { listPage: pack.currentPage })
						)
					)
				}
				this.loadStatus =
					pack.currentPage >= pack.lastPage || !pack.rows.length ? 'noMore' : 'more'
				this.loaded = true
			} catch (err) {
				this.loadStatus = 'more'
				if (reset) this.cards = []
				this.$appKit && this.$appKit.msg(err.message || this.copy.loadFailed)
				this.loaded = true
			} finally {
				this.loading = false
			}
		},
		onCardTap(card) {
			if (!card) return
			const id = (card.raw && card.raw.id) || card.id
			if (!id) return
			// 顶部菜单（label_id）入口才传 label_id；推荐更多（order_type）入口不传
			uni.navigateTo({
				url: videoDetailUrl(id, {
					labelId: this.labelId || undefined,
					page: card.listPage || (card.raw && card.raw.page) || 1,
					orderType: this.orderType || undefined,
					isHotDian: this.isHotDian !== '' ? this.isHotDian : undefined
				})
			})
		}
	}
}
</script>

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

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

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

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

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

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

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

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

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

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

.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;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

.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;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.card-like {
	font-size: 22rpx;
	color: #8a8d9e;
	flex-shrink: 0;
}
</style>
