<template>
  <div class="ai-3d-container">
    <!-- 页面加载中 -->
    <div v-if="pageLoading" class="page-loading">
      <div class="loading-content">
        <div class="loading-logo">
          <div class="logo-spinner"></div>
          <ThunderboltOutlined class="logo-icon-center" />
        </div>
        <h3>AI 3D Studio</h3>
        <p>正在加载...</p>
      </div>
    </div>

    <!-- Animated Background -->
    <div class="bg-animation">
      <div class="bg-gradient bg-gradient-1"></div>
      <div class="bg-gradient bg-gradient-2"></div>
      <div class="bg-gradient bg-gradient-3"></div>
    </div>

    <!-- 左侧生成栏 -->
    <div class="left-panel">
      <!-- Header with Logo -->
      <div class="panel-logo">
        <a-button type="text" class="back-btn" @click="handleBack">
          <template #icon><ArrowLeftOutlined /></template>
        </a-button>
        <div class="logo-ring">
          <div class="logo-icon">
            <ThunderboltOutlined />
          </div>
        </div>
        <div class="logo-text">
          <h3>AI 3D Studio</h3>
          <p>智能建模工作室</p>
        </div>
      </div>

      <div class="panel-header">
        <a-segmented
          v-model:value="inputType"
          :options="inputTypeOptions"
          block
        />
      </div>

      <div class="panel-content">
        <!-- 文生3D输入 -->
        <div v-if="inputType === 'text'" class="text-input-section">
          <div class="input-label">
            <EditOutlined class="label-icon" />
            <span>创意描述</span>
          </div>
          <div class="input-hint">
            用文字描述你的想法，AI 将为你生成精美的 3D 模型
          </div>
          <div class="textarea-wrapper">
            <a-textarea
              v-model:value="textContent"
              placeholder="例如：一只卡通风格的橙色小猫，蓝色的大眼睛，尾巴卷曲..."
              :rows="5"
              :maxlength="1024"
              class="text-input"
            />
            <span class="char-count">{{ textContent.length }}/1024</span>
          </div>

          <div class="sample-section">
            <div class="sample-header">
              <span class="sample-title">灵感推荐</span>
              <ReloadOutlined class="refresh-icon" @click="refreshSamples" />
            </div>
            <div class="sample-prompts">
              <span
                v-for="(sample, index) in currentSamples"
                :key="index"
                class="sample-tag"
                @click="applySample(sample)"
              >
                {{ sample }}
              </span>
            </div>
          </div>

          <!-- 模型设置 -->
          <div class="model-settings">
            <div class="setting-row">
              <div class="setting-item">
                <span class="setting-label">模型类型</span>
                <a-select v-model:value="generateType" class="setting-select">
                  <a-select-option value="Normal">带纹理</a-select-option>
                  <a-select-option value="LowPoly">低多边形</a-select-option>
                  <a-select-option value="Geometry">白模</a-select-option>
                  <a-select-option value="Sketch">草图</a-select-option>
                </a-select>
              </div>
              <div class="setting-item">
                <span class="setting-label">模型面数</span>
                <a-select v-model:value="faceCount" class="setting-select">
                  <a-select-option :value="50000">5万面</a-select-option>
                  <a-select-option :value="100000">10万面</a-select-option>
                  <a-select-option :value="300000">30万面</a-select-option>
                  <a-select-option :value="500000">50万面</a-select-option>
                  <a-select-option :value="1000000">100万面</a-select-option>
                </a-select>
              </div>
            </div>
          </div>
        </div>

        <!-- 图生3D上传 -->
        <div v-else class="image-input-section">
          <!-- 单张/多张图片切换 -->
          <div class="image-mode-switch">
            <span
              class="mode-link"
              :class="{ active: imageMode === 'single' }"
              @click="imageMode = 'single'"
              >单张图片</span
            >
            <span
              class="mode-link"
              :class="{ active: imageMode === 'multiple' }"
              @click="imageMode = 'multiple'"
              >多张图片</span
            >

            <!-- 图片上传建议 Popover -->
            <a-popover
              placement="rightTop"
              trigger="click"
              :overlayStyle="{ width: '320px' }"
              overlayClassName="image-tips-popover"
            >
              <template #content>
                <div class="image-tips-content">
                  <div class="tips-desc">
                    支持png/jpg/jpeg/webp格式，图片大小最大不超过10M，分辨率最低要求128x128
                  </div>
                  <div class="tips-example">
                    <img
                      src="https://competition-ms-1325825530.cos.ap-guangzhou.myqcloud.com/img/3d-example.png"
                      alt="示例图片"
                    />
                    <div class="tips-list">
                      <div class="tip-item">
                        <CheckCircleFilled class="tip-icon" />
                        <span>背景简单（尽量纯色）</span>
                      </div>
                      <div class="tip-item">
                        <CheckCircleFilled class="tip-icon" />
                        <span>不包含文字</span>
                      </div>
                      <div class="tip-item">
                        <CheckCircleFilled class="tip-icon" />
                        <span>单主体</span>
                      </div>
                      <div class="tip-item">
                        <CheckCircleFilled class="tip-icon" />
                        <span>主体不要过小</span>
                      </div>
                    </div>
                  </div>
                </div>
              </template>
              <template #title>
                <span class="tips-title">图片上传建议</span>
              </template>
              <span class="image-tips-link">
                <QuestionCircleOutlined />
                <span>图片上传建议</span>
              </span>
            </a-popover>
          </div>

          <!-- 单张图片模式 -->
          <template v-if="imageMode === 'single'">
            <a-upload-dragger
              :file-list="[]"
              :before-upload="handleBeforeUpload"
              :show-upload-list="false"
              :max-count="1"
              accept="image/*"
              class="image-upload"
            >
              <template v-if="imageUrl">
                <img :src="imageUrl" alt="预览" class="upload-preview-image" />
                <div class="upload-change-hint">点击更换图片</div>
              </template>
              <template v-else>
                <p class="upload-icon">
                  <PictureOutlined />
                </p>
                <p class="upload-text">点击或拖拽图片到此处</p>
                <p class="upload-hint">支持 JPG、PNG 格式，最大 10MB</p>
              </template>
            </a-upload-dragger>
          </template>

          <!-- 多张图片模式 -->
          <template v-else>
            <div class="multi-image-container">
              <!-- 缩略图展示条 -->
              <div class="thumbnail-bar" @click="openMultiViewModal">
                <div v-if="hasMultiImages" class="thumbnail-list">
                  <div
                    v-for="(img, key) in multiImages"
                    :key="key"
                    class="thumbnail-item"
                    @click.stop
                  >
                    <img :src="img" :alt="getViewName(key)" />
                    <div
                      class="thumbnail-delete"
                      @click="removeMultiImage(key)"
                    >
                      <CloseOutlined />
                    </div>
                  </div>
                </div>
                <div class="thumbnail-add">
                  <PlusOutlined />
                </div>
              </div>
              <div class="upload-tip">
                <InfoCircleOutlined />
                <span>图片上传建议：上传多角度图片可提升生成质量</span>
              </div>
            </div>
          </template>

          <!-- 模型类型选择 -->
          <div class="model-settings">
            <div class="setting-row">
              <div class="setting-item full-width">
                <span class="setting-label">模型类型</span>
                <a-select v-model:value="generateType" class="setting-select">
                  <a-select-option value="Normal">带纹理</a-select-option>
                  <a-select-option value="LowPoly">低多边形</a-select-option>
                  <a-select-option value="Geometry">白模</a-select-option>
                  <a-select-option value="Sketch">草图</a-select-option>
                </a-select>
              </div>
            </div>
          </div>
        </div>

        <!-- 多视图上传弹框 -->
        <a-modal
          v-model:open="multiViewModalVisible"
          title="添加多视图"
          :width="600"
          :footer="null"
          class="multi-view-modal"
          @cancel="multiViewModalVisible = false"
        >
          <div class="multi-view-grid">
            <!-- 顶图 -->
            <div class="view-row top-row">
              <div class="view-item" @click="triggerUpload('top')">
                <template v-if="multiImages.top">
                  <img :src="multiImages.top" alt="顶图" />
                  <div
                    class="view-delete"
                    @click.stop="removeMultiImage('top')"
                  >
                    <CloseOutlined />
                  </div>
                </template>
                <template v-else>
                  <div class="view-placeholder">
                    <PictureOutlined />
                    <span>上传顶图</span>
                  </div>
                </template>
              </div>
            </div>

            <!-- 左45° 正图 右45° -->
            <div class="view-row middle-row">
              <div class="view-item" @click="triggerUpload('left45')">
                <template v-if="multiImages.left45">
                  <img :src="multiImages.left45" alt="左45°图" />
                  <div
                    class="view-delete"
                    @click.stop="removeMultiImage('left45')"
                  >
                    <CloseOutlined />
                  </div>
                </template>
                <template v-else>
                  <div class="view-placeholder">
                    <PictureOutlined />
                    <span>上传左45°图</span>
                  </div>
                </template>
              </div>
              <div class="view-item required" @click="triggerUpload('front')">
                <template v-if="multiImages.front">
                  <img :src="multiImages.front" alt="正图" />
                  <div
                    class="view-delete"
                    @click.stop="removeMultiImage('front')"
                  >
                    <CloseOutlined />
                  </div>
                </template>
                <template v-else>
                  <div class="view-placeholder">
                    <PictureOutlined />
                    <span>上传正图 <span class="required-mark">*</span></span>
                  </div>
                </template>
              </div>
              <div class="view-item" @click="triggerUpload('right45')">
                <template v-if="multiImages.right45">
                  <img :src="multiImages.right45" alt="右45°图" />
                  <div
                    class="view-delete"
                    @click.stop="removeMultiImage('right45')"
                  >
                    <CloseOutlined />
                  </div>
                </template>
                <template v-else>
                  <div class="view-placeholder">
                    <PictureOutlined />
                    <span>上传右45°图</span>
                  </div>
                </template>
              </div>
            </div>

            <!-- 左图 中心预览 右图 -->
            <div class="view-row center-row">
              <div class="view-item" @click="triggerUpload('left')">
                <template v-if="multiImages.left">
                  <img :src="multiImages.left" alt="左图" />
                  <div
                    class="view-delete"
                    @click.stop="removeMultiImage('left')"
                  >
                    <CloseOutlined />
                  </div>
                </template>
                <template v-else>
                  <div class="view-placeholder">
                    <PictureOutlined />
                    <span>上传左图</span>
                  </div>
                </template>
              </div>
              <div class="view-center">
                <div class="center-preview">
                  <img
                    v-if="multiImages.front"
                    :src="multiImages.front"
                    alt="预览"
                  />
                  <div v-else class="center-placeholder">
                    <AppstoreOutlined />
                    <span>3D 预览</span>
                  </div>
                </div>
              </div>
              <div class="view-item" @click="triggerUpload('right')">
                <template v-if="multiImages.right">
                  <img :src="multiImages.right" alt="右图" />
                  <div
                    class="view-delete"
                    @click.stop="removeMultiImage('right')"
                  >
                    <CloseOutlined />
                  </div>
                </template>
                <template v-else>
                  <div class="view-placeholder">
                    <PictureOutlined />
                    <span>上传右图</span>
                  </div>
                </template>
              </div>
            </div>

            <!-- 背图 -->
            <div class="view-row bottom-row">
              <div class="view-item" @click="triggerUpload('back')">
                <template v-if="multiImages.back">
                  <img :src="multiImages.back" alt="背图" />
                  <div
                    class="view-delete"
                    @click.stop="removeMultiImage('back')"
                  >
                    <CloseOutlined />
                  </div>
                </template>
                <template v-else>
                  <div class="view-placeholder">
                    <PictureOutlined />
                    <span>上传背图</span>
                  </div>
                </template>
              </div>
            </div>

            <!-- 底图 -->
            <div class="view-row bottom-row">
              <div class="view-item" @click="triggerUpload('bottom')">
                <template v-if="multiImages.bottom">
                  <img :src="multiImages.bottom" alt="底图" />
                  <div
                    class="view-delete"
                    @click.stop="removeMultiImage('bottom')"
                  >
                    <CloseOutlined />
                  </div>
                </template>
                <template v-else>
                  <div class="view-placeholder">
                    <PictureOutlined />
                    <span>上传底图</span>
                  </div>
                </template>
              </div>
            </div>
          </div>

          <!-- 隐藏的文件输入 -->
          <input
            ref="multiImageInput"
            type="file"
            accept="image/*"
            style="display: none"
            @change="handleMultiImageUpload"
          />
        </a-modal>
      </div>

      <div class="panel-footer">
        <button
          class="generate-btn"
          :class="{ 'is-loading': generating, 'is-disabled': !canGenerate }"
          :disabled="!canGenerate"
          @click="handleGenerate"
        >
          <span class="btn-bg"></span>
          <span class="btn-content">
            <LoadingOutlined v-if="generating" class="spin-icon" />
            <ThunderboltOutlined v-else />
            <span>{{ generating ? "生成中..." : "立即生成" }}</span>
          </span>
        </button>
      </div>
    </div>

    <!-- 右侧内容区 -->
    <div class="right-panel">
      <!-- 介绍区 -->
      <div class="intro-section">
        <h1 class="intro-title">用一句话、一张图，创造你的 3D 世界</h1>
        <p class="intro-desc">
          借助先进的 AI 技术，将文字描述或图片瞬间转化为专业级 3D 模型
        </p>

        <div class="intro-features">
          <div class="feature-card">
            <div class="feature-icon gradient-1">
              <BulbOutlined />
            </div>
            <div class="feature-info">
              <h3>AI 智能建模</h3>
              <p>输入文字或图片，自动生成 3D 模型</p>
            </div>
          </div>

          <div class="feature-card">
            <div class="feature-icon gradient-2">
              <EyeOutlined />
            </div>
            <div class="feature-info">
              <h3>实时预览</h3>
              <p>支持旋转、缩放，全方位查看细节</p>
            </div>
          </div>

          <div class="feature-card">
            <div class="feature-icon gradient-3">
              <FolderOutlined />
            </div>
            <div class="feature-info">
              <h3>作品管理</h3>
              <p>自动保存至个人作品库，随时访问</p>
            </div>
          </div>

          <div class="feature-card">
            <div class="feature-icon gradient-4">
              <SyncOutlined />
            </div>
            <div class="feature-info">
              <h3>迭代优化</h3>
              <p>基于已有作品再次生成与优化</p>
            </div>
          </div>
        </div>
      </div>

      <!-- 创作历史区 -->
      <div class="history-section">
        <div class="history-header">
          <div class="header-left">
            <h2 class="history-title">创作历史</h2>
            <span class="history-count"
              >{{ allHistoryTotal || historyList.length }} 个作品</span
            >
          </div>
          <a class="view-all" @click="goToHistory">
            查看全部
            <ArrowRightOutlined />
          </a>
        </div>

        <div v-if="historyLoading" class="history-loading">
          <div class="loading-spinner">
            <div class="spinner-ring"></div>
            <div class="spinner-ring"></div>
            <div class="spinner-ring"></div>
          </div>
          <p>加载中...</p>
        </div>

        <div v-else-if="historyList.length === 0" class="history-empty">
          <div class="empty-icon">
            <FileImageOutlined />
          </div>
          <p class="empty-title">还没有创作记录</p>
          <p class="empty-text">开始你的第一次 3D 创作之旅吧</p>
        </div>

        <div v-else ref="historyGridRef" class="history-grid">
          <div
            v-for="task in displayedHistoryList"
            :key="task.id"
            class="history-card"
            @click="handleViewTask(task)"
          >
            <div class="card-preview">
              <img
                v-if="task.status === 'completed' && task.previewUrl"
                :src="getPreviewUrl(task)"
                alt="预览"
                class="preview-image"
                @error="handleImageError"
                @load="handleImageLoad"
              />
              <div
                v-else-if="
                  task.status === 'processing' || task.status === 'pending'
                "
                class="preview-loading"
              >
                <div class="loading-dots">
                  <span></span>
                  <span></span>
                  <span></span>
                </div>
                <span class="loading-text">{{ task.status === 'pending' ? '排队中' : '生成中' }}</span>
              </div>
              <div
                v-else-if="
                  task.status === 'failed' || task.status === 'timeout'
                "
                class="preview-failed"
              >
                <div class="failed-icon">
                  <CloseOutlined />
                </div>
              </div>
              <div v-else class="preview-placeholder">
                <FileImageOutlined />
              </div>

              <!-- Status Badge -->
              <div class="status-badge" :class="`status-${task.status}`">
                {{ getStatusText(task.status) }}
              </div>
            </div>

            <!-- 悬停显示的底部信息 -->
            <div class="card-hover-info" @click.stop>
              <div class="hover-left">
                <img
                  v-if="task.inputType === 'image'"
                  :src="task.inputContent"
                  alt=""
                  class="input-thumb"
                />
                <span v-else class="input-desc">{{ task.inputContent }}</span>
              </div>
              <span class="hover-date">{{ formatDate(task.createTime) }}</span>
              <div class="hover-actions">
                <a-tooltip v-if="['failed', 'timeout'].includes(task.status)" title="重试" placement="top">
                  <button
                    class="action-btn"
                    :disabled="task.retryCount >= 3"
                    @click="handleRetry(task)"
                  >
                    <ReloadOutlined />
                  </button>
                </a-tooltip>
                <a-tooltip title="删除" placement="top">
                  <button
                    class="action-btn"
                    @click="handleDelete(task)"
                  >
                    <DeleteOutlined />
                  </button>
                </a-tooltip>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick } from "vue"
import { useRouter, useRoute } from "vue-router"
import { message, Modal } from "ant-design-vue"
import {
  ReloadOutlined,
  PictureOutlined,
  ThunderboltOutlined,
  LoadingOutlined,
  CloseOutlined,
  FileImageOutlined,
  EyeOutlined,
  DeleteOutlined,
  ArrowRightOutlined,
  ArrowLeftOutlined,
  BulbOutlined,
  FolderOutlined,
  SyncOutlined,
  EditOutlined,
  PlusOutlined,
  InfoCircleOutlined,
  AppstoreOutlined,
  QuestionCircleOutlined,
  CheckCircleFilled,
} from "@ant-design/icons-vue"
import {
  createAI3DTask,
  getAI3DTasks,
  getAI3DTask,
  retryAI3DTask,
  deleteAI3DTask,
  type AI3DTask,
} from "@/api/ai-3d"
import { uploadFile } from "@/api/upload"
import { useAuthStore } from "@/stores/auth"
import dayjs from "dayjs"

// 获取认证状态
const authStore = useAuthStore()
const router = useRouter()
const route = useRoute()

// 返回首页
const handleBack = () => {
  const tenantCode = route.params.tenantCode as string
  router.push(`/${tenantCode}`)
}

// 跳转到历史记录页面
const goToHistory = () => {
  const tenantCode = route.params.tenantCode as string
  router.push(`/${tenantCode}/workbench/3d-lab/history`)
}

// 输入类型选项
const inputTypeOptions = [
  { label: "文生3D", value: "text" },
  { label: "图生3D", value: "image" },
]

// 示例提示词
const samplePrompts = [
  ["啄木鸟", "尖锐的嘴", "金黄色"],
  ["可爱的猫咪", "卡通风格", "蓝色眼睛"],
  ["机器人", "金属质感", "未来风格"],
  ["中式花瓶", "青花瓷", "精致纹理"],
  ["小恐龙", "Q版造型", "绿色皮肤"],
  ["宇航员", "太空服", "写实风格"],
]

// 状态
const inputType = ref<"text" | "image">("text")
const textContent = ref("")
const imageUrl = ref("")
const generating = ref(false)
const currentSampleIndex = ref(0)

// 图片模式：单张/多张
const imageMode = ref<"single" | "multiple">("single")

// 多图上传相关
type MultiImageKey =
  | "top"
  | "left45"
  | "front"
  | "right45"
  | "left"
  | "right"
  | "back"
  | "bottom"
const multiImages = ref<Partial<Record<MultiImageKey, string>>>({})
const multiViewModalVisible = ref(false)
const multiImageInput = ref<HTMLInputElement | null>(null)
const currentUploadKey = ref<MultiImageKey | null>(null)

// 视图名称映射
const viewNameMap: Record<MultiImageKey, string> = {
  top: "顶图",
  left45: "左45°图",
  front: "正图",
  right45: "右45°图",
  left: "左图",
  right: "右图",
  back: "背图",
  bottom: "底图",
}

// 模型设置
const generateType = ref<"Normal" | "LowPoly" | "Geometry" | "Sketch">("Normal")
const faceCount = ref(500000)

// 页面加载状态
const pageLoading = ref(true)

// 历史记录
const historyList = ref<AI3DTask[]>([])
const historyLoading = ref(false)
const allHistoryTotal = ref(0)

// 历史网格容器引用和宽度
const historyGridRef = ref<HTMLElement | null>(null)
const historyGridWidth = ref(0)

// 轮询定时器
let pollingTimer: number | null = null
// ResizeObserver 用于监听容器宽度变化
let resizeObserver: ResizeObserver | null = null

// 计算属性
const currentSamples = computed(() => samplePrompts[currentSampleIndex.value])

// 是否有多图上传
const hasMultiImages = computed(() => {
  return Object.keys(multiImages.value).length > 0
})

const canGenerate = computed(() => {
  // 首先检查用户是否有创建权限
  if (!authStore.hasPermission("ai-3d:create")) {
    return false
  }

  // 检查输入内容是否有效
  if (inputType.value === "text") {
    return textContent.value.trim().length > 0
  } else {
    // 图生3D模式
    if (imageMode.value === "single") {
      return imageUrl.value.length > 0
    } else {
      // 多图模式：至少需要正图
      return !!multiImages.value.front
    }
  }
})

// 计算一行最多能展示的卡片数量
// 卡片宽度 240px + 间距 20px = 260px
const maxCardsPerRow = computed(() => {
  if (historyGridWidth.value === 0) return 6 // 默认值
  const cardWidth = 240
  const gap = 20
  // 可用宽度 = 容器宽度 - 左右 padding (48px * 2)
  const availableWidth = historyGridWidth.value - 96
  // 计算能放多少个：可用宽度 / (卡片宽度 + 间距)
  const count = Math.floor(availableWidth / (cardWidth + gap))
  return Math.max(1, count) // 至少显示1个
})

// 限制显示的历史记录数量
const displayedHistoryList = computed(() => {
  return historyList.value.slice(0, maxCardsPerRow.value)
})

// 刷新示例
const refreshSamples = () => {
  currentSampleIndex.value =
    (currentSampleIndex.value + 1) % samplePrompts.length
}

// 应用示例
const applySample = (sample: string) => {
  if (textContent.value) {
    textContent.value += "，" + sample
  } else {
    textContent.value = sample
  }
}

// 聚焦输入
const focusInput = () => {
  // 滚动到左侧面板
}

// 图片上传前处理
const handleBeforeUpload = async (file: File) => {
  const isImage = file.type.startsWith("image/")
  if (!isImage) {
    message.error("只能上传图片文件")
    return false
  }

  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isLt10M) {
    message.error("图片大小不能超过 10MB")
    return false
  }

  // 上传图片
  try {
    const result: any = await uploadFile(file)
    // 兼容不同的响应格式
    const url = result.data?.url || result.url
    if (url) {
      imageUrl.value = url
      message.success("图片上传成功")
    } else {
      message.error("上传失败：无法获取图片地址")
    }
  } catch (error) {
    console.error("上传失败:", error)
    message.error("图片上传失败")
  }

  return false // 阻止默认上传行为
}

// 多图上传相关方法
const openMultiViewModal = () => {
  multiViewModalVisible.value = true
}

const getViewName = (key: string) => {
  return viewNameMap[key as MultiImageKey] || key
}

const triggerUpload = (key: MultiImageKey) => {
  currentUploadKey.value = key
  multiImageInput.value?.click()
}

const handleMultiImageUpload = async (event: Event) => {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  if (!file || !currentUploadKey.value) return

  const isImage = file.type.startsWith("image/")
  if (!isImage) {
    message.error("只能上传图片文件")
    input.value = ""
    return
  }

  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isLt10M) {
    message.error("图片大小不能超过 10MB")
    input.value = ""
    return
  }

  try {
    const result: any = await uploadFile(file)
    const url = result.data?.url || result.url
    if (url) {
      multiImages.value[currentUploadKey.value] = url
      message.success(`${getViewName(currentUploadKey.value)}上传成功`)
    } else {
      message.error("上传失败：无法获取图片地址")
    }
  } catch (error) {
    console.error("上传失败:", error)
    message.error("图片上传失败")
  }

  input.value = ""
  currentUploadKey.value = null
}

const removeMultiImage = (key: string) => {
  delete multiImages.value[key as MultiImageKey]
}

// 生成3D模型
const handleGenerate = async () => {
  if (!canGenerate.value) return

  generating.value = true
  try {
    let content: string
    if (inputType.value === "text") {
      content = textContent.value.trim()
    } else if (imageMode.value === "single") {
      content = imageUrl.value
    } else {
      // 多张图片模式：使用正图作为主要输入
      content = multiImages.value.front || ""
    }

    // 构建请求参数
    const params: any = {
      inputType: inputType.value,
      inputContent: content,
      generateType: generateType.value,
    }

    // 文生3D时添加模型面数参数
    if (inputType.value === "text") {
      params.faceCount = faceCount.value
    }

    // 多张图片模式：添加额外的视图图片
    if (inputType.value === "image" && imageMode.value === "multiple") {
      const multiViewImages: Record<string, string> = {}
      Object.entries(multiImages.value).forEach(([key, url]) => {
        if (url) {
          multiViewImages[key] = url
        }
      })
      if (Object.keys(multiViewImages).length > 0) {
        params.multiViewImages = multiViewImages
      }
    }

    const task = await createAI3DTask(params)

    // 清空输入
    if (inputType.value === "text") {
      textContent.value = ""
    } else if (imageMode.value === "single") {
      imageUrl.value = ""
    } else {
      multiImages.value = {}
    }

    // 跳转到生成页面
    const taskData = task.data || task // 兼容不同的响应格式
    router.push({
      name: "AI3DGenerate",
      params: { taskId: taskData.id },
    })
  } catch (error: any) {
    message.error(error.response?.data?.message || "提交失败，请重试")
  } finally {
    generating.value = false
  }
}

// 获取历史记录（最近6条）
const fetchHistory = async () => {
  historyLoading.value = true
  try {
    const res = await getAI3DTasks({ page: 1, pageSize: 6 })
    const data = res.data || res // 兼容不同的响应格式
    historyList.value = data.list || []
    // 如果还没有获取过总数，则保存总数
    if (!allHistoryTotal.value && data.total) {
      allHistoryTotal.value = data.total
    }
  } catch (error) {
    console.error("获取历史记录失败:", error)
  } finally {
    historyLoading.value = false
  }
}

// 开始轮询（检查处理中的任务）
const startPolling = () => {
  if (pollingTimer) return

  pollingTimer = window.setInterval(async () => {
    const processingTasks = historyList.value.filter(
      (t) => t.status === "pending" || t.status === "processing",
    )

    if (processingTasks.length === 0) {
      stopPolling()
      return
    }

    // 刷新历史记录
    await fetchHistory()
  }, 3000)
}

// 停止轮询
const stopPolling = () => {
  if (pollingTimer) {
    clearInterval(pollingTimer)
    pollingTimer = null
  }
}

// 预览3D模型
const handlePreview = (task: AI3DTask) => {
  if (task.resultUrl || (task.resultUrls && task.resultUrls.length > 0)) {
    const tenantCode = route.params.tenantCode as string
    const urls = task.resultUrls || [task.resultUrl]

    // 存储到 sessionStorage（支持多模型）
    if (urls.length > 1) {
      sessionStorage.setItem("model-viewer-urls", JSON.stringify(urls))
      sessionStorage.setItem("model-viewer-index", "0")
      sessionStorage.removeItem("model-viewer-url")
    } else {
      sessionStorage.setItem("model-viewer-url", urls[0] || "")
      sessionStorage.removeItem("model-viewer-urls")
      sessionStorage.removeItem("model-viewer-index")
    }

    router.push({
      path: `/${tenantCode}/workbench/model-viewer`,
    })
  }
}

// 查看任务详情
const handleViewTask = (task: AI3DTask) => {
  // 跳转到生成页面查看详情
  router.push({
    name: "AI3DGenerate",
    params: { taskId: task.id },
  })
}

// 重试任务
const handleRetry = async (task: AI3DTask) => {
  if (task.retryCount >= 3) {
    message.warning("已达到最大重试次数，请创建新任务")
    return
  }

  try {
    await retryAI3DTask(task.id)
    message.success("重试已提交")
    fetchHistory()
    startPolling()
  } catch (error: any) {
    message.error(error.response?.data?.message || "重试失败")
  }
}

// 删除任务
const handleDelete = (task: AI3DTask) => {
  Modal.confirm({
    title: "确认删除",
    content: "确定要删除这条创作记录吗？",
    okText: "删除",
    okType: "danger",
    cancelText: "取消",
    async onOk() {
      try {
        await deleteAI3DTask(task.id)
        message.success("删除成功")
        fetchHistory()
      } catch (error) {
        message.error("删除失败")
      }
    },
  })
}

// 获取预览图URL
const getPreviewUrl = (task: AI3DTask) => {
  if (task.previewUrl) {
    // 自己的COS桶直接访问（已配置公有读）
    if (task.previewUrl.includes("competition-ms-1325825530.cos")) {
      return task.previewUrl
    }
    // 混元返回的临时链接通过代理访问（解决CORS问题）
    if (
      task.previewUrl.includes("tencentcos.cn") ||
      task.previewUrl.includes("qcloud.com")
    ) {
      return `/api/ai-3d/proxy-preview?url=${encodeURIComponent(task.previewUrl)}`
    }
    // 其他URL直接返回
    return task.previewUrl
  }
  return ""
}

// 获取状态文本
const getStatusText = (status: string) => {
  const texts: Record<string, string> = {
    pending: "排队中",
    processing: "生成中",
    completed: "已完成",
    failed: "失败",
    timeout: "超时",
  }
  return texts[status] || status
}

// 图片加载错误处理
const handleImageError = (event: Event) => {
  const img = event.target as HTMLImageElement
  console.error("预览图加载失败:", img.src)
  // 可以在这里添加错误提示或显示占位图
}

// 图片加载成功处理
const handleImageLoad = () => {
  // 图片加载成功，可以在这里做一些处理
  console.log("预览图加载成功")
}

// 格式化时间
const formatTime = (time: string) => {
  return dayjs(time).format("MM-DD HH:mm")
}

// 格式化日期（年月日）
const formatDate = (time: string) => {
  return dayjs(time).format("YYYY.MM.DD")
}

// 更新容器宽度
const updateGridWidth = () => {
  if (historyGridRef.value) {
    historyGridWidth.value = historyGridRef.value.offsetWidth
  }
}

// 页面加载
onMounted(async () => {
  try {
    await fetchHistory()
  } finally {
    // 确保页面加载状态关闭
    pageLoading.value = false
  }

  // 等待 DOM 更新后计算容器宽度
  await nextTick()
  updateGridWidth()

  // 监听容器宽度变化
  if (historyGridRef.value) {
    resizeObserver = new ResizeObserver(() => {
      updateGridWidth()
    })
    resizeObserver.observe(historyGridRef.value)
  }

  // 检查是否有处理中的任务，有则开启轮询
  const hasProcessing = historyList.value.some(
    (t) => t.status === "pending" || t.status === "processing",
  )
  if (hasProcessing) {
    startPolling()
  }
})

// 页面卸载
onUnmounted(() => {
  stopPolling()
  if (resizeObserver) {
    resizeObserver.disconnect()
    resizeObserver = null
  }
})
</script>

<style scoped lang="scss">
// ==========================================
// 蓝色主题色彩方案 - 统一色系
// ==========================================
// 主色调 - 蓝色系
$primary: #1890ff;
$primary-dark: #0958d9;
$primary-light: #40a9ff;
$secondary: #4096ff;
$accent: #40a9ff;
$success: #52c41a;
$warning: #faad14;
$error: #ff4d4f;

// 背景色
$background: #f5f5f5; // 浅灰背景（与系统统一）
$surface: #ffffff; // 白色卡片
$surface-light: #fafafa;

// 文字色
$text: rgba(0, 0, 0, 0.85); // 深色文字
$text-secondary: rgba(0, 0, 0, 0.65);
$text-muted: rgba(0, 0, 0, 0.45);
$text-light: #ffffff; // 深色区域的白色文字

// 渐变 - 与导航栏选中按钮一致
$gradient-primary: linear-gradient(135deg, $primary 0%, $primary-dark 100%);
$gradient-secondary: linear-gradient(135deg, $primary-light 0%, $primary 100%);

.ai-3d-container {
  display: flex;
  width: 100%;
  min-height: 100vh;
  background: $background;
  position: relative;
  overflow: hidden;
  align-items: stretch;
}

// 页面加载样式
.page-loading {
  position: fixed;
  inset: 0;
  background: $background;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;

  .loading-content {
    text-align: center;

    h3 {
      margin: 20px 0 8px;
      font-size: 20px;
      font-weight: 700;
      background: $gradient-primary;
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      background-clip: text;
    }

    p {
      margin: 0;
      font-size: 14px;
      color: $text-muted;
    }
  }

  .loading-logo {
    position: relative;
    width: 80px;
    height: 80px;
    margin: 0 auto;

    .logo-spinner {
      position: absolute;
      inset: 0;
      border: 3px solid rgba($primary, 0.1);
      border-top-color: $primary;
      border-radius: 50%;
      animation: spin 1s linear infinite;
    }

    .logo-icon-center {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      font-size: 32px;
      color: $primary;
    }
  }
}

// ==========================================
// 简化背景动画 - 保留微妙效果
// ==========================================
.bg-animation {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.bg-gradient {
  position: absolute;
  border-radius: 50%;
  filter: blur(100px);
  opacity: 0.15;
  animation: float 30s ease-in-out infinite;

  &.bg-gradient-1 {
    width: 600px;
    height: 600px;
    background: $primary;
    top: -200px;
    left: -100px;
  }

  &.bg-gradient-2 {
    width: 500px;
    height: 500px;
    background: $primary-light;
    bottom: -150px;
    right: -100px;
    animation-delay: -10s;
  }

  &.bg-gradient-3 {
    width: 400px;
    height: 400px;
    background: $secondary;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    animation-delay: -20s;
    opacity: 0.1;
  }
}

@keyframes float {
  0%,
  100% {
    transform: translate(0, 0) scale(1);
  }
  33% {
    transform: translate(30px, -30px) scale(1.05);
  }
  66% {
    transform: translate(-20px, 20px) scale(0.95);
  }
}

// ==========================================
// Left Panel - 浅色变体
// ==========================================
.left-panel {
  width: 380px;
  min-height: 100vh;
  background: rgba($surface, 0.5);
  backdrop-filter: blur(20px);
  display: flex;
  flex-direction: column;
  position: relative;
  z-index: 1;
  align-self: stretch;
  border-right: 1px solid rgba($primary, 0.1);
  box-shadow: 2px 0 12px rgba(0, 0, 0, 0.06);
}

.panel-logo {
  padding: 24px;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-shrink: 0;

  .back-btn {
    color: $text !important;
    width: 40px;
    height: 40px;
    border-radius: 10px !important;
    border: 1px solid rgba($primary, 0.3) !important;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s !important;
    flex-shrink: 0;

    &:hover {
      background: rgba($primary, 0.2) !important;
      border-color: $primary !important;
      transform: translateY(-1px);
    }
  }

  .logo-ring {
    position: relative;
    width: 56px;
    height: 56px;
    border: 2px solid transparent;
    border-radius: 50%;
    background:
      linear-gradient($surface, $surface) padding-box,
      $gradient-primary border-box;
    animation: rotateBorder 8s linear infinite;
  }

  .logo-icon {
    position: absolute;
    inset: 6px;
    background: $gradient-primary;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    color: white;
  }

  .logo-text {
    h3 {
      margin: 0;
      font-size: 18px;
      font-weight: 700;
      background: $gradient-primary;
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      background-clip: text;
    }

    p {
      margin: 4px 0 0;
      font-size: 12px;
      color: $text-muted;
    }
  }
}

@keyframes rotateBorder {
  to {
    transform: rotate(360deg);
  }
}

.panel-header {
  padding: 20px 24px;
  flex-shrink: 0;

  :deep(.ant-segmented) {
    background: rgba($surface-light, 0.6);
    border: 1px solid rgba($primary, 0.2);

    .ant-segmented-item {
      color: $text-muted;

      &-selected {
        background: $gradient-primary;
        color: #fff;
      }
    }
  }
}

.panel-content {
  flex: 1;
  padding: 24px;
  overflow-y: auto;
  min-height: 0;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: rgba($primary, 0.05);
  }

  &::-webkit-scrollbar-thumb {
    background: rgba($primary, 0.3);
    border-radius: 3px;

    &:hover {
      background: rgba($primary, 0.5);
    }
  }
}

.input-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: $text;
  margin-bottom: 8px;

  .label-icon {
    font-size: 16px;
    color: $primary;
  }
}

.input-hint {
  font-size: 13px;
  color: $text-muted;
  margin-bottom: 16px;
  line-height: 1.6;
}

.textarea-wrapper {
  position: relative;

  .char-count {
    position: absolute;
    bottom: 8px;
    right: 12px;
    font-size: 12px;
    color: $text-muted;
    pointer-events: none;
  }
}

.text-input {
  background: rgba($surface-light, 0.6) !important;
  border: 2px solid rgba($primary, 0.15) !important;
  border-radius: 12px;
  color: $text;
  resize: none;
  transition: all 0.3s;
  padding-bottom: 28px !important;

  &::placeholder {
    color: rgba($text-muted, 0.5);
  }

  &:hover {
    border-color: rgba($primary, 0.4) !important;
  }

  &:focus {
    border-color: $primary !important;
    box-shadow: 0 0 0 4px rgba($primary, 0.1) !important;
    background: rgba($surface-light, 0.8) !important;
  }
}

// 模型设置
.model-settings {
  margin-top: 16px;
  padding: 16px;
  background: rgba($primary, 0.05);
  border: 1px solid rgba($primary, 0.15);
  border-radius: 12px;

  .setting-row {
    display: flex;
    gap: 12px;
  }

  .setting-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;

    &.full-width {
      flex: none;
      width: 100%;
    }
  }

  .setting-label {
    font-size: 12px;
    font-weight: 500;
    color: $text-secondary;
  }

  .setting-select {
    width: 100%;

    :deep(.ant-select-selector) {
      background: rgba($surface, 0.8) !important;
      border: 1px solid rgba($primary, 0.2) !important;
      border-radius: 8px !important;
      height: 36px !important;

      .ant-select-selection-item {
        line-height: 34px !important;
        font-size: 13px;
      }
    }

    &:hover :deep(.ant-select-selector) {
      border-color: rgba($primary, 0.4) !important;
    }

    &.ant-select-focused :deep(.ant-select-selector) {
      border-color: $primary !important;
      box-shadow: 0 0 0 2px rgba($primary, 0.1) !important;
    }
  }
}

.sample-section {
  margin-top: 16px;
}

.sample-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;

  .sample-title {
    font-size: 13px;
    font-weight: 600;
    color: $text;
  }

  .refresh-icon {
    color: $text-muted;
    cursor: pointer;
    transition: all 0.3s;
    font-size: 14px;

    &:hover {
      color: $primary-light;
      transform: rotate(180deg);
    }
  }
}

.sample-prompts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;

  .sample-tag {
    padding: 6px 14px;
    background: rgba($primary, 0.1);
    border: 1px solid rgba($primary, 0.2);
    border-radius: 20px;
    font-size: 12px;
    color: $text;
    cursor: pointer;
    transition: all 0.3s;

    &:hover {
      background: rgba($primary-light, 0.2);
      border-color: $primary-light;
      transform: translateY(-2px);
    }
  }
}

// 单张/多张图片切换
.image-mode-switch {
  display: flex;
  gap: 16px;
  margin-bottom: 16px;
  align-items: center;

  .mode-link {
    font-size: 14px;
    color: $text-muted;
    cursor: pointer;
    transition: all 0.3s;
    position: relative;

    &:hover {
      color: $primary-light;
    }

    &.active {
      color: $primary;
      font-weight: 500;

      &::after {
        content: "";
        position: absolute;
        bottom: -4px;
        left: 0;
        right: 0;
        height: 2px;
        background: $primary;
        border-radius: 1px;
      }
    }
  }

  .image-tips-link {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    color: $text-muted;
    cursor: pointer;
    margin-left: auto;
    transition: color 0.3s;

    &:hover {
      color: $primary;
    }

    .anticon {
      font-size: 14px;
    }
  }
}

// 图片上传建议弹框样式
.image-tips-content {
  .tips-desc {
    font-size: 12px;
    color: $text-secondary;
    line-height: 1.6;
    margin-bottom: 16px;
  }

  .tips-example {
    display: flex;
    gap: 16px;

    img {
      width: 100px;
      height: 100px;
      border-radius: 8px;
      object-fit: cover;
      flex-shrink: 0;
      border: 1px solid rgba(0, 0, 0, 0.06);
    }

    .tips-list {
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: 8px;
    }

    .tip-item {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 13px;
      color: $text;

      .tip-icon {
        color: $success;
        font-size: 14px;
      }
    }
  }
}

.tips-title {
  font-weight: 600;
  color: $text;
}

// 多图容器
.multi-image-container {
  .thumbnail-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px;
    background: rgba($surface-light, 0.6);
    border: 2px dashed rgba($primary, 0.3);
    border-radius: 12px;
    min-height: 72px;
    cursor: pointer;
    transition: all 0.3s;
    overflow-x: auto;

    &:hover {
      border-color: $primary-light;
      background: rgba($surface-light, 0.8);
    }

    &::-webkit-scrollbar {
      height: 4px;
    }

    &::-webkit-scrollbar-track {
      background: rgba($primary, 0.05);
      border-radius: 2px;
    }

    &::-webkit-scrollbar-thumb {
      background: rgba($primary, 0.3);
      border-radius: 2px;
    }
  }

  .thumbnail-list {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
  }

  .thumbnail-item {
    position: relative;
    width: 48px;
    height: 48px;
    border-radius: 8px;
    overflow: hidden;
    flex-shrink: 0;

    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    .thumbnail-delete {
      position: absolute;
      top: 2px;
      right: 2px;
      width: 18px;
      height: 18px;
      background: rgba(0, 0, 0, 0.6);
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #fff;
      font-size: 10px;
      cursor: pointer;
      opacity: 0;
      transition: opacity 0.2s;
    }

    &:hover .thumbnail-delete {
      opacity: 1;
    }
  }

  .thumbnail-add {
    width: 48px;
    height: 48px;
    border: 2px dashed rgba($primary, 0.4);
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: $primary;
    font-size: 20px;
    flex-shrink: 0;
    transition: all 0.3s;

    &:hover {
      border-color: $primary;
      background: rgba($primary, 0.1);
    }
  }

  .upload-tip {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    font-size: 12px;
    color: $text-muted;

    .anticon {
      color: $primary-light;
    }
  }
}

// 多视图弹框
.multi-view-modal {
  :deep(.ant-modal-content) {
    background: $surface;
    border-radius: 16px;
  }

  :deep(.ant-modal-header) {
    background: transparent;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
    padding: 16px 24px;

    .ant-modal-title {
      font-size: 16px;
      font-weight: 600;
      color: $text;
    }
  }

  :deep(.ant-modal-body) {
    padding: 24px;
  }

  :deep(.ant-modal-close) {
    color: $text-muted;
  }
}

.multi-view-grid {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.view-row {
  display: flex;
  justify-content: center;
  gap: 12px;

  &.middle-row,
  &.center-row {
    width: 100%;
  }
}

.view-item {
  width: 100px;
  height: 100px;
  border: 2px dashed rgba($primary, 0.3);
  border-radius: 12px;
  cursor: pointer;
  transition: all 0.3s;
  position: relative;
  overflow: hidden;
  background: rgba($surface-light, 0.5);

  &:hover {
    border-color: $primary;
    background: rgba($primary, 0.05);
  }

  &.required {
    border-color: rgba($primary, 0.5);
  }

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .view-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    color: $text-muted;

    .anticon {
      font-size: 24px;
      color: $primary-light;
    }

    span {
      font-size: 11px;
      text-align: center;
    }

    .required-mark {
      color: #ff4d4f;
    }
  }

  .view-delete {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 22px;
    height: 22px;
    background: rgba(0, 0, 0, 0.6);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 12px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.2s;

    &:hover {
      background: rgba(255, 77, 79, 0.8);
    }
  }

  &:hover .view-delete {
    opacity: 1;
  }
}

.view-center {
  width: 120px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;

  .center-preview {
    width: 100%;
    height: 100%;
    border: 2px solid rgba($primary, 0.2);
    border-radius: 12px;
    overflow: hidden;
    background: linear-gradient(
      135deg,
      rgba($primary, 0.05) 0%,
      rgba($primary, 0.1) 100%
    );

    img {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }

    .center-placeholder {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 6px;
      color: $text-muted;

      .anticon {
        font-size: 28px;
        color: $primary-light;
      }

      span {
        font-size: 12px;
      }
    }
  }
}

.image-upload {
  :deep(.ant-upload-drag) {
    background: rgba($surface-light, 0.6) !important;
    border: 2px dashed rgba($primary, 0.3) !important;
    border-radius: 12px;
    transition: all 0.3s;
    overflow: hidden;

    &:hover {
      border-color: $primary-light !important;
      background: rgba($surface-light, 0.8) !important;
    }
  }

  :deep(.ant-upload) {
    padding: 24px !important;
  }

  :deep(.upload-icon) {
    color: $primary-light;
    font-size: 56px;
    margin-bottom: 12px;
  }

  :deep(.upload-text) {
    color: $text;
    font-size: 15px;
    margin-bottom: 8px;
  }

  :deep(.upload-hint) {
    color: $text-muted;
    font-size: 12px;
  }

  :deep(.upload-preview-image) {
    max-width: 100%;
    max-height: 180px;
    object-fit: contain;
    border-radius: 8px;
  }

  :deep(.upload-change-hint) {
    margin-top: 12px;
    font-size: 13px;
    color: $text-muted;
    transition: color 0.3s;
  }

  :deep(.ant-upload-drag:hover .upload-change-hint) {
    color: $primary-light;
  }
}

.panel-footer {
  padding: 24px;
  flex-shrink: 0;
}

.generate-btn {
  width: 100%;
  height: 56px;
  border: none;
  border-radius: 14px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  background: transparent;

  .btn-bg {
    position: absolute;
    inset: 0;
    background: $gradient-primary;
    transition: all 0.4s;
  }

  .btn-content {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    color: white;
    font-size: 16px;
    font-weight: 600;
  }

  .spin-icon {
    animation: spin 1s linear infinite;
  }

  &:hover:not(.is-disabled) {
    transform: translateY(-2px);
    box-shadow: 0 15px 35px rgba($primary, 0.4);

    .btn-bg {
      transform: scale(1.02);
    }
  }

  &:active:not(.is-disabled) {
    transform: translateY(0);
  }

  &.is-disabled {
    cursor: not-allowed;
    opacity: 0.5;
  }

  &.is-loading {
    .btn-bg {
      animation: gradientShift 2s ease infinite;
    }
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes gradientShift {
  0%,
  100% {
    background: $gradient-primary;
  }
  50% {
    background: $gradient-secondary;
  }
}

// ==========================================
// Right Panel
// ==========================================
.right-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  z-index: 1;
  height: 100vh;
  background: rgba($surface, 0.3);
  backdrop-filter: blur(20px);
  padding-top: 30px;
}

.intro-section {
  padding: 48px;
  flex-shrink: 0;
  text-align: center;
}

.intro-title {
  font-size: 36px;
  font-weight: 700;
  margin-bottom: 16px;
  line-height: 1.3;
  background: linear-gradient(
    135deg,
    $primary-dark 0%,
    $primary 35%,
    #8b5cf6 70%,
    #a855f7 100%
  );
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

@media (max-width: 900px) {
  .intro-title {
    font-size: 28px;
  }
}

.intro-desc {
  font-size: 16px;
  color: $text-muted;
  margin-bottom: 32px;
  line-height: 1.6;
  max-width: 500px;
  margin-left: auto;
  margin-right: auto;
}

.intro-features {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

.feature-card {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 20px;
  background: $surface-light;
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: 8px;
  transition: all 0.3s;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
}

.feature-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  color: #fff;
  flex-shrink: 0;

  &.gradient-1 {
    background: linear-gradient(135deg, $primary 0%, $primary-dark 100%);
  }
  &.gradient-2 {
    background: linear-gradient(
      135deg,
      $primary-dark 0%,
      darken($primary-dark, 10%) 100%
    );
  }
  &.gradient-3 {
    background: linear-gradient(135deg, $primary 0%, $primary-dark 100%);
  }
  &.gradient-4 {
    background: linear-gradient(135deg, $primary-dark 0%, $primary 100%);
  }
}

.feature-info {
  flex: 1;

  h3 {
    margin: 0 0 4px;
    font-size: 15px;
    font-weight: 600;
    color: $text;
  }

  p {
    margin: 0;
    font-size: 13px;
    color: $text-muted;
    line-height: 1.5;
  }
}

// ==========================================
// History Section
// ==========================================
.history-section {
  flex: 1;
  min-height: 0;
  padding: 32px 48px;
  overflow-y: auto;

  &::-webkit-scrollbar {
    width: 8px;
  }

  &::-webkit-scrollbar-track {
    background: rgba($primary, 0.05);
  }

  &::-webkit-scrollbar-thumb {
    background: rgba($primary, 0.3);
    border-radius: 4px;

    &:hover {
      background: rgba($primary, 0.5);
    }
  }
}

.history-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
}

.header-left {
  display: flex;
  align-items: baseline;
  gap: 12px;
}

.history-title {
  font-size: 24px;
  font-weight: 600;
  color: $text;
  margin: 0;
}

.history-count {
  font-size: 14px;
  color: $text-muted;
}

.view-all {
  display: flex;
  align-items: center;
  gap: 6px;
  color: $primary-light;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.3s;

  &:hover {
    color: $primary;
    transform: translateX(4px);
  }
}

.history-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 300px;
  gap: 16px;
  color: $text-muted;
}

.loading-spinner {
  position: relative;
  width: 60px;
  height: 60px;

  .spinner-ring {
    position: absolute;
    inset: 0;
    border: 2px solid transparent;
    border-radius: 50%;
    animation: spin 2s linear infinite;

    &:nth-child(1) {
      border-top-color: $primary;
      animation-duration: 1.5s;
    }

    &:nth-child(2) {
      border-right-color: $primary-light;
      animation-duration: 2s;
    }

    &:nth-child(3) {
      border-bottom-color: $accent;
      animation-duration: 2.5s;
    }
  }
}

.history-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 300px;
  gap: 12px;

  .empty-icon {
    width: 80px;
    height: 80px;
    background: rgba($primary, 0.1);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 32px;
    color: $primary-light;
    margin-bottom: 8px;
  }

  .empty-title {
    font-size: 16px;
    font-weight: 600;
    color: $text;
    margin: 0;
  }

  .empty-text {
    font-size: 14px;
    color: $text-muted;
    margin: 0;
  }
}

.history-grid {
  display: flex;
  flex-direction: row;
  gap: 24px;
  flex-wrap: nowrap;
  padding: 8px; // 为阴影留出空间
  margin: -8px; // 抵消padding对布局的影响
}

.history-card {
  flex-shrink: 0;
  width: 280px;
  background: $surface;
  border-radius: 16px;
  overflow: hidden;
  cursor: pointer;
  position: relative;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06), 0 1px 4px rgba(0, 0, 0, 0.04);
  transition: box-shadow 0.3s ease, transform 0.3s ease;

  &:hover {
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1), 0 4px 12px rgba(0, 0, 0, 0.06);
    transform: translateY(-4px);

    .card-preview .preview-image {
      transform: scale(1.05);
    }

    .card-hover-info {
      opacity: 1;
      transform: translateY(0);
    }
  }
}

.card-preview {
  height: 220px;
  background: linear-gradient(
    135deg,
    rgba($surface-light, 0.9) 0%,
    rgba($primary, 0.05) 100%
  );
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  border-radius: 16px;

  .preview-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  }

  .preview-loading,
  .preview-failed,
  .preview-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    color: $text-muted;
    font-size: 32px;

    .loading-text {
      font-size: 13px;
    }
  }

  .preview-failed {
    .failed-icon {
      width: 56px;
      height: 56px;
      background: linear-gradient(
        135deg,
        rgba($error, 0.15) 0%,
        rgba($error, 0.25) 100%
      );
      border: 2px solid rgba($error, 0.3);
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 24px;
      color: $error;
      animation: pulse-error 2s ease-in-out infinite;
    }
  }
}

@keyframes pulse-error {
  0%,
  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba($error, 0.3);
  }
  50% {
    transform: scale(1.05);
    box-shadow: 0 0 20px 5px rgba($error, 0.15);
  }
}

.loading-dots {
  display: flex;
  gap: 6px;

  span {
    width: 8px;
    height: 8px;
    background: $primary-light;
    border-radius: 50%;
    animation: dotPulse 1.4s ease-in-out infinite;

    &:nth-child(1) {
      animation-delay: 0s;
    }
    &:nth-child(2) {
      animation-delay: 0.2s;
    }
    &:nth-child(3) {
      animation-delay: 0.4s;
    }
  }
}

@keyframes dotPulse {
  0%,
  60%,
  100% {
    transform: scale(1);
    opacity: 1;
  }
  30% {
    transform: scale(1.5);
    opacity: 0.7;
  }
}

.status-badge {
  position: absolute;
  top: 12px;
  right: 12px;
  padding: 4px 12px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 600;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);

  &.status-completed {
    background: rgba($success, 0.2);
    color: $success;
    border-color: rgba($success, 0.3);
  }

  &.status-processing,
  &.status-pending {
    background: rgba($primary-light, 0.2);
    color: $primary-light;
    border-color: rgba($primary-light, 0.3);
  }

  &.status-failed,
  &.status-timeout {
    background: rgba($error, 0.2);
    color: $error;
    border-color: rgba($error, 0.3);
  }
}

// 悬停显示的底部信息
.card-hover-info {
  position: absolute;
  bottom: 8px;
  left: 8px;
  right: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(12px);
  border-radius: 12px;
  opacity: 0;
  transform: translateY(10px);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);

  .hover-left {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;

    .input-thumb {
      width: 36px;
      height: 36px;
      object-fit: cover;
      border-radius: 6px;
      border: 1px solid rgba(255, 255, 255, 0.2);
    }

    .input-desc {
      font-size: 13px;
      color: rgba(255, 255, 255, 0.95);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 100px;
    }
  }

  .hover-date {
    font-size: 12px;
    color: rgba(255, 255, 255, 0.6);
    white-space: nowrap;
  }

  .hover-actions {
    display: flex;
    align-items: center;
    gap: 6px;

    .action-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 32px;
      height: 32px;
      border: none;
      border-radius: 8px;
      background: rgba(255, 255, 255, 0.12);
      color: rgba(255, 255, 255, 0.85);
      cursor: pointer;
      transition: all 0.2s;
      font-size: 14px;

      &:hover {
        background: rgba(255, 255, 255, 0.25);
        color: #fff;
      }

      &:disabled {
        opacity: 0.4;
        cursor: not-allowed;
      }
    }
  }
}

// ==========================================
// Responsive
// ==========================================
@media (max-width: 1024px) {
  .left-panel {
    width: 100%;
  }

  .intro-features {
    grid-template-columns: 1fr;
  }

  .history-card {
    width: 240px;

    .card-preview {
      height: 200px;
    }
  }
}

@media (max-width: 768px) {
  .ai-3d-container {
    flex-direction: column;
  }

  .left-panel {
    width: 100%;
  }

  .intro-section {
    padding: 32px 24px;
  }

  .history-section {
    padding: 24px;
  }

  .history-card {
    width: 220px;

    .card-preview {
      height: 180px;
    }

    .card-hover-info {
      bottom: 6px;
      left: 6px;
      right: 6px;
      padding: 10px 12px;
      border-radius: 10px;

      .hover-left {
        .input-thumb {
          width: 30px;
          height: 30px;
        }

        .input-desc {
          font-size: 12px;
          max-width: 80px;
        }
      }

      .hover-date {
        font-size: 11px;
      }

      .hover-actions .action-btn {
        width: 28px;
        height: 28px;
      }
    }
  }
}
</style>

<!-- 全局样式 - 用于 Popover 等渲染到 body 的组件 -->
<style lang="scss">
// 图片上传建议 Popover 全局样式
.image-tips-popover {
  .ant-popover-inner {
    border-radius: 12px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
  }

  .ant-popover-title {
    padding: 12px 16px;
    border-bottom: 1px solid #f0f0f0;
    font-weight: 600;
  }

  .ant-popover-inner-content {
    padding: 16px;
  }

  .image-tips-content {
    .tips-desc {
      font-size: 12px;
      color: rgba(0, 0, 0, 0.65);
      line-height: 1.6;
      margin-bottom: 16px;
    }

    .tips-example {
      display: flex;
      gap: 16px;

      img {
        width: 100px;
        height: 100px;
        border-radius: 8px;
        object-fit: cover;
        flex-shrink: 0;
        border: 1px solid rgba(0, 0, 0, 0.06);
      }

      .tips-list {
        flex: 1;
        display: flex;
        flex-direction: column;
        gap: 8px;
      }

      .tip-item {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 13px;
        color: rgba(0, 0, 0, 0.85);

        .tip-icon {
          color: #52c41a;
          font-size: 14px;
        }
      }
    }
  }
}
</style>
