<template>
  <div class="generate-page">
    <!-- 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>

    <!-- Header -->
    <div class="page-header">
      <div class="header-left">
        <a-button type="text" class="back-btn" @click="handleBack">
          <template #icon><ArrowLeftOutlined /></template>
        </a-button>
        <span class="title">{{ pageTitle }}</span>
        <span class="live-badge">
          <span class="pulse-dot"></span>
          LIVE
        </span>
        <a-tag class="pbr-tag">PBR</a-tag>
      </div>
      <div class="header-right">
        <span
          class="status-text"
          v-if="task?.status === 'processing' || task?.status === 'pending'"
        >
          <LoadingOutlined class="spin-icon" />
          生成中...
        </span>
        <span
          class="status-text completed"
          v-else-if="task?.status === 'completed'"
        >
          <CheckCircleOutlined />
          已完成
        </span>
      </div>
    </div>

    <!-- Main Content -->
    <div class="page-content">
      <!-- Model Grid -->
      <div class="model-grid">
        <div
          v-for="(item, index) in modelCards"
          :key="index"
          class="model-card"
          :class="{
            'is-ready': item.status === 'completed',
            'is-selected': selectedIndex === index,
            'is-loading':
              item.status === 'pending' || item.status === 'processing',
          }"
          @click="handleCardClick(index)"
        >
          <!-- Card Index Badge -->
          <div class="card-index">{{ index + 1 }}</div>

          <!-- Loading State -->
          <template
            v-if="item.status === 'pending' || item.status === 'processing'"
          >
            <div class="card-loading">
              <div class="cube-container">
                <div class="cube">
                  <div class="cube-face front"></div>
                  <div class="cube-face back"></div>
                  <div class="cube-face right"></div>
                  <div class="cube-face left"></div>
                  <div class="cube-face top"></div>
                  <div class="cube-face bottom"></div>
                </div>
              </div>
              <div class="loading-info">
                <div class="loading-title">
                  {{ task?.status === "pending" ? "排队中" : "AI 生成中" }}
                </div>
                <div v-if="task?.status === 'pending'" class="loading-text">
                  <p>
                    队列位置:
                    <span class="highlight">{{ queueInfo.position }}</span>
                  </p>
                  <p>
                    预计时间:
                    <span class="highlight">{{
                      formatEstimatedTime(queueInfo.estimatedTime)
                    }}</span>
                  </p>
                </div>
                <div v-else class="loading-text">
                  <p>正在生成3D模型，请耐心等待...</p>
                </div>
                <div class="progress-bar">
                  <div class="progress-fill"></div>
                </div>
              </div>
            </div>
          </template>

          <!-- Completed State -->
          <template v-else-if="item.status === 'completed'">
            <div class="card-preview">
              <img :src="item.previewUrl" :alt="`预览图${index + 1}`" />
              <div class="preview-overlay">
                <div class="preview-icon">
                  <EyeOutlined />
                </div>
                <span class="preview-text">查看 3D 模型</span>
              </div>
              <div class="card-shine"></div>
            </div>
          </template>

          <!-- Failed State -->
          <template v-else-if="item.status === 'failed'">
            <div class="card-error">
              <div class="failed-icon">
                <CloseOutlined />
              </div>
            </div>
          </template>
        </div>
      </div>

      <!-- Input Display - 仅文生3D显示提示词 -->
      <div class="input-display" v-if="task?.inputType === 'text'">
        <div class="input-card">
          <div class="input-icon">
            <ThunderboltOutlined />
          </div>
          <div class="input-content">
            <span class="input-label">生成提示词</span>
            <span class="input-text">{{ task?.inputContent }}</span>
          </div>
        </div>
      </div>

      <!-- Tips -->
      <div class="tips-section">
        <div class="tip-item">
          <span class="tip-icon">1</span>
          <span>点击任意完成的卡片查看 3D 模型</span>
        </div>
        <div class="tip-item">
          <span class="tip-icon">2</span>
          <span>支持旋转、缩放、平移操作</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from "vue"
import { useRouter, useRoute } from "vue-router"
import { message } from "ant-design-vue"
import {
  ArrowLeftOutlined,
  EyeOutlined,
  CloseOutlined,
  LoadingOutlined,
  CheckCircleOutlined,
  ThunderboltOutlined,
} from "@ant-design/icons-vue"
import { getAI3DTask, type AI3DTask } from "@/api/ai-3d"

const router = useRouter()
const route = useRoute()

// Task data
const task = ref<AI3DTask | null>(null)
const loading = ref(true)
const selectedIndex = ref<number | null>(null)

// Polling timer
let pollingTimer: number | null = null

// 每个任务预估耗时（秒）
const ESTIMATED_TIME_PER_TASK = 180

// Queue info
const queueInfo = computed(() => {
  const position = task.value?.queuePosition || 0
  // 预估时间 = 队列位置 * 每个任务耗时
  const estimatedTime = position * ESTIMATED_TIME_PER_TASK
  return {
    position,
    estimatedTime,
  }
})

// 格式化预估时间
const formatEstimatedTime = (seconds: number) => {
  if (seconds <= 0) return "计算中..."
  if (seconds < 60) return `${seconds}秒`
  const minutes = Math.ceil(seconds / 60)
  return `约${minutes}分钟`
}

// Page title
const pageTitle = computed(() => {
  if (task.value?.inputType === "text") {
    return "文生3D"
  } else if (task.value?.inputType === "image") {
    return "图生3D"
  }
  return "3D生成"
})

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

// Model cards state - 根据 previewUrls 数量动态展示
const modelCards = computed(() => {
  if (!task.value) {
    // 加载中时显示1个加载卡片
    return [{ status: "pending", previewUrl: "" }]
  }

  const status = task.value.status
  const previewUrls = task.value.previewUrls || []
  const resultUrls = task.value.resultUrls || []

  // 如果是加载中状态且没有预览图，显示1个加载卡片
  if (
    (status === "pending" || status === "processing") &&
    previewUrls.length === 0
  ) {
    return [{ status: status, previewUrl: "" }]
  }

  // 如果是失败状态，显示1个失败卡片
  if (status === "failed" || status === "timeout") {
    return [{ status: "failed", previewUrl: "" }]
  }

  // 根据 previewUrls 数量生成卡片（至少1个）
  const cardCount = Math.max(previewUrls.length, resultUrls.length, 1)

  return Array(cardCount)
    .fill(null)
    .map((_, index) => {
      const originalPreviewUrl = previewUrls[index] || ""
      return {
        status: status,
        previewUrl: getPreviewUrl(originalPreviewUrl),
        originalPreviewUrl: originalPreviewUrl,
        resultUrl: resultUrls[index] || "",
      }
    })
})

// Back to previous page
const handleBack = () => {
  router.back()
}

// Card click handler
const handleCardClick = (index: number) => {
  const card = modelCards.value[index]

  if (card.status === "pending" || card.status === "processing") {
    message.info("模型生成中，请稍候...")
    return
  }

  if (card.status === "failed") {
    message.error("该模型生成失败")
    return
  }

  if (card.status === "completed" && card.resultUrl) {
    // 收集所有有效的模型URLs
    const allResultUrls = modelCards.value
      .filter((c) => c.status === "completed" && c.resultUrl)
      .map((c) => c.resultUrl)

    // 存储到 sessionStorage（避免URL过长）
    if (allResultUrls.length > 1) {
      sessionStorage.setItem("model-viewer-urls", JSON.stringify(allResultUrls))
      sessionStorage.setItem("model-viewer-index", String(index))
      // 清除单URL存储
      sessionStorage.removeItem("model-viewer-url")
    } else {
      sessionStorage.setItem("model-viewer-url", card.resultUrl)
      sessionStorage.removeItem("model-viewer-urls")
      sessionStorage.removeItem("model-viewer-index")
    }

    // Navigate to model viewer
    const tenantCode = route.params.tenantCode as string
    router.push({
      path: `/${tenantCode}/workbench/model-viewer`,
    })
  }
}

// Fetch task details
const fetchTask = async () => {
  const taskId = route.params.taskId as string
  if (!taskId) return

  try {
    const res = await getAI3DTask(Number(taskId))
    const taskData = res.data || res // 兼容不同的响应格式
    task.value = taskData as AI3DTask

    // Stop polling if task is complete or failed
    if (
      taskData.status === "completed" ||
      taskData.status === "failed" ||
      taskData.status === "timeout"
    ) {
      stopPolling()
    }
  } catch (error) {
    console.error("获取任务详情失败:", error)
    message.error("获取任务详情失败")
  } finally {
    loading.value = false
  }
}

// Start polling
const startPolling = () => {
  if (pollingTimer) return

  pollingTimer = window.setInterval(() => {
    fetchTask()
  }, 3000)
}

// Stop polling
const stopPolling = () => {
  if (pollingTimer) {
    clearInterval(pollingTimer)
    pollingTimer = null
  }
}

// Page mounted
onMounted(() => {
  fetchTask()
  startPolling()
})

// Page unmounted
onUnmounted(() => {
  stopPolling()
})
</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);

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

.generate-page {
  min-height: 100vh;
  background: $background;
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
}

// ==========================================
// Animated Background
// ==========================================
.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);
  }
}

// ==========================================
// Header
// ==========================================
.page-header {
  height: 64px;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  position: relative;
  z-index: 10;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 16px;

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

  .title {
    font-size: 20px;
    font-weight: 600;
    background: $gradient-primary;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }

  .live-badge {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    background: rgba($success, 0.1);
    border: 1px solid rgba($success, 0.3);
    border-radius: 20px;
    color: $success;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.5px;

    .pulse-dot {
      width: 6px;
      height: 6px;
      background: $success;
      border-radius: 50%;
      animation: pulse 1.5s ease-in-out infinite;
    }
  }

  .pbr-tag {
    background: rgba($primary, 0.1) !important;
    border: 1px solid rgba($primary, 0.2) !important;
    color: $primary !important;
    font-size: 11px;
    font-weight: 600;
    border-radius: 6px;
  }
}

.header-right {
  .status-text {
    display: flex;
    align-items: center;
    gap: 8px;
    color: $primary;
    font-size: 14px;
    font-weight: 500;

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

    &.completed {
      color: $success;
    }
  }
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.5;
    transform: scale(0.8);
  }
}

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

// ==========================================
// Main Content
// ==========================================
.page-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px;
  overflow: auto;
  position: relative;
  z-index: 1;
}

// ==========================================
// Model Grid
// ==========================================
.model-grid {
  display: grid;
  grid-template-columns: repeat(2, 300px);
  gap: 24px;
  margin-bottom: 40px;
  justify-content: center;

  // 只有1个卡片时居中
  &:has(.model-card:only-child) {
    grid-template-columns: 300px;
  }
}

// ==========================================
// Model Card
// ==========================================
.model-card {
  width: 300px;
  height: 220px;
  background: $surface;
  border-radius: 16px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  border: 1px solid #e8e8e8;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  position: relative;

  &:hover {
    border-color: $primary;
    transform: translateY(-4px);
    box-shadow: 0 12px 24px rgba($primary, 0.15);
  }

  &.is-ready {
    &:hover {
      border-color: $primary;
      box-shadow: 0 12px 24px rgba($primary, 0.2);
    }
  }

  &.is-selected {
    border-color: $primary;
  }

  &.is-loading {
    .card-index {
      background: rgba($primary, 0.1);
    }
  }
}

// Card Index Badge
.card-index {
  position: absolute;
  top: 12px;
  left: 12px;
  width: 28px;
  height: 28px;
  background: rgba($primary, 0.1);
  border: 1px solid rgba($primary, 0.2);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: $primary;
  font-size: 12px;
  font-weight: 600;
  z-index: 5;
}

// ==========================================
// Loading State
// ==========================================
.card-loading {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: $gradient-card;
}

// 3D Cube Animation
.cube-container {
  width: 60px;
  height: 60px;
  perspective: 200px;
  margin-bottom: 20px;
}

.cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
  animation: rotateCube 4s linear infinite;
}

.cube-face {
  position: absolute;
  width: 40px;
  height: 40px;
  left: 50%;
  top: 50%;
  margin-left: -20px;
  margin-top: -20px;
  border: 2px solid rgba($primary, 0.3);
  background: rgba($primary, 0.05);

  &.front {
    transform: translateZ(20px);
    border-color: $primary;
  }
  &.back {
    transform: rotateY(180deg) translateZ(20px);
    border-color: $primary-light;
  }
  &.right {
    transform: rotateY(90deg) translateZ(20px);
    border-color: $secondary;
  }
  &.left {
    transform: rotateY(-90deg) translateZ(20px);
    border-color: $primary-light;
  }
  &.top {
    transform: rotateX(90deg) translateZ(20px);
    border-color: $primary;
  }
  &.bottom {
    transform: rotateX(-90deg) translateZ(20px);
    border-color: $secondary;
  }
}

@keyframes rotateCube {
  0% {
    transform: rotateX(-20deg) rotateY(0deg);
  }
  100% {
    transform: rotateX(-20deg) rotateY(360deg);
  }
}

.loading-info {
  text-align: center;

  .loading-title {
    color: $text;
    font-size: 16px;
    font-weight: 600;
    margin-bottom: 12px;
    background: $gradient-primary;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }

  .loading-text {
    color: $text-muted;
    font-size: 13px;
    line-height: 1.8;

    p {
      margin: 0;
    }

    .highlight {
      color: $primary;
      font-weight: 600;
    }
  }
}

.progress-bar {
  width: 200px;
  height: 4px;
  background: rgba($primary, 0.2);
  border-radius: 2px;
  margin-top: 16px;
  overflow: hidden;

  .progress-fill {
    height: 100%;
    width: 30%;
    background: $gradient-primary;
    border-radius: 2px;
    animation: progressPulse 2s ease-in-out infinite;
  }
}

@keyframes progressPulse {
  0% {
    width: 20%;
    opacity: 0.5;
  }
  50% {
    width: 80%;
    opacity: 1;
  }
  100% {
    width: 20%;
    opacity: 0.5;
  }
}

// ==========================================
// Preview State
// ==========================================
.card-preview {
  height: 100%;
  position: relative;
  overflow: hidden;

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s;
  }

  &:hover img {
    transform: scale(1.1);
  }

  .preview-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(
      180deg,
      transparent 0%,
      rgba(0, 0, 0, 0.6) 100%
    );
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.3s;

    .preview-icon {
      width: 56px;
      height: 56px;
      background: $gradient-primary;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 24px;
      color: #fff;
      margin-bottom: 12px;
      transform: scale(0.8);
      transition: transform 0.3s;
    }

    .preview-text {
      color: #fff;
      font-size: 14px;
      font-weight: 500;
    }
  }

  &:hover .preview-overlay {
    opacity: 1;

    .preview-icon {
      transform: scale(1);
    }
  }

  .card-shine {
    position: absolute;
    top: 0;
    left: -100%;
    width: 50%;
    height: 100%;
    background: linear-gradient(
      90deg,
      transparent,
      rgba(255, 255, 255, 0.1),
      transparent
    );
    transition: left 0.5s;
  }

  &:hover .card-shine {
    left: 150%;
  }
}

// ==========================================
// Error State
// ==========================================
.card-error {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba($error, 0.02);

  .failed-icon {
    width: 64px;
    height: 64px;
    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: 28px;
    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);
  }
}

// ==========================================
// Input Display
// ==========================================
.input-display {
  margin-bottom: 24px;
}

.input-card {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 24px;
  background: $surface;
  border: 1px solid #e8e8e8;
  border-radius: 16px;
  max-width: 600px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);

  .input-icon {
    width: 44px;
    height: 44px;
    background: $gradient-primary;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    color: #fff;
    flex-shrink: 0;
  }

  .input-content {
    display: flex;
    flex-direction: column;
    gap: 4px;

    .input-label {
      font-size: 12px;
      color: $text-muted;
      text-transform: uppercase;
      letter-spacing: 0.5px;
    }

    .input-text {
      font-size: 15px;
      color: $text;
      font-weight: 500;
    }
  }
}

// ==========================================
// Tips Section
// ==========================================
.tips-section {
  display: flex;
  gap: 24px;
}

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

  .tip-icon {
    width: 22px;
    height: 22px;
    background: rgba($primary, 0.1);
    border: 1px solid rgba($primary, 0.2);
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 600;
    color: $primary;
  }
}

// ==========================================
// Responsive
// ==========================================
@media (max-width: 1024px) {
  .page-content {
    padding: 24px;
  }

  .model-grid {
    grid-template-columns: repeat(2, 280px);
    gap: 20px;
  }

  .model-card {
    width: 280px;
    height: 200px;
  }
}

@media (max-width: 768px) {
  .page-header {
    padding: 0 16px;
  }

  .header-left {
    gap: 12px;

    .title {
      font-size: 16px;
    }

    .live-badge,
    .pbr-tag {
      display: none;
    }
  }

  .page-content {
    padding: 16px;
  }

  .model-grid {
    grid-template-columns: 1fr;
    gap: 16px;
  }

  .model-card {
    width: 100%;
    max-width: 320px;
    height: 180px;
  }

  .tips-section {
    flex-direction: column;
    gap: 12px;
  }

  .action-buttons {
    flex-direction: column;
    gap: 12px;

    .action-btn {
      width: 100%;
    }
  }
}
</style>
