<!-- 机构端 - 服务评价页面 -->
<template>
	<view class="reviews-page">
		<!-- #ifdef MP-WEIXIN -->
		<view style="padding-top: var(--status-bar-height); background-color: #ffffff; display: flex; flex-direction: row; align-items: flex-end; border-bottom: 1rpx solid #eeeeee; box-sizing: border-box; height: calc(88rpx + var(--status-bar-height));">
			<view style="display: flex; flex-direction: row; align-items: center; padding: 0 30rpx; height: 88rpx;" @click="uni.navigateBack()">
				<text style="font-size: 44rpx; color: #333333; line-height: 1; margin-right: 6rpx;">‹</text>
				<text style="font-size: 28rpx; color: #333333;">返回</text>
			</view>
		</view>
		<!-- #endif -->
		<view class="filter-tabs">
			<view class="filter-tab" :class="{ active: currentFilter === 'all' }" @click="switchFilter('all')">全部</view>
			<view class="filter-tab" :class="{ active: currentFilter === 'pending' }" @click="switchFilter('pending')">待回复</view>
			<view class="filter-tab" :class="{ active: currentFilter === 'replied' }" @click="switchFilter('replied')">已回复</view>
		</view>
		
		<scroll-view class="reviews-list" scroll-y :refresher-enabled="true" :refresher-triggered="refreshing" @refresherrefresh="onRefresh" @scrolltolower="loadMore">
			<view v-if="loading && reviews.length === 0" class="loading-container"><text class="loading-text">加载中...</text></view>
			<view v-else-if="reviews.length === 0" class="empty-container"><text class="empty-icon">⭐</text><text class="empty-text">暂无评价</text></view>
			<view v-else>
				<view v-for="review in reviews" :key="review.id" class="review-card">
					<view class="review-header">
						<image :src="review.user_avatar || '/static/images/default-avatar.png'" class="user-avatar" mode="aspectFill"/>
						<view class="user-info">
							<text class="user-name">{{ review.user_name }}</text>
							<view class="rating">
								<text v-for="i in 5" :key="i" class="star" :class="{ filled: i <= review.rating }">★</text>
							</view>
						</view>
						<text class="review-time">{{ formatTime(review.created_at) }}</text>
					</view>
					<view class="review-product">
						<text class="product-name">服务项目: {{ review.product_name }}</text>
					</view>
					<view class="review-content">{{ review.content }}</view>
					<view v-if="review.images" class="review-images">
						<image v-for="(img, idx) in parseImages(review.images)" :key="idx" :src="img" class="review-image" mode="aspectFill" @click="previewImage(review.images, idx)"/>
					</view>
					<view v-if="review.reply" class="review-reply">
						<text class="reply-label">机构回复:</text>
						<text class="reply-content">{{ review.reply }}</text>
					</view>
					<view v-else class="review-actions">
						<view class="action-btn" @click="replyReview(review)">回复用户评价</view>
					</view>
				</view>
			</view>
			<view v-if="loadingMore" class="load-more"><text class="load-more-text">加载中...</text></view>
		</scroll-view>
		
		<view v-if="showReplyModal" class="modal-mask" @click="closeReplyModal">
			<view class="modal-content" @click.stop>
				<view class="modal-header"><text class="modal-title">回复评价</text><text class="modal-close" @click="closeReplyModal">×</text></view>
				<view class="modal-body">
					<textarea class="reply-input" v-model="replyContent" placeholder="请输入回复内容" maxlength="200"/>
				</view>
				<view class="modal-footer">
					<view class="modal-btn cancel" @click="closeReplyModal">取消</view>
					<view class="modal-btn confirm" @click="submitReply">提交</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script lang="uts">
	import supa from '@/components/supadb/aksupainstance.uts'
	import { requireMerchantAuth } from '@/utils/merchantAuth.uts'
	import { USE_MOCK, MOCK_MERCHANT_ID, getMockReviews } from '@/pages/mall/merchant/mock/merchant-mock-data.uts'
	
	type ReviewType = {
		id: string
		product_id: string
		product_name: string
		user_id: string
		user_name: string
		user_avatar: string
		rating: number
		content: string
		images: string
		reply: string
		created_at: string
	}
	
	export default {
		data() {
			return {
				currentFilter: 'all',
				reviews: [] as ReviewType[],
				loading: false,
				loadingMore: false,
				refreshing: false,
				page: 1,
				limit: 20,
				hasMore: true,
				merchantId: '',
				showReplyModal: false,
				currentReview: null as ReviewType | null,
				replyContent: ''
			}
		},
		
		onLoad() {
			if (USE_MOCK) {
				this.merchantId = MOCK_MERCHANT_ID
				this.loadReviews()
				return
			}
			this.ensureMerchantAuth().then((passed: boolean) => {
				if (passed) {
					this.loadReviews()
				}
			})
		},
		
		onShow() {
			this.handlePageShow()
		},
		
		methods: {
			async ensureMerchantAuth(): Promise<boolean> {
				if (USE_MOCK) return true
				const result = await requireMerchantAuth({ redirectOnFail: true, toastOnFail: true })
				if (!result.ok) {
					this.merchantId = ''
					return false
				}
				this.merchantId = result.userInfo != null && result.userInfo.id != null ? result.userInfo.id : ''
				return this.merchantId !== ''
			},

			async handlePageShow() {
				const passed = await this.ensureMerchantAuth()
				if (!passed) return
				this.loadReviews()
			},

			async loadReviews() {
				if (!this.merchantId || this.merchantId.split('-').length !== 5) return
				if (this.loading) return
				this.loading = true
				if (USE_MOCK) {
					this.reviews = getMockReviews(this.currentFilter) as ReviewType[]
					this.hasMore = false
					this.loading = false
					this.refreshing = false
					return
				}
				try {
					let query = supa
						.from('ml_product_reviews')
						.select('*')
						.eq('merchant_id', this.merchantId)
						.order('created_at', { ascending: false })
						.page(this.page)
						.limit(this.limit)
					const response = await query.execute()
					
					if (response.error != null || !response.data) {
						this.reviews = []
						return
					}
					
					const rawData = response.data as any[]
					const reviewsData: ReviewType[] = []
					for (let i = 0; i < rawData.length; i++) {
						const item = rawData[i] as UTSJSONObject
						reviewsData.push({
							id: item.getString('id') || '',
							product_id: item.getString('product_id') || '',
							product_name: item.getString('product_name') || '',
							user_id: item.getString('user_id') || '',
							user_name: item.getString('user_name') || '匿名用户',
							user_avatar: item.getString('user_avatar') || '',
							rating: item.getNumber('rating') || 5,
							content: item.getString('content') || '',
							images: item.getString('images') || '',
							reply: item.getString('reply') || '',
							created_at: item.getString('created_at') || ''
						} as ReviewType)
					}
					
					if (this.page === 1) {
						this.reviews = reviewsData
					} else {
						this.reviews = [...this.reviews, ...reviewsData]
					}
					
					this.hasMore = rawData.length >= this.limit
				} catch (e) {
					console.error('加载评价失败:', e)
				} finally {
					this.loading = false
					this.refreshing = false
				}
			},
			
			switchFilter(filter: string) {
				this.currentFilter = filter
				this.page = 1
				this.hasMore = true
				this.loadReviews()
			},
			
			onRefresh() {
				this.refreshing = true
				this.page = 1
				this.loadReviews()
			},
			
			loadMore() {
				if (!this.loadingMore && this.hasMore) {
					this.loadingMore = true
					this.page++
					const resetMore = () => { this.loadingMore = false }
					this.loadReviews().then(resetMore).catch(resetMore)
				}
			},
			
			replyReview(review: ReviewType) {
				this.currentReview = review
				this.replyContent = ''
				this.showReplyModal = true
			},
			
			closeReplyModal() {
				this.showReplyModal = false
				this.currentReview = null
				this.replyContent = ''
			},
			
			async submitReply() {
				if (!this.replyContent.trim()) {
					uni.showToast({ title: '请输入回复内容', icon: 'none' })
					return
				}
				
				try {
					const response = await supa
						.from('ml_product_reviews')
						.update({
							reply: this.replyContent,
							reply_at: new Date().toISOString()
						})
						.eq('id', this.currentReview!.id)
						.execute()
					
					if (response.error != null) {
						uni.showToast({ title: '回复失败', icon: 'none' })
						return
					}
					
					uni.showToast({ title: '回复成功', icon: 'success' })
					this.closeReplyModal()
					this.loadReviews()
				} catch (e) {
					uni.showToast({ title: '回复失败', icon: 'none' })
				}
			},
			
			parseImages(imagesStr: string): string[] {
				if (!imagesStr) return []
				try {
					return JSON.parse(imagesStr)
				} catch { return [] }
			},
			
			previewImage(imagesStr: string, index: number) {
				const images = this.parseImages(imagesStr)
				uni.previewImage({ urls: images, current: index })
			},
			
			formatTime(timeStr: string): string {
				if (!timeStr) return ''
				const date = new Date(timeStr)
				return `${date.getMonth() + 1}-${date.getDate()}`
			}
		}
	}
</script>

<style>
	.reviews-page {
		display: flex;
		flex-direction: column;
		background-color: #f5f5f5;
		min-height: 100vh;
		box-sizing: border-box;
	}

	.filter-tabs {
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		background-color: #ffffff;
		padding: 0 20rpx;
		margin-bottom: 20rpx;
		border-bottom: 1rpx solid #f2f2f2;
		box-sizing: border-box;
	}

	.filter-tab {
		flex: 1;
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: center;
		height: 88rpx;
		font-size: 26rpx;
		color: #666666;
		position: relative;
		box-sizing: border-box;
	}

	.filter-tab.active {
		color: #09C39D;
		font-weight: bold;
	}

	.filter-tab.active::after {
		content: '';
		position: absolute;
		bottom: 0;
		left: 50%;
		transform: translateX(-50%);
		width: 44rpx;
		height: 4rpx;
		background-color: #09C39D;
		border-radius: 2rpx;
	}

	.reviews-list {
		flex: 1;
		height: calc(100vh - 176rpx);
		padding: 0 20rpx 20rpx;
		box-sizing: border-box;
	}

	.loading-container,
	.empty-container {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		padding: 120rpx 0;
		box-sizing: border-box;
	}

	.empty-icon {
		font-size: 100rpx;
		line-height: 1;
		margin-bottom: 20rpx;
	}

	.empty-text,
	.loading-text {
		font-size: 28rpx;
		color: #999999;
		line-height: 1.4;
	}

	.review-card {
		background-color: #ffffff;
		border-radius: 16rpx;
		margin-bottom: 20rpx;
		padding: 24rpx;
		box-sizing: border-box;
	}

	.review-header {
		display: flex;
		flex-direction: row;
		align-items: center;
		margin-bottom: 20rpx;
		box-sizing: border-box;
	}

	.user-avatar {
		width: 72rpx;
		height: 72rpx;
		border-radius: 36rpx;
		margin-right: 16rpx;
		background-color: #f5f5f5;
		flex-shrink: 0;
	}

	.user-info {
		flex: 1;
		display: flex;
		flex-direction: column;
		justify-content: center;
		box-sizing: border-box;
	}

	.user-name {
		font-size: 26rpx;
		color: #333333;
		font-weight: 500;
		line-height: 1.4;
		margin-bottom: 8rpx;
	}

	.rating {
		display: flex;
		flex-direction: row;
		align-items: center;
		flex-wrap: nowrap;
	}

	.star {
		font-size: 22rpx;
		line-height: 1;
		color: #dddddd;
		margin-right: 4rpx;
	}

	.star.filled {
		color: #ffb800;
	}

	.review-time {
		margin-left: 16rpx;
		font-size: 22rpx;
		color: #999999;
		line-height: 1.4;
		text-align: right;
		flex-shrink: 0;
	}

	.review-product {
		margin-bottom: 12rpx;
	}

	.product-name {
		font-size: 24rpx;
		color: #666666;
		line-height: 1.4;
	}

	.review-content {
		font-size: 26rpx;
		color: #333333;
		line-height: 1.6;
		margin-bottom: 16rpx;
	}

	.review-images {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		margin-bottom: 16rpx;
	}

	.review-image {
		width: 120rpx;
		height: 120rpx;
		border-radius: 8rpx;
		margin-right: 12rpx;
		margin-bottom: 12rpx;
		background-color: #f5f5f5;
	}

	.review-reply {
		display: flex;
		flex-direction: column;
		background-color: #f7f8fa;
		padding: 18rpx 20rpx;
		border-radius: 10rpx;
		margin-top: 16rpx;
		box-sizing: border-box;
	}

	.reply-label {
		font-size: 24rpx;
		color: #09C39D;
		font-weight: 500;
		line-height: 1.4;
		margin-bottom: 8rpx;
	}

	.reply-content {
		font-size: 24rpx;
		color: #666666;
		line-height: 1.6;
	}

	.review-actions {
		display: flex;
		flex-direction: row;
		justify-content: flex-end;
		align-items: center;
		margin-top: 16rpx;
	}

	.action-btn {
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: center;
		padding: 12rpx 24rpx;
		font-size: 24rpx;
		line-height: 1.4;
		background-color: #e8f0fe;
		color: #09C39D;
		border-radius: 24rpx;
		box-sizing: border-box;
	}

	.load-more {
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: center;
		padding: 30rpx 0;
	}

	.load-more-text {
		font-size: 24rpx;
		color: #999999;
		line-height: 1.4;
	}

	.modal-mask {
		position: fixed;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		background-color: rgba(0, 0, 0, 0.5);
		display: flex;
		flex-direction: row;
		align-items: flex-end;
		justify-content: center;
		z-index: 1000;
	}

	.modal-content {
		width: 100%;
		background-color: #ffffff;
		border-radius: 24rpx 24rpx 0 0;
		padding-bottom: env(safe-area-inset-bottom);
		box-sizing: border-box;
	}

	.modal-header {
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		padding: 30rpx;
		border-bottom: 1rpx solid #f2f2f2;
		box-sizing: border-box;
	}

	.modal-title {
		font-size: 32rpx;
		font-weight: bold;
		color: #333333;
		line-height: 1.4;
	}

	.modal-close {
		font-size: 44rpx;
		color: #999999;
		line-height: 1;
	}

	.modal-body {
		padding: 30rpx;
		box-sizing: border-box;
	}

	.reply-input {
		width: 100%;
		height: 220rpx;
		border: 1rpx solid #e5e5e5;
		border-radius: 12rpx;
		padding: 20rpx;
		font-size: 28rpx;
		line-height: 1.6;
		box-sizing: border-box;
		background-color: #ffffff;
	}

	.modal-footer {
		display: flex;
		flex-direction: row;
		align-items: center;
		border-top: 1rpx solid #f2f2f2;
	}

	.modal-btn {
		flex: 1;
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: center;
		height: 88rpx;
		font-size: 28rpx;
		box-sizing: border-box;
	}

	.modal-btn.cancel {
		color: #666666;
		border-right: 1rpx solid #f2f2f2;
	}

	.modal-btn.confirm {
		color: #09C39D;
		font-weight: bold;
	}
</style>