<template>
	<view class="page">
		<!-- 背景图片 -->
		<view class="hear-bg" :style="headerGradientOuter()">
			<view class="hear-bg-mask" :style="headerGradientMask()"></view>
		</view>
		<!-- #ifndef H5 -->
		<!-- APP端导航栏（流式布局，不使用 fixed 定位） -->
		<view class="nav-bar" :style="{ paddingTop: pageStatusBarHeight + 'px' }">
			<view class="nav-content">
				<view class="nav-back" @click="handleBack">
					<uni-icons type="left" size="22" color="#333333"></uni-icons>
				</view>
				<text class="nav-title">导游认证</text>
				<view class="nav-placeholder"></view>
			</view>
		</view>
		<!-- #endif -->
		<view class="guide-page">
			<!-- 已通过认证页面 -->
			<view v-if="isApproved" class="success-page">
				<view class="success-content">
					<view class="success-icon-wrapper">
						<uni-icons type="checkmarkempty" size="64" color="#ffffff"></uni-icons>
					</view>
					<text class="success-title">审核已通过！</text>
					<view class="auth-result">
						<view class="form-item">
							<view class="form-row">
								<text class="form-label">导游证号码</text>
								<view class="form-value">
									<text class="value-text value-filled">{{ (maskedGuideNum != null && maskedGuideNum != '') ? maskedGuideNum : '--' }}</text>
								</view>
							</view>
						</view>
						<view class="form-divider"></view>
						<view class="form-item">
							<view class="form-row">
								<text class="form-label">失效日期</text>
								<view class="form-value">
									<text class="value-text value-filled">{{ authExpiryDisplay }}</text>
								</view>
							</view>
						</view>
					</view>
				</view>
				<view v-if="authGuideImage != null && authGuideImage != ''" class="success-image-wrapper">
					<image :src="authGuideImage" mode="aspectFill" class="success-image" />
					<text class="image-label">已认证导游证</text>
				</view>
			</view>
			
			<!-- 审核中页面 -->
			<view v-else-if="isPending" class="pending-page">
				<view class="pending-content">
					<view class="pending-icon-wrapper">
						<uni-icons type="spinner-cycle" size="48" color="#FF8C00"></uni-icons>
					</view>
					<text class="pending-title">导游认证审核中</text>
					<text class="pending-desc">我们将在1-2个工作日内完成审核，请耐心等待。审核结果将通过消息通知您。</text>
					
					<view class="auth-result">
						<view class="form-item">
							<view class="form-row">
								<text class="form-label">导游证号码</text>
								<view class="form-value">
									<text class="value-text value-filled">{{ (maskedGuideNum != null && maskedGuideNum != '') ? maskedGuideNum : '--' }}</text>
								</view>
							</view>
						</view>
						<view class="form-divider"></view>
						<view class="form-item">
							<view class="form-row">
								<text class="form-label">失效日期</text>
								<view class="form-value">
									<text class="value-text value-filled">{{ authExpiryDisplay }}</text>
								</view>
							</view>
						</view>
					</view>
					
					<view v-if="pendingHasGuideImage" class="pending-image-card">
						<image :src="pendingGuideImage" mode="aspectFill" class="pending-image" />
						<text class="image-label">已提交导游证</text>
					</view>
					<view class="pending-tips">
						<uni-icons type="info" size="16" color="#FF8C00"></uni-icons>
						<text class="pending-tips-text">审核期间无法修改认证信息，如需重新提交，请等待审核结果。</text>
					</view>
				</view>
			</view>
			
			<!-- 未认证 / 未通过表单页面 -->
			<view v-else class="content">
				<view v-if="isRejected" class="status-banner status-failed">
					<uni-icons type="close" size="32" color="#FF4D4F"></uni-icons>
					<text class="status-text">审核未通过，请核对信息后重新提交认证资料。</text>
				</view>
				
				<!-- 页面标题 -->
				<view class="page-header">
					<text class="page-title">导游证认证</text>
					<text class="page-subtitle">请上传真实、完整、内容清晰可辨的图片</text>
				</view>
				
				<!-- 基本信息表单 -->
				<view class="form-section">
					<view class="form-item" @click="openGuideNumInput">
						<view class="form-row">
							<text class="form-label">导游证编号</text>
							<view class="form-value">
								<text class="value-text" :class="(formGuideNum != null && formGuideNum != '') ? 'value-filled' : 'value-placeholder'">
									{{ (formGuideNum != null && formGuideNum != '') ? formGuideNum : '请输入导游证编号' }}
								</text>
								<text class="arrow">›</text>
							</view>
						</view>
					</view>
					<view class="form-divider"></view>
					<view class="form-item" @click="openDatePicker">
						<view class="form-row">
							<text class="form-label">证件有效期</text>
							<view class="form-value">
								<text class="value-text" :class="(formExpiry != null && formExpiry != '') ? 'value-filled' : 'value-placeholder'">
									{{ (formExpiry != null && formExpiry != '') ? formExpiry : '请选择证件有效期' }}
								</text>
								<text class="arrow">›</text>
							</view>
						</view>
					</view>
				</view>
				
				<!-- 导游证照片上传 -->
				<view class="form-section">
					<text class="section-title">导游证照片</text>
					<text class="section-desc">请确保图片清晰完整，信息可见</text>
					<view class="upload-item" @click="uploadImage">
						<image
							v-if="formGuideImage != null && formGuideImage != ''"
							class="upload-image"
							:src="formGuideImage"
							mode="aspectFill"
						/>
						<view v-else class="upload-placeholder">
							<uni-icons type="camera" size="80" color="#333333"></uni-icons>
							<text class="upload-text">上传导游证照片</text>
							<text class="upload-desc">请上传清晰完整的导游证照片</text>
						</view>
					</view>
				</view>
			</view>
			
		</view>
		
		<!-- 底部提交按钮（流式布局，参考 addTrends 发布按钮） -->
		<view v-if="isEditable" class="submit-section">
			<view class="submit-btn" :style="{ backgroundColor: (canSubmit && !submitting) ? '#37B1F2' : '#F0F0F0' }" @click="handleSubmit">
				<text class="btn-text" :style="{ color: (canSubmit && !submitting) ? '#FFFFFF' : '#CCCCCC' }">{{ submitting ? '提交中...' : (isRejected ? '重新提交' : '提交') }}</text>
			</view>
		</view>
		
		<!-- 导游证编号输入弹窗 -->
		<view v-if="showGuideInput" class="popup-mask" @click="closeGuideNumInput">
			<view class="popup-container" @click.stop="">
				<view class="popup-header">
					<text class="popup-title">编辑导游证编号</text>
				</view>
				<view class="popup-content">
					<input
						class="edit-input"
						v-model="tempGuideNum"
						placeholder="请输入导游证编号"
						:maxlength="20"
						:focus="showGuideInput"
						:adjust-position="true"
						:cursor-spacing="200"
					/>
				</view>
				<view class="popup-actions">
					<view class="action-btn cancel-btn" @click="closeGuideNumInput">
						<text class="cancel-btn-text">取消</text>
					</view>
					<view class="action-btn confirm-btn" @click="confirmGuideNum">
						<text class="confirm-btn-text">确认</text>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 证件有效期滚轮选择器弹窗 -->
		<view v-if="showDatePicker" class="picker-mask" @click="closeDatePicker">
			<view class="picker-popup" @click.stop="">
				<view class="picker-header">
					<text class="picker-cancel" @click="closeDatePicker">取消</text>
					<text class="picker-title">选择证件有效期</text>
					<text class="picker-confirm" @click="confirmDate">确定</text>
				</view>
				<view class="picker-body">
					<scroll-view class="picker-column" :scroll-y="true" :scroll-into-view="dpYearScrollId">
						<view v-for="(year, yIndex) in (dpYearList as Array<number>)" :key="yIndex" :id="'dpyear-' + year.toString()" class="picker-item" :class="{ 'picker-item-active': dpTempYear == year }" @click="dpSelectYear(year)">
							<text class="picker-item-text" :class="{ 'picker-item-text-active': dpTempYear == year }">{{ year }}年</text>
						</view>
					</scroll-view>
					<scroll-view class="picker-column" :scroll-y="true" :scroll-into-view="dpMonthScrollId">
						<view v-for="(month, mIndex) in (dpMonthList as Array<number>)" :key="mIndex" :id="'dpmonth-' + month.toString()" class="picker-item" :class="{ 'picker-item-active': dpTempMonth == month }" @click="dpSelectMonth(month)">
							<text class="picker-item-text" :class="{ 'picker-item-text-active': dpTempMonth == month }">{{ month }}月</text>
						</view>
					</scroll-view>
					<scroll-view class="picker-column" :scroll-y="true" :scroll-into-view="dpDayScrollId">
						<view v-for="(day, dIndex) in (dpDayList as Array<number>)" :key="dIndex" :id="'dpday-' + day.toString()" class="picker-item" :class="{ 'picker-item-active': dpTempDay == day }" @click="dpSelectDay(day)">
							<text class="picker-item-text" :class="{ 'picker-item-text-active': dpTempDay == day }">{{ day }}日</text>
						</view>
					</scroll-view>
				</view>
			</view>
		</view>
	</view>
</template>

<script setup lang="uts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { headerGradientOuter, headerGradientMask } from '@/common/utils/themeHelper.uts'
import { handlePageError, handleSilentError } from '@/common/utils/errorHandler.uts'
import request from '@/utils/request'
import { getUserId } from '@/stores/user.uts'
import { pageStatusBarHeight, initPageLayout } from '@/common/composables/usePageLayout.uts'
import { 
	checkUserLoginReliable, 
	waitForLoginStatus, 
	getCurrentUserIdReliable,
	onLoginStatusChange,
	offLoginStatusChange,
	parseLoginStatusData,
	getIsLoginFromData
} from '@/common/utils/loginHelper.uts'
import { cosUploader } from '@/utils/upload/index.uts'
import { requestPermissionTip, PERMISSION_CAMERA_ALBUM } from '@/common/utils/permissionTipManager.uts'
// 🎯 导入统一的用户信息缓存刷新函数
import { refreshCurrentUserProfile, destroyEventListeners } from '@/common/composables/useCurrentUserProfile.uts'
import { safeGetStorageSync } from '@/common/utils/storageHelper'

const authStatus = ref(10) // 10:未认证 20:审核中 30:已通过 40:未通过
const submitting = ref(false)

// 返回按钮处理
const handleBack = () => {
	uni.navigateBack({
		delta: 1,
		fail: () => {
			uni.switchTab({ url: '/pages/my/index' })
		}
	})
}

// 使用独立 ref 存储表单字段，避免 iOS 端复合对象序列化问题
const formGuideNumVal = ref<string>('')
const formExpiryVal = ref<string>('')
const formGuideImageVal = ref<string>('')

const authGuideNumVal = ref<string>('')
const authExpiryVal = ref<string>('')
const authGuideImageVal = ref<string>('')

const showGuideInput = ref(false)
const showDatePicker = ref(false)
const tempGuideNum = ref('')

const getCurrentUserKid = (): string | null => {
	try {
		// 使用 loginHelper 的可靠版本获取用户ID
		const reliableUserId = getCurrentUserIdReliable()
		if (reliableUserId != null && reliableUserId != '') {
			return reliableUserId
		}
		
		// 降级使用 storage
		const storage = safeGetStorageSync('userInfo') as string
		if (storage == null) {
			return null
		}
		const rawJson = (typeof storage === 'string') ? storage : JSON.stringify(storage)
		if (rawJson == null || rawJson == '') return null
		const parsed = JSON.parse(rawJson) as UTSJSONObject
		if (parsed == null) return null
		let kidGetVal: string | number | boolean | UTSJSONObject | null = null
		try { kidGetVal = parsed.get('kid') } catch (e) {}
		const kidStr = (kidGetVal != null && kidGetVal != '') ? kidGetVal.toString() : ''
		return (kidStr != null && kidStr.length > 0) ? kidStr : null
	} catch (e) {
		handleSilentError(e, '读取用户信息')
		return null
	}
}

const isPending = computed(() => authStatus.value === 20)
const isApproved = computed(() => authStatus.value === 30)
const isRejected = computed(() => authStatus.value === 40)
const isEditable = computed(() => authStatus.value === 10 || authStatus.value === 40)

// 直接读取独立 ref，不再需要 JSON 序列化（必须在 computed 引用之前定义，UTS 不支持 const 提升）
const getAuthGuideNum = (): string => { return authGuideNumVal.value }
const getAuthExpiryDate = (): string => { return authExpiryVal.value }
const getAuthGuideImage = (): string => { return authGuideImageVal.value }
const getFormGuideNum = (): string => { return formGuideNumVal.value }
const getFormExpiry = (): string => { return formExpiryVal.value }
const getFormGuideImage = (): string => { return formGuideImageVal.value }
const setFormExpiry = (value: string): void => { formExpiryVal.value = value }

const canSubmit = computed((): boolean => {
	try {
		if (isEditable.value == null || isEditable.value == false) return false
		// 使用已有的 UTS-safe getter 函数，避免 iOS 端 toUTSJSON 序列化问题
		const numStr = getFormGuideNum()
		const expiryStr = getFormExpiry()
		const imgStr = getFormGuideImage()
		return (numStr != '' && expiryStr != '' && imgStr != '')
	} catch (e) {}
	return false
})

const maskedGuideNum = computed((): string => {
	try {
		const authNum = getAuthGuideNum()
		const formNum = getFormGuideNum()

		const guideNum = (authNum != '') ? authNum : formNum
		if (guideNum == null || guideNum == '') return '--'
		if (guideNum.length <= 6) return guideNum
		return guideNum.substring(0, 3) + '****' + guideNum.substring(guideNum.length - 3)
	} catch (e) {}
	return '--'
})

const authGuideNum = computed((): string => { return authGuideNumVal.value })
const pendingHasGuideImage = computed((): boolean => { return authGuideImageVal.value != '' })
const pendingGuideImage = computed((): string => { return authGuideImageVal.value })
const authExpiryDisplay = computed((): string => { return (authExpiryVal.value != '') ? authExpiryVal.value : '--' })
const authGuideImage = computed((): string => { return authGuideImageVal.value })
const formGuideNum = computed((): string => { return formGuideNumVal.value })
const formExpiry = computed((): string => { return formExpiryVal.value })
const formGuideImage = computed((): string => { return formGuideImageVal.value })

const loadAuthStatus = async () => {
	try {
		const userKid = getCurrentUserKid()
		if (userKid == null) {
			handleSilentError(new Error('用户未登录'), '加载导游认证信息')
			return
		}
		const paramsPayload = { userKid: userKid } as UTSJSONObject

		const res = await request.post('/user/baseInfo/v1/queryAuthInfo', paramsPayload, false)
		const resJson = JSON.stringify(res)
		const resObj = (resJson != null && resJson != '') ? JSON.parse(resJson) as UTSJSONObject : null
		let codeGetVal: string | number | boolean | UTSJSONObject | null = null
		try { codeGetVal = (resObj != null) ? resObj.get('code') : null } catch (e) {}
		const codeStr = (codeGetVal != null) ? codeGetVal.toString() : ''
		if (codeStr != '200') {
			handleSilentError(new Error('查询认证信息失败'), '加载导游认证信息')
			return
		}
		let dataGetVal: string | number | boolean | UTSJSONObject | null = null
		try { dataGetVal = (resObj != null) ? resObj.get('data') : null } catch (e) {}
		if (dataGetVal == null || dataGetVal == '') {
			return
		}
		let data: UTSJSONObject = {} as UTSJSONObject
		try {
			const dataJson = JSON.stringify(dataGetVal)
			data = (dataJson != null && dataJson != '') ? JSON.parse(dataJson) as UTSJSONObject : {} as UTSJSONObject
		} catch (e) { data = {} as UTSJSONObject }
		// UTS-safe: access fields via UTSJSONObject.get
		let dataObjJson = ''
		try { dataObjJson = JSON.stringify(data) } catch (e) { dataObjJson = '' }
		const dataObjParsed = (dataObjJson != null && dataObjJson != '') ? JSON.parse(dataObjJson) as UTSJSONObject : null
		let statuGetVal: string | number | boolean | UTSJSONObject | null = null
		try { statuGetVal = (dataObjParsed != null) ? dataObjParsed.get('guideAuthenticatStatu') : null } catch (e) {}
		const statusVal = (statuGetVal != null && statuGetVal != '') ? parseInt(statuGetVal.toString()) : 10
		authStatus.value = (statusVal === 10 || statusVal === 20 || statusVal === 30 || statusVal === 40) ? statusVal : 10
		let guideNumGetVal: string | number | boolean | UTSJSONObject | null = null
		try { guideNumGetVal = (dataObjParsed != null) ? dataObjParsed.get('guideAuthenticatNum') : null } catch (e) {}
		let expiryGetVal: string | number | boolean | UTSJSONObject | null = null
		try { expiryGetVal = (dataObjParsed != null) ? dataObjParsed.get('expiryDate') : null } catch (e) {}
		let guideImageGetVal: string | number | boolean | UTSJSONObject | null = null
		try { guideImageGetVal = (dataObjParsed != null) ? dataObjParsed.get('guideAuthenticatImage') : null } catch (e) {}
		const guideNum = (guideNumGetVal != null && guideNumGetVal != '') ? guideNumGetVal.toString() : ''
		const expiry = (expiryGetVal != null && expiryGetVal != '') ? expiryGetVal.toString() : ''
		const guideImage = (guideImageGetVal != null && guideImageGetVal != '') ? guideImageGetVal.toString() : ''
		if (isApproved.value || isPending.value) {
			authGuideNumVal.value = guideNum
			authExpiryVal.value = expiry
			authGuideImageVal.value = guideImage
			formGuideNumVal.value = ''
			formExpiryVal.value = ''
			formGuideImageVal.value = ''
		} else {
			formGuideNumVal.value = guideNum
			formExpiryVal.value = expiry
			formGuideImageVal.value = guideImage
			authGuideNumVal.value = ''
			authExpiryVal.value = ''
			authGuideImageVal.value = ''
		}
	} catch (error) {
		handlePageError(error, '加载导游认证信息', null)
	}
}

onMounted(() => {
	initPageLayout()
	loadAuthStatus()
})

// 原生 input 事件处理 — 安全提取输入值
const getInputValue = (e: UniInputEvent): string => {
	try {
		const eStr = JSON.stringify(e)
		if (eStr != null && eStr != '') {
			const eObj = JSON.parse(eStr) as UTSJSONObject
			if (eObj != null) {
				const detailVal = eObj.get('detail')
				if (detailVal != null) {
					const detailStr = JSON.stringify(detailVal)
					if (detailStr != null && detailStr != '') {
						const detail = JSON.parse(detailStr) as UTSJSONObject
						const valueVal = detail.get('value')
						if (valueVal != null) {
							return valueVal.toString()
						}
					}
				}
			}
		}
	} catch (err) {}
	return ''
}

const onGuideNumInput = (e: UniInputEvent) => {
	tempGuideNum.value = getInputValue(e)
}

const openGuideNumInput = () => {
	if (isEditable.value == null || isEditable.value == false) return
	tempGuideNum.value = getFormGuideNum()
	showGuideInput.value = true
}

const closeGuideNumInput = () => {
	showGuideInput.value = false
}

const confirmGuideNum = () => {
	const value = tempGuideNum.value.trim()
	if (value == null || value == '') {
		uni.showToast({ title: '请输入导游证编号', icon: 'none' })
		return
	}
	formGuideNumVal.value = value
	showGuideInput.value = false
}

// ========== 证件有效期滚轮选择器 ==========
const dpYearList = ref<Array<number>>([])
const dpMonthList = ref<Array<number>>([])
const dpDayList = ref<Array<number>>([])
const dpTempYear = ref<number>(2030)
const dpTempMonth = ref<number>(1)
const dpTempDay = ref<number>(1)
const dpYearScrollId = ref<string>('')
const dpMonthScrollId = ref<string>('')
const dpDayScrollId = ref<string>('')

const dpGetDaysInMonth = (year: number, month: number): number => {
	const date = new Date(year, month, 0)
	return date.getDate()
}

const dpInitDayList = () => {
	const days: Array<number> = []
	const daysInMonth = dpGetDaysInMonth(dpTempYear.value, dpTempMonth.value)
	let i = 1
	while (i <= daysInMonth) {
		days.push(i)
		i = i + 1
	}
	dpDayList.value = days
}

const openDatePicker = () => {
	if (isEditable.value == null || isEditable.value == false) return
	
	// 初始化年份列表（当前年份 ~ 当前年份+20）
	const years: Array<number> = []
	const currentYear = new Date().getFullYear()
	let y = currentYear
	while (y <= currentYear + 20) {
		years.push(y)
		y = y + 1
	}
	dpYearList.value = years
	
	// 初始化月份列表
	const months: Array<number> = []
	let m = 1
	while (m <= 12) {
		months.push(m)
		m = m + 1
	}
	dpMonthList.value = months
	
	// 解析当前有效期
	const currentValue = getFormExpiry()
	if (currentValue != null && currentValue != '') {
		const parts = currentValue.split('-')
		if (parts.length >= 3) {
			const yVal = parseInt(parts[0])
			if (isNaN(yVal) == false) dpTempYear.value = yVal
			const mVal = parseInt(parts[1])
			if (isNaN(mVal) == false) dpTempMonth.value = mVal
			const dVal = parseInt(parts[2])
			if (isNaN(dVal) == false) dpTempDay.value = dVal
		}
	} else {
		dpTempYear.value = currentYear + 5
		dpTempMonth.value = 1
		dpTempDay.value = 1
	}
	
	dpInitDayList()
	
	// 设置滚动定位
	dpYearScrollId.value = 'dpyear-' + dpTempYear.value.toString()
	dpMonthScrollId.value = 'dpmonth-' + dpTempMonth.value.toString()
	dpDayScrollId.value = 'dpday-' + dpTempDay.value.toString()
	
	showDatePicker.value = true
}

const closeDatePicker = () => {
	showDatePicker.value = false
}

const dpSelectYear = (year: number) => {
	dpTempYear.value = year
	dpInitDayList()
	if (dpTempDay.value > dpDayList.value.length) {
		dpTempDay.value = dpDayList.value.length
	}
}

const dpSelectMonth = (month: number) => {
	dpTempMonth.value = month
	dpInitDayList()
	if (dpTempDay.value > dpDayList.value.length) {
		dpTempDay.value = dpDayList.value.length
	}
}

const dpSelectDay = (day: number) => {
	dpTempDay.value = day
}

const confirmDate = () => {
	const monthStr = (dpTempMonth.value < 10) ? ('0' + dpTempMonth.value.toString()) : dpTempMonth.value.toString()
	const dayStr = (dpTempDay.value < 10) ? ('0' + dpTempDay.value.toString()) : dpTempDay.value.toString()
	const dateValue = dpTempYear.value.toString() + '-' + monthStr + '-' + dayStr
	setFormExpiry(dateValue)
	showDatePicker.value = false
}

// 使用 cosUploader 上传导游证图片到 COS
const uploadGuideCardToCOS = async (filePath: string): Promise<string> => {
	try {
		const result = await cosUploader.uploadGuideCard(filePath, (progress: number) => {
			console.log('📈 导游证图片上传进度:', progress.toString() + '%')
		})
		
		// 🔧 关键：使用 UTSJSONObject 的 get 方法访问属性
		if (result != null) {
			const successVal = result.get('success')
			const success = (successVal != null && successVal.toString() == 'true')
			if (success == true) {
				const dataVal = result.get('data')
				if (dataVal != null) {
					const data = dataVal as UTSJSONObject
					const compressedUrlVal = data.get('compressedUrl')
					const originalUrlVal = data.get('originalUrl')
					if (compressedUrlVal != null && compressedUrlVal.toString() != '') {
						return compressedUrlVal.toString()
					} else if (originalUrlVal != null && originalUrlVal.toString() != '') {
						return originalUrlVal.toString()
					}
				}
			}
			
			let errorMsg = '上传失败'
			const errorVal = result.get('error')
			if (errorVal != null && errorVal.toString() != '') {
				errorMsg = errorVal.toString()
			}
			throw new Error(errorMsg)
		}
		
		throw new Error('上传失败')
	} catch (error) {
		handleSilentError(error as any, '导游证图片上传')
		throw error
	}
}

const uploadImage = () => {
	const userKid = getCurrentUserKid()
	if (userKid == null) {
		uni.showToast({ title: '用户未登录，请先登录', icon: 'none' })
		return
	}
	requestPermissionTip(PERMISSION_CAMERA_ALBUM).then((confirmed: boolean): void => {
		if (confirmed != true) return
	uni.chooseImage({
		count: 1,
		sizeType: ['compressed'],
		sourceType: ['album', 'camera'],
		success: (res) => {
			if ((res.tempFilePaths == null) || (res.tempFilePaths.length === 0)) {
				return
			}
			const filePath = res.tempFilePaths[0]
			uni.showLoading({ title: '上传中...', mask: true })
			
			// 使用 cosUploader 直传到 COS
			uploadGuideCardToCOS(filePath).then((imageUrl: string) => {
				uni.hideLoading()
				if (imageUrl != null && imageUrl != '') {
					formGuideImageVal.value = imageUrl
					uni.showToast({ title: '上传成功', icon: 'none' })
				} else {
					uni.showToast({ title: '图片上传失败，请重试', icon: 'none' })
				}
			}).then((resultIgnore: any | null) => {
				// 成功处理已在上面完成
			}, (err: any | null) => {
				uni.hideLoading()
				handleSilentError(err as any, '导游证图片上传')
				let errorMsg = '图片上传失败，请重试'
				if (err != null) {
					try {
						const errStr = JSON.stringify(err)
						const errObj = JSON.parse(errStr) as UTSJSONObject
						const msgVal = errObj.get('message')
						if (msgVal != null && msgVal.toString() != '') {
							errorMsg = msgVal.toString()
						}
					} catch (e) {}
				}
				uni.showToast({ title: errorMsg, icon: 'none' })
			})
		}
	})
	}) // requestPermissionTip
}

const handleSubmit = async () => {
	if (!canSubmit.value) return
	if (submitting.value) return
	if (!canSubmit.value) {
		console.log('📋 [Guide] canSubmit 为 false，不提交')
		return
	}
	if (submitting.value) {
		console.log('📋 [Guide] 正在提交中，忽略重复点击')
		return
	}
	if (!canSubmit.value) {
		console.log('📋 [Guide] canSubmit 为 false，不提交')
		return
	}
	if (submitting.value) {
		console.log('📋 [Guide] 正在提交中，忽略重复点击')
		return
	}
	if (authStatus.value === 20) {
		uni.showToast({ title: '导游认证正在审核中，请耐心等待', icon: 'none' })
		return
	}
	if (authStatus.value === 30) {
		uni.showToast({ title: '导游认证已通过，无需再次提交', icon: 'none' })
		return
	}
	const imgValCheck = getFormGuideImage()
	if (imgValCheck == null || imgValCheck == '') {
		uni.showToast({ title: '请上传导游证照片', icon: 'none' })
		return
	}
	const numValCheck = getFormGuideNum()
	if (numValCheck == null || numValCheck == '') {
		uni.showToast({ title: '请输入导游证编号', icon: 'none' })
		return
	}
	const expiryValCheck = getFormExpiry()
	if (expiryValCheck == null || expiryValCheck == '') {
		uni.showToast({ title: '请选择证件有效期', icon: 'none' })
		return
	}
	const userKid = getCurrentUserKid()
	if (userKid == null) {
		uni.showToast({ title: '用户信息不存在，请重新登录', icon: 'none' })
		return
	}
	submitting.value = true
	try {
			const guideImage = (getFormGuideImage() != null && getFormGuideImage() != '') ? getFormGuideImage() : ''
			const guideNum = (getFormGuideNum() != null && getFormGuideNum() != '') ? getFormGuideNum() : ''
			// GuideAuthParams: userKid, guideAuthenticatImage, guideCertificateNo (optional)
			const submitPayload = {
				userKid: userKid,
				guideAuthenticatImage: guideImage,
				guideCertificateNo: guideNum
			} as UTSJSONObject

			const res = await request.post('/user/baseInfo/guideAuth', submitPayload, true)
			const resJson = JSON.stringify(res)
			const resObj = (resJson != null && resJson != '') ? JSON.parse(resJson) as UTSJSONObject : null
			let codeGetVal: string | number | boolean | UTSJSONObject | null = null
			try { codeGetVal = (resObj != null) ? resObj.get('code') : null } catch (e) {}
			const codeSubmitStr = (codeGetVal != null) ? codeGetVal.toString() : ''
			if (codeSubmitStr == '200') {
			uni.showToast({ title: '提交成功，请等待审核', icon: 'none' })
			// 🎯 刷新用户信息缓存（更新认证状态）
			refreshCurrentUserProfile().then((profile: any | null) => {
			}).catch((err: any | null): void => {
				handleSilentError(err as any, '[GuideAuth] 刷新缓存')
			})
			await loadAuthStatus()
		} else {
				let msgGetVal: string | number | boolean | UTSJSONObject | null = null
				try { msgGetVal = (resObj != null) ? resObj.get('msg') : null } catch (e) {}
				let msgGetVal2: string | number | boolean | UTSJSONObject | null = null
				try { msgGetVal2 = (resObj != null) ? resObj.get('message') : null } catch (e) {}
				const msg = (msgGetVal != null && msgGetVal != '') ? msgGetVal.toString() : ((msgGetVal2 != null && msgGetVal2 != '') ? msgGetVal2.toString() : '提交失败')
			uni.showToast({ title: msg, icon: 'none' })
		}
	} catch (error) {
		handlePageError(error, '提交导游认证', null)
	} finally {
		submitting.value = false
	}
}

// 🔧 优化：组件卸载时清理 useCurrentUserProfile 事件监听器，防止内存泄漏
onUnmounted(() => {
	destroyEventListeners()
})
</script>

<style scoped>
.page {
	flex-direction: column;
	width: 750rpx;
	height: 100%;
	background-color: #F5F5F5;
	padding-bottom: 40rpx;
}

/* #ifndef H5 */
/* APP端导航栏样式（流式布局） */
.nav-bar {
	position: relative;
	z-index: 10;
	flex-direction: column;
}

.nav-content {
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	height: 88rpx;
	padding-left: 20rpx;
	padding-right: 20rpx;
}

.nav-back {
	width: 80rpx;
	height: 88rpx;
	flex-direction: row;
	align-items: center;
	justify-content: flex-start;
}

.nav-title {
	font-size: 34rpx;
	color: #333333;
	font-weight: bold;
}

.nav-placeholder {
	width: 80rpx;
}
/* #endif */

.hear-bg {
	width: 750rpx;
	height: 392rpx;
	position: absolute;
	top: 0;
	left: 0;
	z-index: 0;
}

.hear-bg-mask {
	position: absolute;
	top: 0;
	left: 0;
	width: 750rpx;
	height: 392rpx;
	z-index: 0;
}

.guide-page {
	background-color: transparent;
	position: relative;
	z-index: 1;
}

.success-page {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-start;
	padding: 20rpx 28rpx;
}

.pending-page {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-start;
	padding: 20rpx 28rpx;
}

.success-content {
	width: 100%;
	background-color: #ffffff;
	border-radius: 24rpx;
	box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
	padding: 48rpx 40rpx 40rpx;
	text-align: center;
}

.success-icon-wrapper {
	width: 120rpx;
	height: 120rpx;
	border-radius: 60rpx;
	background-color: #37B1F2;
	display: flex;
	align-items: center;
	justify-content: center;
	margin: 0 auto 32rpx;
	box-shadow: 0 8rpx 24rpx rgba(45, 202, 194, 0.4);
}

.success-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 64rpx;
	color: #ffffff;
}

.success-title {
	font-size: 40rpx;
	color: #333333;
	font-weight: bold;
	margin-bottom: 32rpx;
	display: flex;
	justify-content: center;
	text-align: center;
}

.auth-result {
	margin-top: 24rpx;
}

.success-image-wrapper {
	margin-top: 24rpx;
	margin-right: 0;
	margin-bottom: 0;
	margin-left: 0;
	text-align: center;
	width: 100%;
}

.success-image {
	width: 100%;
	height: 360rpx;
	border-radius: 16rpx;
	overflow: hidden;
}

.image-label {
	margin-top: 12rpx;
	font-size: 26rpx;
	color: #666666;
	text-align: center;
}

.pending-content {
	width: 100%;
	background-color: #ffffff;
	border-radius: 24rpx;
	box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
	padding-top: 48rpx;
	padding-bottom: 40rpx;
	padding-left: 40rpx;
	padding-right: 40rpx;
	text-align: center;
}

.pending-icon-wrapper {
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 24rpx;
}

.pending-title {
	font-size: 40rpx;
	color: #333333;
	font-weight: bold;
	margin-bottom: 20rpx;
	display: flex;
	justify-content: center;
	text-align: center;
}

.pending-desc {
	font-size: 26rpx;
	color: #999999;
	line-height: 1.6;
	margin-bottom: 32rpx;
	display: flex;
	text-align: center;
}

.pending-image-card {
	margin-top: 24rpx;
}

.pending-image {
	width: 100%;
	height: 360rpx;
	border-radius: 16rpx;
	overflow: hidden;
}

.pending-tips {
	margin-top: 32rpx;
	display: flex;
	flex-direction: row;
	align-items: center;
	background-color: #FFF3E0;
	border-radius: 8rpx;
	padding: 16rpx 20rpx;
}

.pending-tips-text {
	flex: 1;
	font-size: 22rpx;
	color: #FF6B35;
	line-height: 1.4;
	margin-left: 8rpx;
}

.content {
	padding: 8rpx 0 16rpx;
}

.status-banner {
	background-color: #FFEBEE;
	padding: 20rpx 28rpx;
	display: flex;
	align-items: center;
	margin-bottom: 20rpx;
}

.status-failed {
	background-color: #FFEBEE;
}

.status-text {
	flex: 1;
	font-size: 26rpx;
	color: #FF5C5C;
}

.page-header {
	padding: 24rpx 28rpx 16rpx;
	text-align: center;
}

.page-title {
	font-size: 36rpx;
	color: #333333;
	font-weight: bold;
	margin-bottom: 8rpx;
	display: flex;
}

.page-subtitle {
	font-size: 24rpx;
	color: #999999;
	display: flex;
}

.form-section {
	background-color: #ffffff;
	padding: 28rpx;
	margin-top: 0;
	margin-right: 28rpx;
	margin-bottom: 20rpx;
	margin-left: 28rpx;
	border-radius: 24rpx;
	box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
}

.section-title {
	font-size: 30rpx;
	color: #333333;
	font-weight: bold;
	margin-bottom: 12rpx;
	display: flex;
}

.section-desc {
	font-size: 24rpx;
	color: #999999;
	margin-bottom: 24rpx;
	display: flex;
}

.form-item {
	padding: 12rpx 0;
}

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

.form-label {
	font-size: 28rpx;
	color: #333333;
}

.form-value {
	display: flex;
	flex-direction: row;
	align-items: center;
}

.value-text {
	font-size: 28rpx;
}

.value-placeholder {
	color: #C0C4CC;
}

.value-filled {
	color: #333333;
}

.arrow {
	margin-left: 8rpx;
	font-size: 28rpx;
	color: #C8C8C8;
}

.form-divider {
	height: 2rpx;
	background-color: #F2F2F2;
	margin: 8rpx 0;
}

.upload-item {
	width: 100%;
	height: 300rpx;
	border-radius: 8rpx;
	overflow: hidden;
}

.upload-image {
	width: 100%;
	height: 100%;
}

.upload-placeholder {
	width: 100%;
	height: 100%;
	background-color: #f8f9fa;
	border: 4rpx dashed #e0e0e0;
	border-radius: 8rpx;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
}

.upload-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 16rpx;
}

.upload-text {
	font-size: 28rpx;
	color: #333333;
	margin-bottom: 8rpx;
}

.upload-desc {
	font-size: 22rpx;
	color: #999999;
}

.footer-section {
	padding: 40rpx 32rpx;
	flex-direction: column;
	align-items: center;
}

.submit-section {
	padding: 40rpx 32rpx;
	flex-direction: column;
	align-items: center;
}

.submit-btn {
	width: 654rpx;
	height: 88rpx;
	border-radius: 44rpx;
	background-color: #37B1F2;
	flex-direction: row;
	align-items: center;
	justify-content: center;
	position: relative;
	z-index: 1;
}

.submit-btn.disabled {
	background: #F0F0F0;
	box-shadow: none;
}

.submit-btn.disabled .btn-text {
	color: #CCCCCC;
}

.btn-text {
	font-size: 32rpx;
	font-weight: bold;
	color: #FFFFFF;
}

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

.popup-container {
	width: 600rpx;
	background-color: #ffffff;
	border-radius: 20rpx;
	flex-direction: column;
}

.popup-header {
	padding-top: 30rpx;
	padding-bottom: 30rpx;
	border-bottom-width: 1rpx;
	border-bottom-style: solid;
	border-bottom-color: #f0f0f0;
	flex-direction: row;
	justify-content: center;
}

.popup-title {
	font-size: 32rpx;
	color: #333333;
	font-weight: bold;
}

.popup-content {
	padding-left: 30rpx;
	padding-right: 30rpx;
	padding-top: 30rpx;
	padding-bottom: 30rpx;
	flex-direction: column;
}

.edit-input {
	width: 540rpx;
	height: 80rpx;
	border-width: 1rpx;
	border-style: solid;
	border-color: #e0e0e0;
	border-radius: 10rpx;
	padding-left: 20rpx;
	padding-right: 20rpx;
	font-size: 28rpx;
}

.popup-actions {
	flex-direction: row;
	border-top-width: 1rpx;
	border-top-style: solid;
	border-top-color: #f0f0f0;
}

.action-btn {
	flex: 1;
	height: 90rpx;
	flex-direction: row;
	justify-content: center;
	align-items: center;
}

.cancel-btn {
	border-right-width: 1rpx;
	border-right-style: solid;
	border-right-color: #f0f0f0;
}

.cancel-btn-text {
	font-size: 30rpx;
	color: #666666;
}

.confirm-btn-text {
	font-size: 30rpx;
	color: #07c160;
}

/* ========== 滚轮日期选择器样式 ========== */
.picker-mask {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background-color: rgba(0, 0, 0, 0.5);
	z-index: 1000;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
}

.picker-popup {
	width: 750rpx;
	background-color: #ffffff;
	border-top-left-radius: 24rpx;
	border-top-right-radius: 24rpx;
	flex-direction: column;
}

.picker-header {
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	padding-left: 32rpx;
	padding-right: 32rpx;
	padding-top: 32rpx;
	padding-bottom: 32rpx;
	border-bottom-width: 1rpx;
	border-bottom-style: solid;
	border-bottom-color: #EEEEEE;
}

.picker-cancel {
	font-size: 30rpx;
	color: #999999;
}

.picker-title {
	font-size: 32rpx;
	font-weight: bold;
	color: #333333;
}

.picker-confirm {
	font-size: 30rpx;
	color: #37B1F2;
	font-weight: bold;
}

.picker-body {
	flex-direction: row;
	height: 400rpx;
}

.picker-column {
	flex: 1;
	height: 400rpx;
}

.picker-item {
	height: 80rpx;
	flex-direction: row;
	align-items: center;
	justify-content: center;
}

.picker-item-active {
	background-color: #E6F7FF;
}

.picker-item-text {
	font-size: 30rpx;
	color: #333333;
}

.picker-item-text-active {
	color: #37B1F2;
	font-weight: bold;
}
</style>
