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

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

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

				<view v-else class="rel-list">
					<view
						v-for="(item, index) in rows"
						:key="rowKey(item, index)"
						class="rel-card"
						@tap="openUser(item)"
					>
						<image
							class="rel-avatar"
							:src="avatarUrl(item)"
							mode="aspectFill"
						/>
						<view class="rel-main">
							<view class="rel-info">
								<view class="rel-name-row">
									<text v-if="item.shop" class="rel-tag">{{ labels.shopTag }}</text>
									<text class="rel-name">{{ displayName(item) }}</text>
								</view>
								<text class="rel-bio">{{ displayBio(item) }}</text>
							</view>
							<button
								class="rel-follow-btn"
								:class="{ 'rel-follow-btn--on': item.isFollow === 1 }"
								:disabled="followBusyIndex === index"
								@tap.stop="toggleFollow(index)"
							>
								{{ item.isFollow === 1 ? labels.followed : labels.follow }}
							</button>
						</view>
					</view>
				</view>

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

<script>
import { fetchRelationPage, toggleProfileFollow } from '@/features/profile/profile-gateway'
import { stripRichText } from '@/features/profile/catalog-normalize'

export default {
	name: 'ProfileRelationList',
	props: {
		userNo: {
			type: [String, Number],
			default: ''
		},
		listType: {
			type: String,
			required: true
		},
		title: {
			type: String,
			default: ''
		},
		emptyText: {
			type: String,
			default: ''
		},
		followLabel: {
			type: String,
			default: ''
		},
		unfollowLabel: {
			type: String,
			default: ''
		},
		defaultBio: {
			type: String,
			default: ''
		},
		loadingText: { type: String, default: '' },
		noMoreText: { type: String, default: '' },
		loadMoreHint: { type: String, default: '' },
		loadFailedText: { type: String, default: '' },
		actionFailedText: { type: String, default: '' },
		shopTag: { type: String, default: '' }
	},
	data() {
		return {
			statusBar: 0,
			scrollHeight: 600,
			safeBottom: 0,
			rows: [],
			page: 1,
			lastPage: 1,
			loading: false,
			loaded: false,
			loadStatus: 'more',
			followBusyIndex: -1
		}
	},
	computed: {
		labels() {
			const t = this.$t.bind(this)
			return {
				loading: this.loadingText || t('relation.loading'),
				noMore: this.noMoreText || t('relation.noMore'),
				loadMore: this.loadMoreHint || t('relation.loadMore'),
				empty: this.emptyText || t('relation.emptyData'),
				follow: this.followLabel || t('mine.follow'),
				followed: this.unfollowLabel || t('mine.followed'),
				defaultBio: this.defaultBio || t('findUser.defaultBio'),
				shopTag: this.shopTag || t('relation.shopTag'),
				loadFailed: this.loadFailedText || t('relation.loadFailed'),
				actionFailed: this.actionFailedText || t('relation.actionFailed')
			}
		},
		loadMoreContent() {
			return {
				contentdown: this.labels.loadMore,
				contentrefresh: this.labels.loading,
				contentnomore: this.labels.noMore
			}
		}
	},
	watch: {
		userNo: {
			immediate: true,
			handler(val) {
				if (val) 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 (_) {}
		},
		rowKey(item, index) {
			return item.id || item.user_no || `row-${index}`
		},
		avatarUrl(item) {
			const path = item.shop
				? item.shop.avatar
				: (item.user && item.user.avatar) || ''
			return path ? this.$appKit.oss(path, 88, 88, 2, 'avatar') : ''
		},
		displayName(item) {
			if (item.shop && item.shop.shopname) return item.shop.shopname
			return (item.user && item.user.nickname) || '—'
		},
		displayBio(item) {
			const raw = item.shop
				? item.shop.bio
				: (item.user && item.user.bio) || ''
			const text = stripRichText(raw)
			return text || this.labels.defaultBio
		},
		goBack() {
			uni.navigateBack({
				fail: () => uni.switchTab({ url: '/pages/mine/index' })
			})
		},
		openUser(item) {
			if (!item || !item.user_no) return
			uni.navigateTo({
				url: `/pages/profile/show?id=${encodeURIComponent(String(item.user_no))}`
			})
		},
		async reload() {
			if (!this.userNo) return
			this.page = 1
			this.lastPage = 1
			this.loadStatus = 'more'
			this.loaded = false
			this.rows = []
			await this.loadPage(true)
		},
		onScrollToLower() {
			if (this.loadStatus === 'loading' || this.loadStatus === 'noMore') return
			this.loadPage(false)
		},
		async loadPage(reset) {
			if (!this.userNo || this.loading) return
			if (!reset && this.page >= this.lastPage) {
				this.loadStatus = 'noMore'
				return
			}
			const page = reset ? 1 : this.page + 1
			this.loading = true
			this.loadStatus = 'loading'
			try {
				const pack = await fetchRelationPage({
					userNo: this.userNo,
					listType: this.listType,
					page
				})
				this.page = pack.currentPage
				this.lastPage = pack.lastPage
				if (reset) {
					this.rows = pack.rows
				} else {
					this.rows = this.rows.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.rows = []
				this.$appKit && this.$appKit.msg(err.message || this.labels.loadFailed)
				this.loaded = true
			} finally {
				this.loading = false
			}
		},
		async toggleFollow(index) {
			if (!this.$appKit || !this.$appKit.requireLogin()) return
			const row = this.rows[index]
			if (!row || !row.user_no) return
			if (this.followBusyIndex === index) return
			this.followBusyIndex = index
			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.labels.actionFailed)
			} finally {
				this.followBusyIndex = -1
			}
		}
	},
	mounted() {
		this.initLayout()
	}
}
</script>

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

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

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

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

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

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

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

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

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

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

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

.rel-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.06);
	box-sizing: border-box;
}

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

.rel-main {
	flex: 1;
	min-width: 0;
	margin-left: 20rpx;
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
}

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

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

.rel-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;
}

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

.rel-bio {
	display: block;
	font-size: 24rpx;
	color: #8a8d9e;
	line-height: 1.4;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.rel-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;
}

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

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