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

		<scroll-view
			scroll-y
			class="art-scroll"
			:style="{ height: scrollHeight + 'px' }"
			:lower-threshold="120"
			@scrolltolower="onScrollToLower"
		>
			<view class="art-list-body" :style="{ paddingBottom: safeBottom + 'px' }">
				<view v-if="loading && !rows.length" class="art-state">
					<text class="art-state-txt">{{ copy.loading }}</text>
				</view>

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

				<view v-else class="art-list-stack">
					<view
						v-for="item in rows"
						:key="item.id"
						class="art-list-card"
						hover-class="art-list-card--press"
						@tap="openDetail(item)"
					>
						<view
							v-if="item.images && item.images.length > 2"
							class="art-list-media art-list-media--multi"
						>
							<image
								v-for="(img, key) in item.images.slice(0, 3)"
								:key="key"
								class="art-list-multi-img"
								:src="thumb(img)"
								mode="aspectFill"
							/>
							<view class="art-list-img-tag">
								<text class="art-list-img-tag-txt">{{ imageCountLabel(item.images.length) }}</text>
							</view>
						</view>

						<view
							v-else-if="coverImage(item)"
							class="art-list-row"
						>
							<image
								class="art-list-thumb"
								:src="thumb(coverImage(item))"
								mode="aspectFill"
							/>
							<view class="art-list-row-body">
								<text class="art-list-title">{{ item.title }}</text>
								<view class="art-list-foot">
									<text class="art-list-time">{{ item.createtime_text }}</text>
									<view class="art-list-foot-right">
										<text class="art-list-views">{{ viewsLabel(item.views) }}</text>
										<text
											v-if="flagClass(item)"
											class="art-list-flag"
											:class="'art-list-flag--' + flagClass(item)"
										>{{ item.flag_text }}</text>
									</view>
								</view>
							</view>
						</view>

						<view v-else class="art-list-text-only">
							<text class="art-list-title">{{ item.title }}</text>
							<view class="art-list-foot">
								<text class="art-list-time">{{ item.createtime_text }}</text>
								<view class="art-list-foot-right">
									<text class="art-list-views">{{ viewsLabel(item.views) }}</text>
									<text
										v-if="flagClass(item)"
										class="art-list-flag"
										:class="'art-list-flag--' + flagClass(item)"
									>{{ item.flag_text }}</text>
								</view>
							</view>
						</view>

						<template v-if="item.images && item.images.length > 2">
							<text class="art-list-title art-list-title--below">{{ item.title }}</text>
							<view class="art-list-foot">
								<text class="art-list-time">{{ item.createtime_text }}</text>
								<view class="art-list-foot-right">
									<text class="art-list-views">{{ viewsLabel(item.views) }}</text>
									<text
										v-if="flagClass(item)"
										class="art-list-flag"
										:class="'art-list-flag--' + flagClass(item)"
									>{{ item.flag_text }}</text>
								</view>
							</view>
						</template>
					</view>
				</view>

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

<script>
import { fetchArticleListPage } from '@/features/article/article-gateway'

export default {
	data() {
		return {
			statusBar: 0,
			scrollHeight: 600,
			safeBottom: 0,
			rows: [],
			page: 1,
			lastPage: 1,
			loading: false,
			loaded: false,
			loadStatus: 'more'
		}
	},
	computed: {
		copy() {
			const t = this.$t.bind(this)
			return {
				title: t('article.headlines'),
				loading: t('article.loading'),
				empty: t('article.empty'),
				views: t('article.views'),
				network: t('user.realnameNetworkError')
			}
		},
		loadMoreText() {
			return {
				contentdown: ' ',
				contentrefresh: this.copy.loading,
				contentnomore: ''
			}
		}
	},
	onLoad() {
		const sys = uni.getSystemInfoSync()
		this.statusBar = sys.statusBarHeight || 0
		this.safeBottom = sys.safeAreaInsets ? sys.safeAreaInsets.bottom : 0
		const navH = this.statusBar + uni.upx2px(88)
		this.scrollHeight = (sys.windowHeight || 667) - navH
		this.reloadList()
	},
	onPullDownRefresh() {
		this.reloadList()
	},
	methods: {
		goBack() {
			if (getCurrentPages().length > 1) {
				uni.navigateBack({ delta: 1 })
			} else {
				uni.switchTab({
					url: '/pages/index/index',
					fail: () => uni.reLaunch({ url: '/pages/index/index' })
				})
			}
		},
		thumb(url) {
			return this.$appKit && this.$appKit.oss ? this.$appKit.oss(url, 248, 0) : url
		},
		coverImage(item) {
			if (!item) return ''
			if (item.image) return item.image
			if (item.images && item.images.length) return item.images[0]
			return ''
		},
		imageCountLabel(n) {
			return this.$t('article.imageCount').replace('{n}', String(n))
		},
		viewsLabel(views) {
			return `${views || 0} ${this.copy.views}`
		},
		flagClass(item) {
			const flag = item && item.flag
			if (flag === 'hot' || flag === 'index' || flag === 'recommend') return flag
			return ''
		},
		openDetail(item) {
			if (!item || !item.id) return
			const title = encodeURIComponent(item.title || '')
			uni.navigateTo({
				url: `/pages/article/details?id=${item.id}&title=${title}`
			})
		},
		reloadList() {
			this.page = 1
			this.lastPage = 1
			this.rows = []
			this.loaded = false
			this.loadStatus = 'more'
			this.loadPage(true)
		},
		onScrollToLower() {
			if (this.loading || this.page >= this.lastPage) {
				this.loadStatus = 'noMore'
				return
			}
			this.page += 1
			this.loadStatus = 'loading'
			this.loadPage(false)
		},
		async loadPage(replace) {
			if (this.loading) return
			this.loading = true
			try {
				const res = await fetchArticleListPage(this.page, 'new')
				this.rows = replace ? res.rows : this.rows.concat(res.rows)
				this.page = res.currentPage
				this.lastPage = res.lastPage
				this.loadStatus = res.total === 0 || this.page >= this.lastPage ? 'noMore' : 'more'
			} catch (err) {
				this.$appKit.msg((err && err.message) || this.copy.network)
				this.loadStatus = 'more'
			} finally {
				this.loading = false
				this.loaded = true
				uni.stopPullDownRefresh()
			}
		}
	}
}
</script>

<style scoped>
@import './article-shared.css';

.art-list-page {
	min-height: 100vh;
	background-color: #f4f6fb;
}

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

.art-list-stack {
	display: flex;
	flex-direction: column;
	gap: 20rpx;
}

.art-list-card {
	background-color: #ffffff;
	border-radius: 24rpx;
	padding: 24rpx;
	box-shadow: 0 8rpx 32rpx rgba(26, 29, 38, 0.04);
}

.art-list-card--press {
	opacity: 0.92;
}

.art-list-media {
	position: relative;
	border-radius: 16rpx;
	overflow: hidden;
	margin-bottom: 16rpx;
}

.art-list-media--multi {
	display: flex;
	flex-direction: row;
	justify-content: space-between;
	height: 180rpx;
}

.art-list-multi-img {
	width: 32%;
	height: 100%;
	border-radius: 12rpx;
	background-color: #f0f3f8;
}

.art-list-img-tag {
	position: absolute;
	right: 0;
	bottom: 0;
	padding: 4rpx 14rpx;
	background: rgba(26, 29, 38, 0.65);
	border-top-left-radius: 12rpx;
}

.art-list-img-tag-txt {
	font-size: 22rpx;
	color: #ffffff;
}

.art-list-row {
	display: flex;
	flex-direction: row;
	align-items: flex-start;
}

.art-list-thumb {
	width: 220rpx;
	height: 160rpx;
	border-radius: 16rpx;
	background-color: #f0f3f8;
	flex-shrink: 0;
}

.art-list-row-body {
	flex: 1;
	min-width: 0;
	margin-left: 20rpx;
	min-height: 160rpx;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
}

.art-list-text-only {
	display: flex;
	flex-direction: column;
}

.art-list-title {
	display: block;
	font-size: 30rpx;
	font-weight: 600;
	color: #1a1d26;
	line-height: 1.45;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

.art-list-title--below {
	margin-top: 4rpx;
}

.art-list-foot {
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	margin-top: 16rpx;
}

.art-list-time {
	font-size: 24rpx;
	color: #8a8d9e;
}

.art-list-foot-right {
	display: flex;
	flex-direction: row;
	align-items: center;
}

.art-list-views {
	font-size: 24rpx;
	color: #8a8d9e;
}

.art-list-flag {
	margin-left: 12rpx;
	padding: 2rpx 12rpx;
	font-size: 20rpx;
	border-radius: 8rpx;
}

.art-list-flag--hot {
	color: #ea580c;
	background: rgba(234, 88, 12, 0.12);
}

.art-list-flag--index {
	color: #4a8cff;
	background: rgba(74, 140, 255, 0.12);
}

.art-list-flag--recommend {
	color: #e11d48;
	background: rgba(225, 29, 72, 0.1);
}
</style>
