<template>
  <view class="page-container">
    <!-- 背景图片 -->
    <image
      class="background-image"
      src="/static/background/starbook.jpg"
      mode="aspectFill"
    ></image>

    <!-- 主内容区域 -->
    <scroll-view
      class="content-wrapper"
      scroll-y="true"
      :show-scrollbar="false"
      :enhanced="scrollEnhanced"
    >
      <!-- 光栅卡：必须分别上传背景 + 主体 -->
      <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，单张不超过 2MB</view>
      </view>

      <!-- 表单区域 -->
      <view class="form-section">
        <!-- 素材类型选择器 -->
        <view class="form-item form-item-picker">
          <text class="form-label">素材类型</text>
          <view class="custom-picker">
            <view class="picker-display" @click="toggleMaterialTypePicker">
              <text class="picker-text">{{
                materialTypes[materialTypeIndex]
              }}</text>
              <text
                class="picker-arrow"
                :class="{ 'picker-arrow-up': showMaterialTypePicker }"
                >›</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">藏品信息</text>
          <textarea
            class="form-textarea"
            v-model="nftInfo"
            placeholder="请输入藏品相关信息"
            placeholder-class="textarea-placeholder"
            maxlength="500"
            auto-height
            :show-confirm-bar="false"
          />
        </view>
      </view>

      <!-- AI描述区域 -->
      <view class="ai-section">
        <text class="section-title">AI 生成描述</text>

        <!-- AI描述输入框 -->
        <view class="ai-input-wrapper">
          <textarea
            class="ai-input"
            v-model="aiDescription"
            placeholder="背景有什么想法？边框想要什么样式的？有没有特别想加的装饰元素？整体材质的效果想要什么样的？主色调是应援色吗，还是别的颜色？"
            placeholder-class="ai-placeholder"
            auto-height
            :show-confirm-bar="false"
            maxlength="500"
          />
        </view>
      </view>

      <!-- 底部按钮 -->
      <view class="button-section">
        <button class="btn-secondary" @click="handleBack">返回</button>
        <button class="btn-skip" @click="handleLenticularGenerate">生成</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 setup>
defineOptions({
  inheritAttrs: false,
});

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 { getSandboxFileUri, clearSandboxSubdir } from "@/utils/ioPath.js";
import { useAliveGuard } from "@/composables/useAliveGuard.js";
import ConfirmModal from "@/components/ConfirmModal.vue";
import {
  buildCastloveFormSnapshot,
  CRAFT_LENTICULAR_CN,
} from "@/utils/castloveMintForm.js";
import {
  startCraftGenerationFlow,
  STUDIO_LENTICULAR,
} from "@/utils/castloveGenerationFlow.js";

// #ifdef MP-WEIXIN
const scrollEnhanced = true;
// #endif
// #ifndef MP-WEIXIN
// const scrollEnhanced = false;
// #endif

const pageType = ref("");
const pageName = ref("");

const isLenticularCraft = computed(
  () => (pageName.value || "").trim() === CRAFT_LENTICULAR_CN,
);

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

// alive 守卫:页面销毁后,原生异步回调不再触碰 state,避免 iOS WebView 报错
const { guard } = useAliveGuard();

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("[LenticularCreate] 工艺名称:", 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 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: guard((res) => {
      const filePath = res.tempFilePaths[0];
      const tempFile = res.tempFiles && res.tempFiles[0];

      uni.getFileInfo({
        filePath: filePath,
        success: guard((fileInfo) => {
          const maxSize = 5 * 1024 * 1024;
          const slotLabel = lenticularSlot === "bg" ? "背景图" : "主体图";
          if (fileInfo.size > maxSize) {
            pendingLenticularSlot.value = "";
            showConfirmModal({
              title: "图片不符合要求",
              content: `${slotLabel}大小不能超过5MB，当前图片大小为${(fileInfo.size / 1024 / 1024).toFixed(2)}MB，请重新选择`,
              showCancel: false,
              confirmText: "知道了",
            });
            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 = "";
            showConfirmModal({
              title: "图片格式不符合要求",
              content: `${slotLabel}只支持JPG和PNG格式的图片，请重新选择`,
              showCancel: false,
              confirmText: "知道了",
            });
            return;
          }

          const rawName =
            tempFile && tempFile.name
              ? tempFile.name
              : filePath.split("/").pop();
          originalFileName.value = rawName;
          convertImageToBase64(filePath, originalFileName.value);
        }),
        fail: guard((error) => {
          pendingLenticularSlot.value = "";
          console.error("获取文件信息失败:", error);
          uni.showToast({ title: "获取文件信息失败", icon: "none" });
        }),
      });
    }),
    fail: guard((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("[LenticularCreate] Base64转换成功 (H5)");
        console.log(
          "[LenticularCreate] Base64长度:",
          (e.target.result && e.target.result.length) || 0,
        );
      };
      reader.onerror = (error) => {
        pendingLenticularSlot.value = "";
        console.error("[LenticularCreate] Base64转换失败 (H5):", error);
        uni.hideLoading();
        uni.showToast({ title: "图片处理失败", icon: "none", duration: 2000 });
        isUploading.value = false;
      };
      reader.readAsDataURL(blob);
    })
    .catch((error) => {
      pendingLenticularSlot.value = "";
      console.error("[LenticularCreate] 获取图片失败 (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: guard((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("[LenticularCreate] Base64转换成功 (小程序)");
      console.log("[LenticularCreate] Base64长度:", dataUrl.length);
    }),
    fail: guard((error) => {
      pendingLenticularSlot.value = "";
      console.error("[LenticularCreate] Base64转换失败 (小程序):", error);
      uni.hideLoading();
      uni.showToast({ title: "图片处理失败", icon: "none", duration: 2000 });
      isUploading.value = false;
    }),
  });
  // #endif

  // #ifdef APP-PLUS
  plus.io.resolveLocalFileSystemURL(
    filePath,
    guard((entry) => {
      entry.file(
        guard((file) => {
          const reader = new plus.io.FileReader();
          reader.onloadend = guard((e) => {
            applyUploadResult(filePath, e.target.result);
            console.log("[LenticularCreate] Base64转换成功 (App)");
            console.log(
              "[LenticularCreate] Base64长度:",
              (e.target.result && e.target.result.length) || 0,
            );
          });
          reader.onerror = guard((error) => {
            pendingLenticularSlot.value = "";
            console.error("[LenticularCreate] Base64转换失败 (App):", error);
            uni.hideLoading();
            uni.showToast({
              title: "图片处理失败",
              icon: "none",
              duration: 2000,
            });
            isUploading.value = false;
          });
          reader.readAsDataURL(file);
        }),
      );
    }),
    guard((error) => {
      pendingLenticularSlot.value = "";
      console.error("[LenticularCreate] 读取文件失败 (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
    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: guard(() => {
        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: guard((uploadRes) => {
            if (uploadRes.statusCode === 200 || uploadRes.statusCode === 204) {
              const imageUrl = `${ossData.host}/${ossData.dir}${fileName}`;
              resolve(imageUrl);
            } else {
              reject(new Error(`上传失败，状态码: ${uploadRes.statusCode}`));
            }
          }),
          fail: guard((error) => {
            reject(error);
          }),
        });
      }),
      fail: guard((error) => {
        reject(error);
      }),
    });
    // #endif

    // #ifdef APP-PLUS
    // Android 10+ 适配:bitmap.save 接受沙盒 file:// 绝对路径(避免 '_doc/' 字符串写失败)
    console.log("[LenticularCreate] App环境上传");
    const base64ContentApp = base64Data.split(",")[1];
    const bitmap = new plus.nativeObj.Bitmap("temp");

    bitmap.loadBase64Data(
      base64ContentApp,
      guard(
        () => {
          getSandboxFileUri(["castlove-lenticular", "tmp"], fileName)
            .then((tempFilePath) => {
              bitmap.save(
                tempFilePath,
                { overwrite: true },
                guard(
                  () => {
                    console.log(
                      "[LenticularCreate] 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: guard((uploadRes) => {
                        console.log(
                          "[LenticularCreate] App上传响应:",
                          uploadRes,
                        );
                        if (
                          uploadRes.statusCode === 200 ||
                          uploadRes.statusCode === 204
                        ) {
                          const imageUrl = `${ossData.host}/${ossData.dir}${fileName}`;
                          // 上传成功后清理临时文件(doc/castlove-lenticular/tmp/),避免 doc 残留垃圾
                          clearSandboxSubdir([
                            "castlove-lenticular",
                            "tmp",
                          ]).catch((e) => {
                            console.warn(
                              "[LenticularCreate] clear tmp dir failed:",
                              e?.message,
                            );
                          });
                          resolve(imageUrl);
                        } else {
                          reject(
                            new Error(
                              `上传失败，状态码: ${uploadRes.statusCode}`,
                            ),
                          );
                        }
                      }),
                      fail: guard((error) => {
                        console.error("[LenticularCreate] App上传失败:", error);
                        reject(error);
                      }),
                    });
                  },
                  guard((error) => {
                    console.error(
                      "[LenticularCreate] App保存临时文件失败:",
                      error,
                    );
                    bitmap.clear();
                    reject(new Error("保存临时文件失败"));
                  }),
                ),
              );
            })
            .catch((err) => {
              console.error("[LenticularCreate] getSandboxFileUri 失败:", err);
              bitmap.clear();
              reject(err);
            });
        },
        guard((error) => {
          console.error("[LenticularCreate] 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 = buildCastloveFormSnapshot({
    nftInfo: nftInfo.value,
    materialTypes,
    materialTypeIndex: materialTypeIndex.value,
    pageName: pageName.value,
    uploadedImage: uploadedSubject.value,
    uploadedImageBase64: uploadedSubjectBase64.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;
};

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();
    const result = startCraftGenerationFlow({ formData, studioKind });
    if (result && !result.success && result.error) {
      showConfirmModal({
        title: result.error.title,
        content: result.error.content,
        showCancel: false,
        confirmText: "知道了",
      });
      return;
    }
  } catch (e) {
    console.error("[LenticularCreate] craft studio pipeline", e);
    uni.showToast({ title: "启动失败，请重试", icon: "none" });
  }
};

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

// 重置表单
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;
}

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

/* 图片上传区域 */
.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-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;
  opacity: 0;
  pointer-events: none;
}

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

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

.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;
}
</style>
