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

		<scroll-view
			scroll-y
			class="acct-pwd-scroll"
			:style="{ height: scrollHeight + 'px' }"
		>
			<view class="acct-pwd-body" :style="{ paddingBottom: footerPad + 'px' }">
				<view class="acct-pwd-hero">
					<view class="acct-pwd-hero-icon-wrap">
						<text class="acct-pwd-hero-icon">🚩</text>
					</view>
					<text class="acct-pwd-hero-title">{{ copy.heroTitle }}</text>
					<text class="acct-pwd-hero-desc">{{ heroDesc }}</text>
				</view>

				<text class="cp-section">{{ copy.sectionReason }}</text>
				<view class="acct-pwd-card cp-picker-card">
					<picker
						mode="selector"
						:range="reasonLabels"
						:value="reasonIndex >= 0 ? reasonIndex : 0"
						:disabled="!reasonLabels.length"
						@change="onReasonPick"
					>
						<view class="cp-picker-row">
							<text
								class="cp-picker-value"
								:class="{ 'cp-picker-value--placeholder': reasonIndex < 0 }"
							>{{ reasonLabel }}</text>
							<text class="cp-picker-chevron">›</text>
						</view>
					</picker>
				</view>

				<text class="cp-section">{{ copy.sectionScreenshots }}</text>
				<view class="acct-pwd-card">
					<view class="cp-img-head">
						<text class="cp-img-head-label">{{ copy.previewImages }}</text>
						<text class="cp-img-head-count">{{ form.images.length }}/8</text>
					</view>
					<view class="cp-img-grid">
						<view
							v-for="(image, index) in form.images"
							:key="index"
							class="cp-img-cell"
						>
							<image
								class="cp-img-thumb"
								:src="thumb(image)"
								mode="aspectFill"
								@tap="previewImages(index)"
							/>
							<view class="cp-img-remove" @tap.stop="removeImage(index)">
								<text class="cp-img-remove-icon">×</text>
							</view>
						</view>
						<view
							v-if="form.images.length < 8"
							class="cp-img-cell cp-img-cell--add"
							@tap="pickImages"
						>
							<text class="cp-img-add-icon">+</text>
							<text class="cp-img-add-txt">{{ copy.addImage }}</text>
						</view>
					</view>
				</view>

				<text class="cp-section">{{ copy.sectionDetails }}</text>
				<view class="acct-pwd-card">
					<textarea
						v-model="form.content"
						class="cp-textarea"
						maxlength="-1"
						:placeholder="copy.placeholder"
						placeholder-class="cp-textarea-placeholder"
					/>
				</view>
			</view>
		</scroll-view>

		<view class="cp-footer" :style="{ paddingBottom: safeBottom + 'px' }">
			<button
				class="acct-pwd-submit"
				:disabled="submitting"
				:loading="submitting"
				:class="{ 'acct-pwd-submit--busy': submitting }"
				@tap="submit"
			>
				<text class="acct-pwd-submit__text">{{ submitting ? copy.submitting : copy.submit }}</text>
			</button>
		</view>
	</view>
</template>

<script>
import {
	buildComplaintDraft,
	fetchComplaintReasons,
	submitComplaint,
	uploadComplaintImage
} from '@/features/account/complaint-gateway'

export default {
	data() {
		return {
			statusBar: 0,
			scrollHeight: 600,
			safeBottom: 0,
			footerPad: 120,
			submitting: false,
			uploading: false,
			typeName: '',
			targetId: 0,
			reasonIndex: -1,
			reasonOptions: [],
			form: {
				type: 0,
				complaint_user_id: 0,
				complaint_shop_id: 0,
				complaint_goods_id: 0,
				images: [],
				content: '',
				reason: -1
			}
		}
	},
	computed: {
		copy() {
			const t = this.$t.bind(this)
			return {
				pageTitle: t('user.panelReport'),
				heroTitle: t('complaint.heroTitle'),
				sectionReason: t('complaint.reason'),
				sectionScreenshots: t('complaint.screenshots'),
				sectionDetails: t('complaint.details'),
				previewImages: t('complaint.preview-images'),
				addImage: t('complaint.add-image'),
				placeholder: t('complaint.placeholder'),
				submit: t('complaint.submit'),
				submitting: t('complaint.submitting'),
				selectReason: t('complaint.select-reason'),
				reasonRequired: t('complaint.reason-required'),
				contentRequired: t('complaint.content-required'),
				submitOk: t('complaint.submit-ok'),
				network: t('user.realnameNetworkError')
			}
		},
		heroDesc() {
			if (this.targetId) {
				return this.$t('complaint.targetHint', {
					typeName: this.typeName,
					id: this.targetId
				})
			}
			return this.$t('complaint.generalHint')
		},
		reasonLabels() {
			return this.reasonOptions.map((item) => item.title)
		},
		reasonLabel() {
			if (this.reasonIndex < 0 || !this.reasonOptions[this.reasonIndex]) {
				return this.copy.selectReason
			}
			return this.reasonOptions[this.reasonIndex].title
		}
	},
	onLoad(option) {
		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 - uni.upx2px(120)
		this.footerPad = uni.upx2px(120) + this.safeBottom

		const built = buildComplaintDraft(option || {}, this.$t.bind(this))
		this.form = { ...built.draft }
		this.typeName = built.typeName
		this.targetId = built.targetId

		this.loadReasons()
	},
	methods: {
		goBack() {
			if (getCurrentPages().length > 1) {
				uni.navigateBack({ delta: 1 })
			} else {
				uni.switchTab({
					url: '/pages/mine/index',
					fail: () => uni.reLaunch({ url: '/pages/mine/index' })
				})
			}
		},
		thumb(url) {
			return this.$appKit && this.$appKit.oss ? this.$appKit.oss(url, 200, 200) : url
		},
		async loadReasons() {
			try {
				const list = await fetchComplaintReasons()
				if (list.length) {
					this.reasonOptions = list
				}
			} catch (_) {}
		},
		onReasonPick(e) {
			const idx = Number(e.detail.value)
			if (Number.isNaN(idx) || idx < 0) {
				this.reasonIndex = -1
				this.form.reason = -1
				return
			}
			this.reasonIndex = idx
			const row = this.reasonOptions[idx]
			this.form.reason = row ? row.code_num : idx
		},
		pickImages() {
			if (this.uploading) return
			const remain = 8 - this.form.images.length
			if (remain <= 0) return
			uni.chooseImage({
				sourceType: ['camera', 'album'],
				sizeType: ['compressed'],
				count: remain,
				success: (res) => {
					this.uploadChosen(res.tempFilePaths || [])
				}
			})
		},
		async uploadChosen(paths) {
			if (!paths.length) return
			this.uploading = true
			uni.showLoading({ mask: true, title: this.$t('complaint.uploading') })
			try {
				for (const path of paths) {
					const url = await uploadComplaintImage(path)
					if (url) this.form.images.push(url)
				}
			} catch (err) {
				this.$appKit.msg((err && err.message) || this.copy.network)
			} finally {
				this.uploading = false
				uni.hideLoading()
			}
		},
		removeImage(index) {
			this.form.images.splice(index, 1)
		},
		previewImages(index) {
			const urls = this.form.images.map((item) =>
				this.$appKit.oss ? this.$appKit.oss(item, 500) : item
			)
			uni.previewImage({
				urls,
				current: urls[index],
				indicator: 'number'
			})
		},
		async submit() {
			if (this.submitting) return
			if (this.form.reason === -1) {
				this.$appKit.msg(this.copy.reasonRequired)
				return
			}
			if (!String(this.form.content || '').trim()) {
				this.$appKit.msg(this.copy.contentRequired)
				return
			}
			this.submitting = true
			uni.showLoading({ mask: true })
			try {
				await submitComplaint({ ...this.form })
				this.$appKit.msg(this.copy.submitOk)
				setTimeout(() => {
					uni.navigateTo({
						url: '/pages/account/complaint-lists',
						fail: () => this.goBack()
					})
				}, 400)
			} catch (err) {
				this.$appKit.msg((err && err.message) || this.copy.network)
			} finally {
				this.submitting = false
				uni.hideLoading()
			}
		}
	}
}
</script>

<style scoped>
@import './account-flow.css';

.cp-section {
	display: block;
	padding: 0 8rpx 16rpx;
	font-size: 26rpx;
	color: #8a8d9e;
}

.cp-picker-card {
	padding: 0 28rpx;
}

.cp-picker-row {
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	min-height: 96rpx;
}

.cp-picker-value {
	flex: 1;
	font-size: 30rpx;
	color: #1a1d26;
}

.cp-picker-value--placeholder {
	color: #b8bcc8;
}

.cp-picker-chevron {
	font-size: 36rpx;
	color: #c5cad6;
	line-height: 1;
}

.cp-img-head {
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 20rpx;
}

.cp-img-head-label {
	font-size: 28rpx;
	color: #1a1d26;
	font-weight: 500;
}

.cp-img-head-count {
	font-size: 24rpx;
	color: #8a8d9e;
}

.cp-img-grid {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	margin: -8rpx;
}

.cp-img-cell {
	position: relative;
	width: calc(25% - 16rpx);
	height: 152rpx;
	margin: 8rpx;
	border-radius: 16rpx;
	overflow: hidden;
	background-color: #f0f3f8;
}

.cp-img-cell--add {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	border: 2rpx dashed #d5dae6;
	background-color: #f7f9fc;
}

.cp-img-thumb {
	width: 100%;
	height: 100%;
}

.cp-img-remove {
	position: absolute;
	top: 0;
	right: 0;
	width: 40rpx;
	height: 40rpx;
	background: rgba(239, 68, 68, 0.92);
	display: flex;
	align-items: center;
	justify-content: center;
	border-bottom-left-radius: 12rpx;
}

.cp-img-remove-icon {
	color: #ffffff;
	font-size: 28rpx;
	line-height: 1;
}

.cp-img-add-icon {
	font-size: 44rpx;
	color: #4a8cff;
	line-height: 1;
}

.cp-img-add-txt {
	margin-top: 6rpx;
	font-size: 20rpx;
	color: #8a8d9e;
}

.cp-textarea {
	width: 100%;
	min-height: 220rpx;
	font-size: 28rpx;
	color: #1a1d26;
	line-height: 1.5;
}

.cp-textarea-placeholder {
	color: #b8bcc8;
}

.cp-footer {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 16rpx 28rpx 0;
	background: linear-gradient(180deg, rgba(244, 246, 251, 0) 0%, #f4f6fb 28%);
	box-sizing: border-box;
}
</style>
