<template>
	<view class="sr-page">
		<view class="sr-hd" :style="{ paddingTop: (statusBar + 12) + 'px' }">
			<view class="sr-hd-row">
				<view class="sr-back" @tap="goBack">
					<text class="sr-back-icon">←</text>
				</view>
				<view class="sr-search-bar" @tap="openSearch">
					<text class="sr-search-icon">🔍</text>
					<text class="sr-search-text">{{ keyword || copy.placeholder }}</text>
				</view>
			</view>

			<scroll-view scroll-x class="sr-tabs-scroll" :show-scrollbar="false">
				<view class="sr-tabs">
					<view
						v-for="(tab, index) in tabs"
						:key="tab.type"
						class="sr-tab"
						:class="{ 'sr-tab--on': currentTab === index }"
						@tap="onTabChange(index)"
					>
						<text class="sr-tab-text">{{ tabLabel(index) }}</text>
					</view>
				</view>
			</scroll-view>
		</view>

		<!-- 作品：双列网格 -->
		<scroll-view
			v-if="currentTab === 0"
			scroll-y
			class="sr-scroll"
			:style="{ height: scrollHeight + 'px' }"
			:lower-threshold="120"
			@scrolltolower="loadMore"
		>
			<view class="sr-body" :style="{ paddingBottom: safeBottom + 'px' }">
				<view v-if="activeTab.loading && !activeTab.rows.length" class="sr-state">
					<text class="sr-state-txt">{{ copy.loading }}</text>
				</view>
				<empty
					v-else-if="activeTab.loaded && !activeTab.rows.length"
					src="find_default3x"
					:text="copy.emptyWorks"
				/>
				<view v-else class="sr-works">
					<view
						v-for="(item, index) in activeTab.rows"
						:key="item.id || index"
						class="sr-work-card"
					>
						<view class="sr-work-cover-wrap" @tap="openFind(item)">
							<image
								v-if="coverOf(item)"
								class="sr-work-cover"
								:src="coverOf(item)"
								mode="aspectFill"
							/>
							<view v-else class="sr-work-cover sr-work-cover--ph" />
							<view v-if="isVideoItem(item)" class="sr-work-video-badge">
								<text class="sr-work-video-icon">▶</text>
							</view>
						</view>
						<view class="sr-work-body">
							<view class="sr-work-title" @tap="openFind(item)">
								<text v-if="item.type_text" class="sr-work-tag">{{ item.type_text }}</text>
								<text class="sr-work-txt">{{ formatContent(item.content) }}</text>
							</view>
							<view class="sr-work-ft">
								<text class="sr-work-date">{{ formatDate(item.createtime) }}</text>
								<view class="sr-work-like" @tap.stop="onLike(index)">
									<text
										class="sr-work-like-icon"
										:class="{ 'sr-work-like-icon--on': item.isLike === 1 }"
									>♥</text>
									<text class="sr-work-like-num">{{ item.likes || 0 }}</text>
								</view>
							</view>
						</view>
					</view>
				</view>
				<uni-load-more
					v-if="activeTab.rows.length"
					:status="activeTab.loadStatus"
					:content-text="loadMoreText"
				/>
			</view>
		</scroll-view>

		<!-- 用户 -->
		<scroll-view
			v-else
			scroll-y
			class="sr-scroll"
			:style="{ height: scrollHeight + 'px' }"
			:lower-threshold="120"
			@scrolltolower="loadMore"
		>
			<view class="sr-body" :style="{ paddingBottom: safeBottom + 'px' }">
				<view v-if="activeTab.loading && !activeTab.rows.length" class="sr-state">
					<text class="sr-state-txt">{{ copy.loading }}</text>
				</view>
				<empty
					v-else-if="activeTab.loaded && !activeTab.rows.length"
					src="find_default3x"
					:text="copy.emptyUsers"
				/>
				<view v-else class="sr-users">
					<view
						v-for="(item, index) in activeTab.rows"
						:key="item.user_no || index"
						class="sr-user-card"
						@tap="openUser(item)"
					>
						<image class="sr-user-avatar" :src="userAvatar(item)" mode="aspectFill" />
						<view class="sr-user-main">
							<view class="sr-user-info">
								<view class="sr-user-name-row">
									<text v-if="item.shop" class="sr-user-shop-tag">{{ copy.shopTag }}</text>
									<text class="sr-user-name">{{ userName(item) }}</text>
								</view>
								<view class="sr-user-stats">
									<text class="sr-user-stat">{{ statFans(item) }}</text>
									<text class="sr-user-stat">{{ statPraised(item) }}</text>
								</view>
							</view>
							<button
								class="sr-follow-btn"
								:class="{ 'sr-follow-btn--on': item.isFollow === 1 }"
								@tap.stop="onFollow(index)"
							>
								{{ item.isFollow === 1 ? copy.followed : copy.follow }}
							</button>
						</view>
					</view>
				</view>
				<uni-load-more
					v-if="activeTab.rows.length"
					:status="activeTab.loadStatus"
					:content-text="loadMoreText"
				/>
			</view>
		</scroll-view>
	</view>
</template>

<script>
import { fetchFindSearchPage } from '@/features/search/search-gateway'
import { stripHtml } from '@/features/feed/clip-normalize'
import { toggleClipLike } from '@/features/feed/feed-gateway'
import { toggleProfileFollow } from '@/features/profile/profile-gateway'
import { detailPageUrl, videoDetailUrl } from '@/features/dynamics/post-media'

function createTabState(type) {
	return {
		type,
		rows: [],
		page: 1,
		loadStatus: 'more',
		loading: false,
		loaded: false
	}
}

export default {
	data() {
		return {
			statusBar: 0,
			safeBottom: 0,
			scrollHeight: 600,
			keyword: '',
			currentTab: 0,
			tabs: [
				createTabState('works'),
				createTabState('user')
			]
		}
	},
	computed: {
		copy() {
			const t = this.$t.bind(this)
			return {
				placeholder: t('search.placeholder'),
				tabWorks: t('search.tabWorks'),
				tabUser: t('search.tabUser'),
				loading: t('search.loading'),
				emptyWorks: t('search.emptyWorks'),
				emptyUsers: t('search.emptyUsers'),
				shopTag: t('search.shopTag'),
				follow: t('search.follow'),
				followed: t('search.followed'),
				loadFailed: t('search.loadFailed'),
				actionFailed: t('search.actionFailed'),
				contentUnavailable: t('search.contentUnavailable')
			}
		},
		loadMoreText() {
			const t = this.$t.bind(this)
			return {
				contentdown: t('search.loadMore'),
				contentrefresh: t('search.loading'),
				contentnomore: t('search.noMore')
			}
		},
		activeTab() {
			return this.tabs[this.currentTab] || this.tabs[0]
		},
		headerHeight() {
			return this.statusBar + uni.upx2px(180)
		}
	},
	onLoad(query) {
		this.keyword = query && query.search ? decodeURIComponent(query.search) : ''
		this.initLayout()
		this.loadTab(0, true)
	},
	onPullDownRefresh() {
		this.loadTab(this.currentTab, true).finally(() => {
			try { uni.stopPullDownRefresh() } catch (_) {}
		})
	},
	methods: {
		tabLabel(index) {
			if (index === 0) return this.copy.tabWorks
			if (index === 1) return this.copy.tabUser
			return ''
		},
		statFans(item) {
			return this.$t('search.statFans', { n: item.fans || 0 })
		},
		statPraised(item) {
			return this.$t('search.statPraised', { n: item.praised || 0 })
		},
		initLayout() {
			try {
				const info = uni.getSystemInfoSync()
				this.statusBar = info.statusBarHeight || 0
				this.safeBottom = (info.safeAreaInsets && info.safeAreaInsets.bottom) || 0
				this.scrollHeight = (info.windowHeight || 667) - this.headerHeight
			} catch (_) {}
		},
		goBack() {
			uni.navigateBack({
				fail: () => uni.switchTab({ url: '/pages/index/index' })
			})
		},
		openSearch() {
			const q = this.keyword
				? `?keywords=${encodeURIComponent(this.keyword)}&type=find`
				: '?type=find'
			uni.navigateTo({ url: `/pages/search/index${q}` })
		},
		onTabChange(index) {
			if (this.currentTab === index) return
			this.currentTab = index
			const tab = this.tabs[index]
			if (!tab.loaded) {
				this.loadTab(index, true)
			}
		},
		loadMore() {
			this.loadTab(this.currentTab, false)
		},
		async loadTab(tabIndex, reset) {
			const tab = this.tabs[tabIndex]
			if (!tab) return
			if (tab.loadStatus === 'noMore' && !reset) return
			if (tab.loading) return

			if (reset) {
				tab.page = 1
				tab.rows = []
				tab.loadStatus = 'more'
				tab.loaded = false
			}

			tab.loading = true
			tab.loadStatus = 'loading'

			try {
				const pack = await fetchFindSearchPage(tab.page, {
					search: this.keyword,
					listType: tab.type
				})
				const list = (pack.rows || []).map((row) =>
					Object.assign({}, row, { listPage: pack.currentPage || tab.page })
				)
				tab.rows = reset ? list : tab.rows.concat(list)
				tab.page = pack.currentPage || tab.page

				if ((pack.currentPage || 1) >= (pack.lastPage || 1)) {
					tab.loadStatus = 'noMore'
				} else {
					tab.loadStatus = 'more'
					tab.page = (pack.currentPage || tab.page) + 1
				}
				tab.loaded = true
			} catch (err) {
				tab.loadStatus = 'more'
				if (reset) tab.rows = []
				tab.loaded = true
				this.$appKit && this.$appKit.msg(err.message || this.copy.loadFailed)
			} finally {
				tab.loading = false
			}
		},
		oss(url, w = 400, h = 0) {
			if (this.$appKit && typeof this.$appKit.oss === 'function') {
				return this.$appKit.oss(url, w, h)
			}
			return url || ''
		},
		coverOf(item) {
			const images = Array.isArray(item.images) ? item.images : []
			const cover =
				images[0] ||
				(item.video && item.video.cover_url) ||
				item.cover ||
				''
			return cover ? this.oss(cover, 400, 460) : ''
		},
		formatContent(content) {
			const text = stripHtml(content)
			if (!text) return ' '
			return text.length > 48 ? `${text.slice(0, 48)}…` : text
		},
		formatDate(ts) {
			if (this.$appKit && typeof this.$appKit.timeFormat === 'function') {
				return this.$appKit.timeFormat(ts, 'mm-dd')
			}
			return ''
		},
		userAvatar(item) {
			if (item.shop && item.shop.avatar) return this.oss(item.shop.avatar, 88, 88)
			if (item.user && item.user.avatar) return this.oss(item.user.avatar, 88, 88)
			return ''
		},
		userName(item) {
			if (item.shop && item.shop.shopname) return item.shop.shopname
			if (item.user && item.user.nickname) return item.user.nickname
			return '—'
		},
		isVideoItem(item) {
			if (!item) return false
			if (item.type === 'video') return true
			return !!(item.video && (item.video.url || item.video.cover_url))
		},
		openFind(item) {
			if (!item) return
			if (item.state && item.state !== 'normal') {
				this.$appKit && this.$appKit.msg(this.copy.contentUnavailable)
				return
			}
			if (item.type === 'live' && item.live_id) {
				uni.navigateTo({ url: `/pages/live/watch?id=${item.live_id}` })
				return
			}
			if (this.isVideoItem(item)) {
				uni.navigateTo({
					url: videoDetailUrl(item.id, {
						type: 'work',
						page: item.listPage || item.page || 1,
						search: this.keyword || undefined
					})
				})
				return
			}
			if (item.id) {
				uni.navigateTo({ url: detailPageUrl(item.id) })
			}
		},
		openUser(item) {
			if (!item || !item.user_no) return
			uni.navigateTo({
				url: `/pages/profile/show?id=${encodeURIComponent(String(item.user_no))}`
			})
		},
		async onLike(index) {
			if (!this.$appKit || !this.$appKit.requireLogin()) return
			const tab = this.tabs[0]
			const row = tab.rows[index]
			if (!row || !row.id) return
			try {
				const flag = await toggleClipLike(row.id)
				if (flag === 0 || flag === '0') {
					row.isLike = 0
					row.likes = Math.max(0, Number(row.likes || 0) - 1)
				} else if (flag === 1 || flag === '1') {
					row.isLike = 1
					row.likes = Number(row.likes || 0) + 1
				}
			} catch (err) {
				this.$appKit.msg(err.message || this.copy.actionFailed)
			}
		},
		async onFollow(index) {
			if (!this.$appKit || !this.$appKit.requireLogin()) return
			const tab = this.tabs[1]
			const row = tab.rows[index]
			if (!row || !row.user_no) return
			try {
				const flag = await toggleProfileFollow(row.user_no)
				if (flag === 0 || flag === '0') row.isFollow = 0
				else if (flag === 1 || flag === '1') row.isFollow = 1
			} catch (err) {
				this.$appKit.msg(err.message || this.copy.actionFailed)
			}
		}
	}
}
</script>

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

.sr-hd {
	padding-left: 32rpx;
	padding-right: 32rpx;
	padding-bottom: 8rpx;
}

.sr-hd-row {
	display: flex;
	flex-direction: row;
	align-items: center;
	margin-bottom: 20rpx;
}

.sr-back {
	width: 72rpx;
	height: 72rpx;
	border-radius: 20rpx;
	background-color: #ffffff;
	box-shadow: 0 6rpx 20rpx rgba(74, 140, 255, 0.12);
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	margin-right: 20rpx;
}

.sr-back-icon {
	font-size: 36rpx;
	color: #4a8cff;
	line-height: 1;
}

.sr-search-bar {
	flex: 1;
	min-width: 0;
	height: 72rpx;
	border-radius: 20rpx;
	background-color: #ffffff;
	box-shadow: 0 6rpx 20rpx rgba(74, 140, 255, 0.1);
	display: flex;
	flex-direction: row;
	align-items: center;
	padding: 0 24rpx;
	box-sizing: border-box;
}

.sr-search-icon {
	font-size: 28rpx;
	margin-right: 12rpx;
	opacity: 0.7;
}

.sr-search-text {
	flex: 1;
	font-size: 28rpx;
	color: #1a1d29;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.sr-tabs-scroll {
	white-space: nowrap;
}

.sr-tabs {
	display: inline-flex;
	flex-direction: row;
	padding-bottom: 12rpx;
}

.sr-tab {
	padding: 12rpx 28rpx;
	margin-right: 16rpx;
	border-radius: 999rpx;
	background-color: rgba(255, 255, 255, 0.7);
}

.sr-tab--on {
	background: linear-gradient(135deg, #4a8cff 0%, #6ba0ff 100%);
	box-shadow: 0 6rpx 16rpx rgba(74, 140, 255, 0.25);
}

.sr-tab-text {
	font-size: 28rpx;
	color: #8a8d9e;
	font-weight: 500;
}

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

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

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

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

.sr-works {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: space-between;
}

.sr-work-card {
	width: calc((100% - 16rpx) / 2);
	margin-bottom: 24rpx;
	background-color: #ffffff;
	border-radius: 24rpx;
	overflow: hidden;
	box-shadow: 0 6rpx 24rpx rgba(74, 140, 255, 0.08);
}

.sr-work-cover-wrap {
	position: relative;
	width: 100%;
	height: 460rpx;
	background-color: #eef2f8;
}

.sr-work-video-badge {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	width: 72rpx;
	height: 72rpx;
	border-radius: 36rpx;
	background-color: rgba(0, 0, 0, 0.42);
	display: flex;
	align-items: center;
	justify-content: center;
}

.sr-work-video-icon {
	color: #ffffff;
	font-size: 32rpx;
	margin-left: 4rpx;
}

.sr-work-cover {
	width: 100%;
	height: 100%;
	display: block;
}

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

.sr-work-body {
	padding: 16rpx 18rpx 18rpx;
}

.sr-work-title {
	margin-bottom: 12rpx;
}

.sr-work-tag {
	display: inline-block;
	font-size: 20rpx;
	color: #4a8cff;
	background-color: rgba(74, 140, 255, 0.12);
	padding: 2rpx 10rpx;
	border-radius: 8rpx;
	margin-right: 8rpx;
	vertical-align: middle;
}

.sr-work-txt {
	font-size: 26rpx;
	font-weight: 600;
	color: #1a1d29;
	line-height: 36rpx;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

.sr-work-ft {
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
}

.sr-work-date {
	font-size: 22rpx;
	color: #8a8d9e;
}

.sr-work-like {
	display: flex;
	flex-direction: row;
	align-items: center;
}

.sr-work-like-icon {
	font-size: 28rpx;
	color: #b0b4c0;
	margin-right: 6rpx;
}

.sr-work-like-icon--on {
	color: #ff4d4f;
}

.sr-work-like-num {
	font-size: 24rpx;
	color: #5c6070;
}

.sr-users {
	display: flex;
	flex-direction: column;
}

.sr-user-card {
	display: flex;
	flex-direction: row;
	align-items: center;
	padding: 24rpx;
	margin-bottom: 20rpx;
	background-color: #ffffff;
	border-radius: 24rpx;
	box-shadow: 0 6rpx 24rpx rgba(74, 140, 255, 0.08);
}

.sr-user-avatar {
	width: 100rpx;
	height: 100rpx;
	border-radius: 50rpx;
	flex-shrink: 0;
	background-color: #eef2f8;
}

.sr-user-main {
	flex: 1;
	min-width: 0;
	margin-left: 20rpx;
	display: flex;
	flex-direction: row;
	align-items: center;
}

.sr-user-info {
	flex: 1;
	min-width: 0;
	margin-right: 16rpx;
}

.sr-user-name-row {
	display: flex;
	flex-direction: row;
	align-items: center;
	margin-bottom: 8rpx;
}

.sr-user-shop-tag {
	flex-shrink: 0;
	margin-right: 8rpx;
	padding: 2rpx 10rpx;
	border-radius: 8rpx;
	background: linear-gradient(135deg, #4a8cff 0%, #6ec8ff 100%);
	font-size: 20rpx;
	color: #ffffff;
}

.sr-user-name {
	font-size: 30rpx;
	font-weight: 600;
	color: #1a1d26;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.sr-user-stats {
	display: flex;
	flex-direction: row;
}

.sr-user-stat {
	font-size: 24rpx;
	color: #8a8d9e;
	margin-right: 20rpx;
}

.sr-follow-btn {
	flex-shrink: 0;
	margin: 0;
	padding: 0 28rpx;
	height: 56rpx;
	line-height: 56rpx;
	font-size: 24rpx;
	color: #ffffff;
	background: linear-gradient(135deg, #4a8cff 0%, #6ec8ff 100%);
	border-radius: 999rpx;
	border: none;
}

.sr-follow-btn--on {
	color: #8a8d9e;
	background: #f4f6fb;
	border: 1rpx solid #e8edf5;
}

.sr-follow-btn::after {
	border: none;
}
</style>
