<template>
	<view class="page-container" :class="{ 'page-container--laser': isLaserCardCraft }">
		
		<!-- 背景图片 -->
		<image class="background-image" src="/static/background/starbook.jpg" mode="aspectFill"></image>
		<view v-if="isLaserCardCraft" class="laser-bg-veil" aria-hidden="true" />

		<!-- 镭射卡：左上角关闭 -->
		<!-- <view v-if="isLaserCardCraft" class="laser-close-hit" @click="handleBack">
			<text class="laser-close-x">×</text>
		</view> -->

		<!-- 主内容区域 -->
		<scroll-view
			class="content-wrapper"
			:class="{ 'content-wrapper--laser': isLaserCardCraft }"
			scroll-y="true"
			:show-scrollbar="false"
			:enhanced="scrollEnhanced"
		>
			<!-- 页面标题 -->
			<!-- <view v-if="pageName" class="page-title">
				<text class="title-text">创建{{ pageName }}</text>
			</view> -->
			
			<!-- 光栅卡：必须分别上传背景 + 主体 -->
			<view v-if="isLenticularCraft" class="upload-section">
				<view class="lenticular-upload-row">
					<view class="upload-box upload-box--half" @click="chooseLenticularBg">
						<image v-if="uploadedBg" class="uploaded-image" :src="uploadedBg" mode="aspectFit"></image>
						<view v-else class="upload-placeholder">
							<image class="upload-icon" src="/static/icon/add.png" mode="aspectFit"></image>
							<text class="upload-text">背景图</text>
						</view>
					</view>
					<view class="upload-box upload-box--half" @click="chooseLenticularSubject">
						<image v-if="uploadedSubject" class="uploaded-image":src="uploadedSubject" mode="aspectFit"></image>
						<view v-else class="upload-placeholder">
							<image class="upload-icon" src="/static/icon/add.png" mode="aspectFit"></image>
							<text class="upload-text">主体图</text>
						</view>
					</view>
				</view>
				<view class="upload-hint">请各上传一张：JPG / PNG，单张不超过 5MB</view>
			</view>

			<!-- 其他工艺：单图上传 -->
			<view v-else class="upload-section" :class="{ 'upload-section--laser': isLaserCardCraft }">
				<view class="upload-box-wrap">
					<view
						:class="isLaserCardCraft ? 'castlove-laser-upload-root' : 'upload-box'"
						@click="onSingleUploadTap"
					>
						<image v-if="uploadedImage" class="uploaded-image" :src="uploadedImage" mode="aspectFill"></image>
						<view v-else-if="isLaserCardCraft" class="upload-laser-stack">
							<image
								class="upload-laser-photo-bg"
								src="/static/castlove/leisheka.png"
								mode="aspectFill"
							/>
							<view class="upload-laser-watermark" aria-hidden="true" />
							<view class="upload-laser-inset">
								<view class="upload-laser-dashed-inner">
									<text class="upload-plus upload-plus--laser">+</text>
									<text class="upload-text upload-text--laser">点击上传图片</text>
								</view>
							</view>
						</view>
						<view v-else class="upload-placeholder">
							<image class="upload-icon" src="/static/icon/add.png" mode="aspectFit" />
							<text class="upload-text">点击上传图片</text>
						</view>
					</view>
					<view
						v-if="isLaserCardCraft && uploadedImage"
						class="upload-clear upload-clear--laser"
						@click.stop="clearSingleUploadedImage"
					>
						<text class="upload-clear-x upload-clear-x--laser">×</text>
					</view>
				</view>
				<view class="upload-hint">{{ isLaserCardCraft ? '支持JPG.PNG格式，大小不超过5M' : '支持JPG、PNG格式，大小不超过5MB' }}</view>
			</view>

			<!-- 表单区域 -->
			<view class="form-section" :class="{ 'form-section--laser': isLaserCardCraft }">
				<!-- 素材类型选择器 -->
				<view class="form-item form-item-picker">
					<text class="form-label" :class="{ 'form-label--laser': isLaserCardCraft }">素材类型</text>
					<view class="custom-picker">
						<view class="picker-display" :class="{ 'picker-display--laser': isLaserCardCraft }" @click="toggleMaterialTypePicker">
							<text class="picker-text">{{ materialTypes[materialTypeIndex] }}</text>
							<text
								class="picker-arrow"
								:class="{
									'picker-arrow-up': showMaterialTypePicker,
									'picker-arrow--laser': isLaserCardCraft,
								}"
							>{{ isLaserCardCraft ? '▼' : '›' }}</text>
						</view>
						<view v-if="showMaterialTypePicker" class="picker-options">
							<view v-for="(type, index) in materialTypes" :key="index" class="picker-option"
								:class="{ 'picker-option-active': materialTypeIndex === index }"
								@click.stop="selectMaterialType(index)">
								<text class="picker-option-text">{{ type }}</text>
								<text v-if="materialTypeIndex === index" class="picker-option-check">✓</text>
							</view>
						</view>
					</view>
				</view>

				<!-- 藏品信息 -->
				<view class="form-item">
					<text class="form-label" :class="{ 'form-label--laser': isLaserCardCraft }">藏品信息</text>
					<textarea
						class="form-textarea"
						:class="{ 'form-textarea--laser': isLaserCardCraft }"
						v-model="nftInfo"
						placeholder="请输入藏品相关信息"
						placeholder-class="textarea-placeholder"
						maxlength="500"
						auto-height
						:show-confirm-bar="false"
					/>
				</view>
			</view>

			<!-- AI描述区域 -->
			<view class="ai-section" :class="{ 'ai-section--laser': isLaserCardCraft }">
				<text class="section-title" :class="{ 'section-title--laser': isLaserCardCraft }">{{ isLaserCardCraft ? 'AI生成描述' : 'AI 生成描述' }}</text>

				<!-- AI描述输入框 -->
				<view class="ai-input-wrapper" :class="{ 'ai-input-wrapper--laser': isLaserCardCraft }">
					<textarea 
						class="ai-input" 
						v-model="aiDescription" 
						placeholder="背景有什么想法？边框想要什么样式的？有没有特别想加的装饰元素？整体材质的效果想要什么样的？主色调是应援色吗，还是别的颜色？" 
						placeholder-class="ai-placeholder"
						auto-height
						:show-confirm-bar="false"
						maxlength="500"
					/>
					<view v-if="!isLaserCardCraft" class="input-actions">
						<!-- 发送按钮 -->
						<view class="action-icon-btn send-btn" @click="handleGenerate">
							<image class="action-icon" src="/static/icon/send.png" mode="aspectFit" />
							<text class="action-text">发送</text>
						</view>
					</view>
				</view>
			</view>

			<!-- 底部按钮 -->
			<view class="button-section" :class="{ 'button-section--laser': isLaserCardCraft }">
				<button class="btn-secondary" :class="{ 'btn-secondary--laser': isLaserCardCraft }" @click="handleBack">返回</button>
				<button v-if="isLenticularCraft" class="btn-skip" @click="handleLenticularGenerate">生成</button>
				<button
					v-else-if="isLaserCardCraft"
					class="btn-confirm-laser"
					@click="startCraftStudioPipeline(STUDIO_LASER)"
				>
					生成
				</button>
				<button
					v-else
					class="btn-skip"
					@click="handleGenerate"
				>
					生成
				</button>
			</view>
		</scroll-view>

	</view>

	<!-- 通用确认弹窗 -->
	<ConfirmModal
		:visible="confirmModal.visible"
		:title="confirmModal.title"
		:content="confirmModal.content"
		:confirmText="confirmModal.confirmText"
		:cancelText="confirmModal.cancelText"
		:showCancel="confirmModal.showCancel"
		@confirm="onConfirmModal"
		@cancel="onCancelModal"
	/>
</template>

<script>
export default {
	inheritAttrs: false,
};
</script>

<script setup>
import { ref, computed, onMounted } from 'vue';
import { onLoad, onUnload } from '@dcloudio/uni-app';
import { getOssSignatureApi, createMintOrderApi } from '@/utils/api.js';
import { resolveH5OssPostUrl } from '@/utils/h5OssPostUrl.js';
import ConfirmModal from '@/components/ConfirmModal.vue';
import './create-laser-upload.css';
import {
	buildCastloveFormSnapshot,
	CRAFT_LENTICULAR_CN,
	CRAFT_LASER_CARD_CN,
	LENTICULAR_STUDIO_STORAGE_KEY,
} from '@/utils/castloveMintForm.js';
import {
	startAiImageGenerationFlow,
	startCraftGenerationFlow,
	STUDIO_LENTICULAR,
	STUDIO_LASER,
} from '@/utils/castloveGenerationFlow.js';

// 获取页面参数（H5 必须用 onLoad 读 query；仅靠 onMounted + getCurrentPages().options 常为 undefined）
const pageType = ref('');
const pageName = ref('');
// #ifdef MP-WEIXIN
const scrollEnhanced = true;
// #endif
// #ifndef MP-WEIXIN
const scrollEnhanced = false;
// #endif

const isLenticularCraft = computed(() => (pageName.value || '').trim() === CRAFT_LENTICULAR_CN);
const isLaserCardCraft = computed(() => (pageName.value || '').trim() === CRAFT_LASER_CARD_CN);

onUnload(() => {
	try {
		uni.hideToast();
	} catch (e) {
		/* noop */
	}
	try {
		uni.hideLoading();
	} catch (e) {
		/* noop */
	}
});

function safeDecodeParam(v) {
	if (v == null || v === '') return '';
	const s = typeof v === 'string' ? v : String(v);
	try {
		return decodeURIComponent(s.replace(/\+/g, ' '));
	} catch {
		return s;
	}
}

function applyCreateRouteOptions(options) {
	if (!options || typeof options !== 'object') return;
	if (options.type) pageType.value = safeDecodeParam(options.type);
	if (options.name != null && String(options.name) !== '') {
		pageName.value = safeDecodeParam(options.name);
		console.log('[CreatePage] 工艺名称:', pageName.value);
	}
}

// 通用确认弹窗状态
const confirmModal = ref({
	visible: false,
	title: '',
	content: '',
	confirmText: '确认',
	cancelText: '取消',
	showCancel: true,
	confirmCallback: null
});

// 弹窗确认回调
const onConfirmModal = () => {
	if (confirmModal.value.confirmCallback) {
		confirmModal.value.confirmCallback({ confirm: true });
	}
	confirmModal.value.visible = false;
};

// 弹窗取消回调
const onCancelModal = () => {
	if (confirmModal.value.confirmCallback) {
		confirmModal.value.confirmCallback({ confirm: false });
	}
	confirmModal.value.visible = false;
};

// 显示通用确认弹窗
const showConfirmModal = (options) => {
	confirmModal.value = {
		visible: true,
		title: options.title || '',
		content: options.content || '',
		confirmText: options.confirmText || '确认',
		cancelText: options.cancelText || '取消',
		showCancel: options.showCancel !== false,
		confirmCallback: options.success || null
	};
};

// 表单数据
const uploadedImage = ref('');
const uploadedImageBase64 = ref('');
/** 光栅：背景 / 主体双槽位；空字符串表示普通单图上传 */
const pendingLenticularSlot = ref('');
const uploadedBg = ref('');
const uploadedBgBase64 = ref('');
const uploadedSubject = ref('');
const uploadedSubjectBase64 = ref('');
const originalFileName = ref('');
const isUploading = ref(false);
const materialTypes = ['粉丝自制', '热爱痕迹', '其他'];
const materialTypeIndex = ref(0);
const showMaterialTypePicker = ref(false);
const nftInfo = ref(''); // 藏品信息（合并了名称和事件）

// AI描述相关
const aiDescription = ref('');

// 风格标签数据 - 已移除

function applyUploadResult(filePath, dataUrl) {
	const slot = pendingLenticularSlot.value;
	if (slot === 'bg') {
		uploadedBg.value = filePath;
		uploadedBgBase64.value = dataUrl;
	} else if (slot === 'subject') {
		uploadedSubject.value = filePath;
		uploadedSubjectBase64.value = dataUrl;
	} else {
		uploadedImage.value = filePath;
		uploadedImageBase64.value = dataUrl;
	}
	pendingLenticularSlot.value = '';
	uni.hideLoading();
	uni.showToast({ title: '图片加载成功', icon: 'success', duration: 1500 });
	isUploading.value = false;
}

// 选择图片（非光栅单图）
const chooseImage = () => {
	openImagePicker('');
};

const onSingleUploadTap = () => {
	chooseImage();
};

const clearSingleUploadedImage = () => {
	uploadedImage.value = '';
	uploadedImageBase64.value = '';
	originalFileName.value = '';
};

const chooseLenticularBg = () => {
	openImagePicker('bg');
};

const chooseLenticularSubject = () => {
	openImagePicker('subject');
};

const openImagePicker = (lenticularSlot) => {
	if (isUploading.value) {
		uni.showToast({ title: '图片上传中，请稍候', icon: 'none' });
		return;
	}
	pendingLenticularSlot.value = lenticularSlot;

	uni.chooseImage({
		count: 1,
		sourceType: ['album', 'camera'],
		success: (res) => {
			const filePath = res.tempFilePaths[0];
			const tempFile = res.tempFiles && res.tempFiles[0];

			uni.getFileInfo({
				filePath: filePath,
				success: (fileInfo) => {
					const maxSize = 5 * 1024 * 1024;
					if (fileInfo.size > maxSize) {
						pendingLenticularSlot.value = '';
						uni.showToast({ title: '图片大小不能超过5MB', icon: 'none', duration: 2000 });
						return;
					}

					const mimeType = (tempFile && tempFile.type) ? tempFile.type.toLowerCase() : '';
					const pathLower = filePath.toLowerCase();
					const validByMime = mimeType === 'image/jpeg' || mimeType === 'image/png';
					const validByExt = pathLower.endsWith('.jpg') || pathLower.endsWith('.jpeg') || pathLower.endsWith('.png');
					if (!validByMime && !validByExt) {
						pendingLenticularSlot.value = '';
						uni.showToast({ title: '只支持JPG和PNG格式', icon: 'none', duration: 2000 });
						return;
					}

					const rawName = (tempFile && tempFile.name) ? tempFile.name : filePath.split('/').pop();
					originalFileName.value = rawName;
					convertImageToBase64(filePath, originalFileName.value);
				},
				fail: (error) => {
					pendingLenticularSlot.value = '';
					console.error('获取文件信息失败:', error);
					uni.showToast({ title: '获取文件信息失败', icon: 'none' });
				}
			});
		},
		fail: (err) => {
			pendingLenticularSlot.value = '';
			console.error('选择图片失败:', err);
			uni.showToast({ title: '选择图片失败', icon: 'none' });
		}
	});
};

// 将图片转换为 base64
const convertImageToBase64 = (filePath, fileName) => {
	isUploading.value = true;
	uni.showLoading({ title: '处理中...', mask: true });

	// #ifdef H5
	convertImageToBase64H5(filePath, fileName);
	// #endif
	
	// #ifndef H5
	convertImageToBase64Native(filePath, fileName);
	// #endif
};

const convertImageToBase64H5 = (filePath, fileName) => {
	fetch(filePath)
		.then(res => res.blob())
		.then(blob => {
			const reader = new FileReader();
			reader.onload = (e) => {
				applyUploadResult(filePath, e.target.result);
				console.log('[CreatePage] Base64转换成功 (H5)');
				console.log('[CreatePage] Base64长度:', (e.target.result && e.target.result.length) || 0);
			};
			reader.onerror = (error) => {
				pendingLenticularSlot.value = '';
				console.error('[CreatePage] Base64转换失败 (H5):', error);
				uni.hideLoading();
				uni.showToast({ title: '图片处理失败', icon: 'none', duration: 2000 });
				isUploading.value = false;
			};
			reader.readAsDataURL(blob);
		})
		.catch(error => {
			pendingLenticularSlot.value = '';
			console.error('[CreatePage] 获取图片失败 (H5):', error);
			uni.hideLoading();
			uni.showToast({ title: '图片处理失败', icon: 'none', duration: 2000 });
			isUploading.value = false;
		});
};

const convertImageToBase64Native = (filePath, fileName) => {
	// #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ
	const fs = uni.getFileSystemManager();
	fs.readFile({
		filePath: filePath,
		encoding: 'base64',
		success: (res) => {
			const ext = fileName.toLowerCase().split('.').pop();
			let mimeType = 'image/jpeg';
			if (ext === 'png') mimeType = 'image/png';
			const dataUrl = `data:${mimeType};base64,${res.data}`;
			applyUploadResult(filePath, dataUrl);
			console.log('[CreatePage] Base64转换成功 (小程序)');
			console.log('[CreatePage] Base64长度:', dataUrl.length);
		},
		fail: (error) => {
			pendingLenticularSlot.value = '';
			console.error('[CreatePage] Base64转换失败 (小程序):', error);
			uni.hideLoading();
			uni.showToast({ title: '图片处理失败', icon: 'none', duration: 2000 });
			isUploading.value = false;
		}
	});
	// #endif
	
	// #ifdef APP-PLUS
	plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
		entry.file((file) => {
			const reader = new plus.io.FileReader();
			reader.onloadend = (e) => {
				applyUploadResult(filePath, e.target.result);
				console.log('[CreatePage] Base64转换成功 (App)');
				console.log('[CreatePage] Base64长度:', (e.target.result && e.target.result.length) || 0);
			};
			reader.onerror = (error) => {
				pendingLenticularSlot.value = '';
				console.error('[CreatePage] Base64转换失败 (App):', error);
				uni.hideLoading();
				uni.showToast({ title: '图片处理失败', icon: 'none', duration: 2000 });
				isUploading.value = false;
			};
			reader.readAsDataURL(file);
		});
	}, (error) => {
		pendingLenticularSlot.value = '';
		console.error('[CreatePage] 读取文件失败 (App):', error);
		uni.hideLoading();
		uni.showToast({ title: '图片处理失败', icon: 'none', duration: 2000 });
		isUploading.value = false;
	});
	// #endif
};

// 切换素材类型选择器
const toggleMaterialTypePicker = () => {
	showMaterialTypePicker.value = !showMaterialTypePicker.value;
};

const selectMaterialType = (index) => {
	materialTypeIndex.value = index;
	showMaterialTypePicker.value = false;
};

// 上传图片到OSS的辅助函数
const uploadImageToOss = async (base64Data, ossData) => {
	return new Promise((resolve, reject) => {
		const fileName = `${Date.now()}.jpg`;
		
		// #ifdef H5
		// H5：仍走原有 OSS PostObject；本地开发经 manifest devServer /dev-oss-proxy 转发，避免 CORS
		fetch(base64Data)
			.then((res) => res.blob())
			.then((blob) => {
				const formData = new FormData();
				formData.append('key', ossData.dir + fileName);
				formData.append('policy', ossData.policy);
				formData.append('success_action_status', '200');
				formData.append('x-oss-credential', ossData.x_oss_credential);
				formData.append('x-oss-date', ossData.x_oss_date);
				formData.append('x-oss-security-token', ossData.security_token);
				formData.append('x-oss-signature', ossData.signature);
				formData.append('x-oss-signature-version', ossData.x_oss_signature_version);
				formData.append('file', blob, fileName);
				return fetch(resolveH5OssPostUrl(ossData.host), {
					method: 'POST',
					body: formData
				});
			})
			.then((response) => {
				if (response.ok || response.status === 204) {
					const imageUrl = `${ossData.host}/${ossData.dir}${fileName}`;
					resolve(imageUrl);
				} else {
					reject(new Error('上传失败'));
				}
			})
			.catch((error) => {
				reject(error);
			});
		// #endif
		
		// #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ
		// 小程序环境 - 使用文件系统管理器
		const base64Content = base64Data.split(',')[1];
		const filePath = `${wx.env.USER_DATA_PATH}/${fileName}`;
		
		const fs = uni.getFileSystemManager();
		fs.writeFile({
			filePath: filePath,
			data: base64Content,
			encoding: 'base64',
			success: () => {
				uni.uploadFile({
					url: ossData.host,
					filePath: filePath,
					name: 'file',
					formData: {
						key: ossData.dir + fileName,
						policy: ossData.policy,
						success_action_status: '200',
						'x-oss-credential': ossData.x_oss_credential,
						'x-oss-date': ossData.x_oss_date,
						'x-oss-security-token': ossData.security_token,
						'x-oss-signature': ossData.signature,
						'x-oss-signature-version': ossData.x_oss_signature_version
					},
					success: (uploadRes) => {
						if (uploadRes.statusCode === 200 || uploadRes.statusCode === 204) {
							const imageUrl = `${ossData.host}/${ossData.dir}${fileName}`;
							resolve(imageUrl);
						} else {
							reject(new Error(`上传失败，状态码: ${uploadRes.statusCode}`));
						}
					},
					fail: (error) => {
						reject(error);
					}
				});
			},
			fail: (error) => {
				reject(error);
			}
		});
		// #endif
		
		// #ifdef APP-PLUS
		// App环境 - 将base64转为临时文件后上传
		console.log('[CreatePage] App环境上传');
		const base64ContentApp = base64Data.split(',')[1];
		const bitmap = new plus.nativeObj.Bitmap('temp');
		
		bitmap.loadBase64Data(base64Data, () => {
			const tempFilePath = `_doc/${fileName}`;
			bitmap.save(tempFilePath, {}, () => {
				console.log('[CreatePage] App临时文件保存成功:', tempFilePath);
				bitmap.clear();
				
				uni.uploadFile({
					url: ossData.host,
					filePath: tempFilePath,
					name: 'file',
					formData: {
						key: ossData.dir + fileName,
						policy: ossData.policy,
						success_action_status: '200',
						'x-oss-credential': ossData.x_oss_credential,
						'x-oss-date': ossData.x_oss_date,
						'x-oss-security-token': ossData.security_token,
						'x-oss-signature': ossData.signature,
						'x-oss-signature-version': ossData.x_oss_signature_version
					},
					success: (uploadRes) => {
						console.log('[CreatePage] App上传响应:', uploadRes);
						if (uploadRes.statusCode === 200 || uploadRes.statusCode === 204) {
							const imageUrl = `${ossData.host}/${ossData.dir}${fileName}`;
							resolve(imageUrl);
						} else {
							reject(new Error(`上传失败，状态码: ${uploadRes.statusCode}`));
						}
					},
					fail: (error) => {
						console.error('[CreatePage] App上传失败:', error);
						reject(error);
					}
				});
			}, (error) => {
				console.error('[CreatePage] App保存临时文件失败:', error);
				bitmap.clear();
				reject(new Error('保存临时文件失败'));
			});
		}, (error) => {
			console.error('[CreatePage] App加载base64失败:', error);
			bitmap.clear();
			reject(new Error('加载图片数据失败'));
		});
		// #endif
	});
};

// 返回按钮
const handleBack = async () => {
	const hasLenticular =
		isLenticularCraft.value &&
		(uploadedBg.value || uploadedSubject.value || uploadedBgBase64.value || uploadedSubjectBase64.value);
	const hasAny =
		uploadedImage.value ||
		hasLenticular ||
		nftInfo.value ||
		aiDescription.value;
	if (hasAny) {
		showConfirmModal({
			title: '提示',
			content: '确定要返回吗？未保存的数据将会丢失',
			success: async (res) => {
				if (res.confirm) {
					resetForm();
					try {
						uni.hideToast();
					} catch (e) {
						/* noop */
					}
					uni.navigateBack();
				}
			}
		});
	} else {
		try {
			uni.hideToast();
		} catch (e) {
			/* noop */
		}
		uni.navigateBack();
	}
};

/** 光栅 / 镭射：上传 → Loading → 选图 → 工作室 */
const buildCraftFormData = () => {
	const snap = isLenticularCraft.value
		? buildCastloveFormSnapshot({
				nftInfo: nftInfo.value,
				materialTypes,
				materialTypeIndex: materialTypeIndex.value,
				pageName: pageName.value,
				uploadedImage: uploadedSubject.value,
				uploadedImageBase64: uploadedSubjectBase64.value,
		  })
		: buildCastloveFormSnapshot({
				nftInfo: nftInfo.value,
				materialTypes,
				materialTypeIndex: materialTypeIndex.value,
				pageName: pageName.value,
				uploadedImage: uploadedImage.value,
				uploadedImageBase64: uploadedImageBase64.value,
		  });

	return {
		...snap,
		image: isLenticularCraft.value ? uploadedSubject.value : uploadedImage.value,
		imageBase64: isLenticularCraft.value ? uploadedSubjectBase64.value : uploadedImageBase64.value,
		type: pageType.value,
		typeName: pageName.value,
		materialType: snap.material_type,
		materialTypeIndex: materialTypeIndex.value,
		materialTypes: [...materialTypes],
		aiDescription: aiDescription.value,
		nftInfo: nftInfo.value,
		...(isLenticularCraft.value
			? {
					lenticularBgImage: uploadedBg.value,
					lenticularBgBase64: uploadedBgBase64.value,
					lenticularSubjectImage: uploadedSubject.value,
					lenticularSubjectBase64: uploadedSubjectBase64.value,
			  }
			: {}),
	};
};

const buildCraftPrompt = () => {
	let fullText = aiDescription.value.trim() || nftInfo.value.trim();
	if (pageName.value) {
		fullText = `${pageName.value}，${fullText}`;
	}
	return fullText;
};

/** 光栅 / 镭射工作室入口：直达各自 thinking 页，不经 discover/generation-loading */
const startCraftStudioPipeline = (studioKind) => {
	if (isLenticularCraft.value) {
		if (!uploadedBg.value || !uploadedSubject.value) {
			uni.showToast({ title: '请上传背景图与主体图', icon: 'none' });
			return;
		}
		if (!uploadedBgBase64.value || !uploadedSubjectBase64.value) {
			uni.showToast({ title: '图片尚未处理完成', icon: 'none' });
			return;
		}
	} else {
		if (!uploadedImage.value) {
			uni.showToast({ title: '请上传藏品图片', icon: 'none' });
			return;
		}
		if (!uploadedImageBase64.value) {
			uni.showToast({ title: '图片尚未处理完成', icon: 'none' });
			return;
		}
	}
	if (!nftInfo.value.trim()) {
		uni.showToast({ title: '请输入藏品信息', icon: 'none' });
		return;
	}
	try {
		const formData = buildCraftFormData();
		startCraftGenerationFlow({ formData, studioKind });
	} catch (e) {
		console.error('[CreatePage] craft studio pipeline', e);
		uni.showToast({ title: '启动失败，请重试', icon: 'none' });
	}
};

const handleLenticularGenerate = () => {
	startCraftStudioPipeline(STUDIO_LENTICULAR);
};

// 底部导航切换
const handleTabChange = (newTab) => {
	const routes = [
		'/pages/square/square',
		'/pages/starbook/index',
		'/pages/castlove/mall',
		'/pages/starcity/index',
		'/pages/ai-dazi/index'
	];
	
	if (newTab >= 0 && newTab < routes.length) {
		uni.navigateTo({ url: routes[newTab] });
	}
};

// 开始生成（星卡等走铸造；光栅/镭射走工作室链路）
const handleGenerate = async () => {
	if (isLenticularCraft.value) {
		startCraftStudioPipeline(STUDIO_LENTICULAR);
		return;
	}
	if (isLaserCardCraft.value) {
		startCraftStudioPipeline(STUDIO_LASER);
		return;
	}

	if (!uploadedImage.value) {
		uni.showToast({ title: '请上传藏品图片', icon: 'none' });
		return;
	}
	if (!uploadedImageBase64.value) {
		uni.showToast({ title: '图片尚未处理完成', icon: 'none' });
		return;
	}

	if (!nftInfo.value.trim()) {
		uni.showToast({ title: '请输入藏品信息', icon: 'none' });
		return;
	}

	let fullText = aiDescription.value.trim();
	if (pageName.value) {
		fullText = `${pageName.value}，${fullText}`;
	}

	if (!fullText || fullText === `${pageName.value}，`) {
		uni.showToast({ title: '请输入AI描述', icon: 'none' });
		return;
	}

	const snap = buildCastloveFormSnapshot({
		nftInfo: nftInfo.value,
		materialTypes,
		materialTypeIndex: materialTypeIndex.value,
		pageName: pageName.value,
		uploadedImage: uploadedImage.value,
		uploadedImageBase64: uploadedImageBase64.value,
	});

	const formData = {
		...snap,
		image: uploadedImage.value,
		imageBase64: uploadedImageBase64.value,
		type: pageType.value,
		typeName: pageName.value,
		materialType: snap.material_type,
	};

	try {
		uni.setStorageSync('castlove_form_data', JSON.stringify(formData));
	} catch (e) {
		console.error('保存表单数据失败:', e);
		return;
	}

	sendToBackend(fullText);
};

// 发送数据到后端 → 统一 Loading → 选择藏品
const sendToBackend = (aiDescription) => {
	const formDataStr = uni.getStorageSync('castlove_form_data');
	const formData = formDataStr ? JSON.parse(formDataStr) : {};
	startAiImageGenerationFlow({ prompt: aiDescription, formData });
};

// 重置表单
const resetForm = () => {
	pendingLenticularSlot.value = '';
	uploadedBg.value = '';
	uploadedBgBase64.value = '';
	uploadedSubject.value = '';
	uploadedSubjectBase64.value = '';
	uploadedImage.value = '';
	uploadedImageBase64.value = '';
	originalFileName.value = '';
	isUploading.value = false;
	materialTypeIndex.value = 0;
	nftInfo.value = '';
	aiDescription.value = '';
};

onLoad((options) => {
	applyCreateRouteOptions(options || {});
});

onMounted(() => {
	const pages = getCurrentPages();
	const currentPage = pages[pages.length - 1];
	const options = (currentPage && currentPage.options) || {};
	if (options.name || options.type) {
		applyCreateRouteOptions(options);
	}
});
</script>

<style scoped>
.page-container {
	position: relative;
	width: 100vw;
	height: 100vh;
	overflow: hidden;
}

.background-image {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	object-fit: cover;
}

.background-overlay {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	background: rgba(0, 0, 0, 0.3);
}

.content-wrapper {
	position: relative;
	z-index: 1;
	width: 100%;
	height: 100%;
	padding: 100rpx 32rpx 40rpx 32rpx;
	box-sizing: border-box;
}

/* 隐藏滚动条 */
.content-wrapper::-webkit-scrollbar {
	display: none;
	width: 0;
	height: 0;
}

/* 页面标题 */
.page-title {
	width: 100%;
	text-align: center;
	margin-bottom: 40rpx;
}

.title-text {
	font-size: 48rpx;
	color: #ffffff;
	font-weight: 700;
	font-family: 'yt', sans-serif;
	text-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.5);
	
	background-clip: text;
}

/* 图片上传区域 */
.upload-section {
	width: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	margin-bottom: 40rpx;
}

.upload-box {
	width: 300rpx;
	height: 300rpx;
	background: rgba(255, 255, 255, 0.15);
	backdrop-filter: blur(10rpx);
	border-radius: 30rpx;
	border: 4rpx dashed rgba(255, 255, 255, 0.5);
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.2);
}

.upload-hint {
	margin-top: 20rpx;
	font-size: 24rpx;
	color: rgba(255, 255, 255, 0.7);
	text-align: center;
}

.lenticular-upload-row {
	width: 100%;
	display: flex;
	flex-direction: row;
	justify-content: center;
	align-items: stretch;
	gap: 20rpx;
	padding: 0 4rpx;
	box-sizing: border-box;
}

.upload-box--half {
	flex: 1;
	width: 0;
	min-width: 0;
	height: 280rpx;
}

.uploaded-image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.upload-placeholder {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 20rpx;
}

.upload-icon {
	width: 80rpx;
	height: 80rpx;
	opacity: 0.8;
}

.upload-text {
	font-size: 24rpx;
	color: rgba(255, 255, 255, 0.9);
	font-weight: 500;
}

/* 表单区域 */
.form-section {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: 30rpx;
	margin-bottom: 40rpx;
}

.form-item {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: 16rpx;
}

.form-item-picker {
	position: relative;
	z-index: 10;
}

.form-label {
	font-size: 36rpx;
	color: #e6e6e6;
	font-weight: 500;
	font-family: 'yt', sans-serif;
	padding: 18rpx 18rpx;
	background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
	border-radius: 44rpx;
	display: inline-block;
	align-self: flex-start;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
	text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.4);
}

/* 自定义选择器 */
.custom-picker {
	position: relative;
	width: 100%;
	z-index: 10;
}

.picker-display {
	width: 100%;
	height: 88rpx;
	background: rgba(255, 255, 255, 0.15);
	backdrop-filter: blur(10rpx);
	border-radius: 20rpx;
	padding: 0 30rpx;
	display: flex;
	align-items: center;
	justify-content: space-between;
	box-sizing: border-box;
	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
	transition: all 0.3s ease;
}

.picker-display:active {
	background: rgba(255, 255, 255, 0.2);
}

.picker-text {
	font-size: 32rpx;
	color: rgba(255, 255, 255, 0.85);
	text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}

.picker-arrow {
	font-size: 48rpx;
	color: rgba(255, 255, 255, 0.7);
	font-weight: bold;
	transform: rotate(90deg);
	transition: transform 0.3s ease;
}

.picker-arrow-up {
	transform: rotate(-90deg);
}

.picker-options {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	width: 100%;
	margin-top: 10rpx;
	background: rgba(255, 255, 255, 0.2);
	backdrop-filter: blur(15rpx);
	border-radius: 20rpx;
	overflow: hidden;
	box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.2);
	z-index: 10;
	animation: slideDown 0.3s ease-out;
}

@keyframes slideDown {
	from {
		opacity: 0;
		transform: translateY(-10rpx);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.picker-option {
	width: 100%;
	height: 88rpx;
	padding: 0 30rpx;
	display: flex;
	align-items: center;
	justify-content: space-between;
	box-sizing: border-box;
	transition: background 0.2s ease;
	border-bottom: 1rpx solid rgba(255, 255, 255, 0.1);
}

.picker-option:last-child {
	border-bottom: none;
}

.picker-option:active {
	background: rgba(255, 255, 255, 0.15);
}

.picker-option-active {
	background: rgba(255, 255, 255, 0.1);
}

.picker-option-text {
	font-size: 32rpx;
	color: #e6e6e6;
}

.picker-option-check {
	font-size: 36rpx;
	color: #e6e6e6;
	font-weight: bold;
}

.form-input {
	width: 100%;
	height: 88rpx;
	background: rgba(255, 255, 255, 0.15);
	backdrop-filter: blur(10rpx);
	border-radius: 20rpx;
	padding: 0 30rpx;
	font-size: 32rpx;
	color: #e6e6e6;
	box-sizing: border-box;
	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
}

.input-placeholder {
	color: rgba(255, 255, 255, 0.85);
	font-size: 32rpx;
	text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}

.form-textarea {
	width: 100%;
	min-height: 200rpx;
	max-height: 400rpx;
	background: rgba(255, 255, 255, 0.15);
	backdrop-filter: blur(10rpx);
	border-radius: 20rpx;
	padding: 20rpx 30rpx;
	font-size: 32rpx;
	color: #e6e6e6;
	box-sizing: border-box;
	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
	line-height: 1.5;
}

.textarea-placeholder {
	color: rgba(255, 255, 255, 0.85);
	font-size: 32rpx;
	text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}

/* AI描述区域 */
.ai-section {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: 24rpx;
	margin-bottom: 40rpx;
}

.section-title {
	font-size: 36rpx;
	color: #e6e6e6;
	font-weight: 500;
	font-family: 'yt', sans-serif;
	padding: 18rpx 18rpx;
	background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
	border-radius: 44rpx;
	display: inline-block;
	align-self: flex-start;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
	text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.4);
}

/* AI输入框 */
.ai-input-wrapper {
	width: 100%;
	min-height: 200rpx;
	background: rgba(255, 255, 255, 0.15);
	border-radius: 24rpx;
	backdrop-filter: blur(10rpx);
	border: 2rpx solid rgba(255, 255, 255, 0.3);
	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.15);
	display: flex;
	align-items: flex-start;
	padding: 20rpx 24rpx;
	gap: 16rpx;
	box-sizing: border-box;
}

.ai-input {
	flex: 1;
	min-height: 192rpx;
	max-height: 400rpx;
	font-size: 32rpx;
	color: rgba(255, 255, 255, 0.95);
	padding: 0;
	background: transparent;
	border: none;
	line-height: 1.5;
	box-sizing: border-box;
}

.ai-placeholder {
	color: rgba(255, 255, 255, 0.6);
	font-size: 32rpx;
}

.input-actions {
	display: flex;
	align-items: flex-end;
	padding-top: 120rpx;
}

.action-icon-btn {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4rpx;
	padding: 8rpx 12rpx;
	transition: all 0.3s ease;
}

.action-icon {
	width: 40rpx;
	height: 40rpx;
}

.action-text {
	font-size: 20rpx;
	color: rgba(255, 255, 255, 0.8);
	white-space: nowrap;
}

.send-btn .action-text {
	color: rgba(255, 255, 255, 0.95);
	font-weight: 600;
}

.send-btn:active {
	opacity: 0.8;
}

/* 底部按钮 */
.button-section {
	width: 100%;
	display: flex;
	gap: 20rpx;
	margin-top: 40rpx;
	padding-bottom: calc(40rpx + constant(safe-area-inset-bottom)); /* iOS 11.0 */
	padding-bottom: calc(40rpx + env(safe-area-inset-bottom)); /* iOS 11.2+ */
}

.btn-secondary,
.btn-skip {
	flex: 1;
	height: 88rpx;
	line-height: 88rpx;
	border-radius: 44rpx;
	font-size: 36rpx;
	font-family: 'yt', sans-serif;
	font-weight: 600;
	border: none;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
	text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}

.btn-secondary {
	background: rgba(255, 255, 255, 0.2);
	backdrop-filter: blur(10rpx);
	color: #e6e6e6;
	border: 2rpx solid rgba(255, 255, 255, 0.4);
}

.btn-secondary::after {
	border: none;
}

.btn-skip {
	background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
	color: #e6e6e6;
}

.btn-skip::after {
	border: none;
}

.btn-secondary:active {
	background: rgba(255, 255, 255, 0.3);
}

.btn-skip:active {
	opacity: 0.9;
}

/* ========== 镭射卡设计稿专用 ========== */
.page-container--laser {
	position: relative;
}

.laser-bg-veil {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	pointer-events: none;
	background:
		radial-gradient(2rpx 2rpx at 10% 18%, rgba(255, 255, 255, 0.55), transparent 55%),
		radial-gradient(1.5rpx 1.5rpx at 78% 12%, rgba(255, 255, 255, 0.45), transparent 55%),
		radial-gradient(2rpx 2rpx at 42% 8%, rgba(255, 255, 255, 0.4), transparent 50%),
		radial-gradient(1.5rpx 1.5rpx at 88% 46%, rgba(255, 255, 255, 0.5), transparent 50%),
		radial-gradient(2rpx 2rpx at 18% 62%, rgba(255, 255, 255, 0.35), transparent 50%),
		radial-gradient(1.5rpx 1.5rpx at 64% 72%, rgba(255, 255, 255, 0.45), transparent 50%),
		radial-gradient(2rpx 2rpx at 36% 88%, rgba(255, 255, 255, 0.4), transparent 50%),
		radial-gradient(1.5rpx 1.5rpx at 92% 84%, rgba(255, 255, 255, 0.35), transparent 50%),
		linear-gradient(
			165deg,
			rgba(255, 182, 220, 0.16) 0%,
			rgba(140, 100, 210, 0.22) 42%,
			rgba(20, 40, 80, 0.2) 100%
		);
}

.laser-close-hit {
	position: fixed;
	top: calc(16rpx + constant(safe-area-inset-top));
	top: calc(16rpx + env(safe-area-inset-top));
	left: 24rpx;
	z-index: 20;
	width: 72rpx;
	height: 72rpx;
	border-radius: 50%;
	background: linear-gradient(
		135deg,
		#ffb7e8 0%,
		#c9a6ff 28%,
		#8fd4ff 55%,
		#fff3b0 78%,
		#ffa8d8 100%
	);
	background-size: 180% 180%;
	border: 2rpx solid rgba(255, 255, 255, 0.55);
	box-shadow: 0 6rpx 22rpx rgba(120, 60, 160, 0.35);
	display: flex;
	align-items: center;
	justify-content: center;
}

.laser-close-x {
	color: #ffffff;
	font-size: 44rpx;
	line-height: 1;
	font-weight: 300;
}

.content-wrapper--laser {
	padding-top: calc(112rpx + constant(safe-area-inset-top));
	padding-top: calc(112rpx + env(safe-area-inset-top));
}

.upload-section--laser .upload-box-wrap {
	position: relative;
	width: 100%;
	max-width: 640rpx;
	margin: 0 auto;
}

.upload-section--laser .upload-hint {
	color: rgba(255, 255, 255, 0.88);
	font-size: 22rpx;
	margin-top: 16rpx;
}

.upload-section--laser .upload-clear {
	position: absolute;
	top: 14rpx;
	right: 14rpx;
	z-index: 6;
	width: 56rpx;
	height: 56rpx;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
}

.upload-clear--laser {
	background: rgba(255, 255, 255, 0.96);
	border: 2rpx solid rgba(255, 255, 255, 0.95);
	box-shadow: 0 6rpx 18rpx rgba(60, 30, 100, 0.22);
}

.upload-clear-x--laser {
	color: #3d6fd8;
	font-size: 34rpx;
	font-weight: 400;
}

.form-section--laser {
	gap: 36rpx;
}

.form-label--laser,
.section-title--laser {
	font-size: 28rpx;
	padding: 10rpx 22rpx;
	border-radius: 999rpx;
	background: linear-gradient(95deg, #ff7ec8 0%, #ff9f7a 48%, #ffb35c 100%);
	color: #ffffff;
	text-shadow: 0 2rpx 6rpx rgba(160, 40, 80, 0.35);
	box-shadow: 0 4rpx 14rpx rgba(255, 100, 140, 0.28);
}

.ai-section--laser {
	gap: 20rpx;
}

.picker-display--laser {
	background: rgba(255, 255, 255, 0.32);
	backdrop-filter: blur(22rpx);
	-webkit-backdrop-filter: blur(22rpx);
	border: 2rpx solid rgba(255, 255, 255, 0.45);
	box-shadow: 0 8rpx 28rpx rgba(50, 20, 90, 0.12);
}

.form-textarea--laser {
	background: rgba(255, 255, 255, 0.32);
	backdrop-filter: blur(22rpx);
	-webkit-backdrop-filter: blur(22rpx);
	border: 2rpx solid rgba(255, 255, 255, 0.42);
	box-shadow: 0 8rpx 28rpx rgba(50, 20, 90, 0.1);
}

.picker-arrow.picker-arrow--laser {
	transform: rotate(0deg);
	font-size: 22rpx;
	line-height: 1;
	color: rgba(255, 255, 255, 0.88);
	font-weight: 600;
}

.picker-arrow.picker-arrow--laser.picker-arrow-up {
	transform: rotate(180deg);
}

.ai-input-wrapper--laser {
	flex-direction: column;
	min-height: 280rpx;
	padding: 24rpx 28rpx 28rpx;
	background: rgba(255, 255, 255, 0.32);
	backdrop-filter: blur(22rpx);
	-webkit-backdrop-filter: blur(22rpx);
	border: 2rpx solid rgba(255, 255, 255, 0.45);
	box-shadow: 0 8rpx 28rpx rgba(50, 20, 90, 0.1);
}

.ai-input-wrapper--laser .ai-input {
	min-height: 220rpx;
	width: 100%;
}

.button-section--laser {
	gap: 24rpx;
	margin-top: 48rpx;
}

.btn-secondary--laser {
	background: rgba(255, 255, 255, 0.18);
	border-color: rgba(255, 255, 255, 0.35);
}

.btn-confirm-laser {
	flex: 1;
	height: 96rpx;
	line-height: 96rpx;
	border-radius: 48rpx;
	font-size: 36rpx;
	font-family: 'yt', sans-serif;
	font-weight: 600;
	color: #ffffff;
	border: none;
	display: flex;
	align-items: center;
	justify-content: center;
	background: linear-gradient(95deg, #ff8ec5 0%, #ff5a8c 38%, #ff2d6b 72%, #ff4d64 100%);
	box-shadow: 0 10rpx 32rpx rgba(255, 50, 110, 0.42);
	text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.25);
}

.btn-confirm-laser::after {
	border: none;
}

.btn-confirm-laser:active {
	opacity: 0.92;
}

.nav-mask {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	background: rgba(0, 0, 0, 0.3);
	z-index: 999;
	animation: fadeIn 0.3s ease-out;
}

@keyframes fadeIn {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}
</style>
