<template>
  <div class="history-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">创作历史</span>
        <span class="count-badge">{{ total }} 个作品</span>
      </div>
      <div class="header-right">
        <a-select
          v-model:value="statusFilter"
          placeholder="全部状态"
          style="width: 120px"
          allowClear
          @change="handleFilterChange"
        >
          <a-select-option value="">全部</a-select-option>
          <a-select-option value="completed">已完成</a-select-option>
          <a-select-option value="processing">生成中</a-select-option>
          <a-select-option value="pending">排队中</a-select-option>
          <a-select-option value="failed">失败</a-select-option>
          <a-select-option value="timeout">超时</a-select-option>
        </a-select>
      </div>
    </div>

    <!-- Content -->
    <div class="page-content">
      <!-- Loading -->
      <div v-if="loading && list.length === 0" class="loading-state">
        <div class="loader">
          <div class="loader-ring"></div>
          <div class="loader-ring"></div>
          <div class="loader-ring"></div>
        </div>
        <p>加载中...</p>
      </div>

      <!-- Empty -->
      <div v-else-if="list.length === 0" class="empty-state">
        <div class="empty-icon">
          <FileImageOutlined />
        </div>
        <p class="empty-title">暂无创作记录</p>
        <p class="empty-text">开始你的第一次 3D 创作之旅吧</p>
        <a-button type="primary" class="primary-btn" @click="goCreate">
          <ThunderboltOutlined />
          开始创作
        </a-button>
      </div>

      <!-- Grid -->
      <div v-else class="history-grid">
        <div
          v-for="task in list"
          :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"
            />
            <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>

      <!-- Pagination -->
      <div v-if="total > pageSize" class="pagination-wrapper">
        <a-pagination
          v-model:current="currentPage"
          :total="total"
          :page-size="pageSize"
          :show-size-changer="false"
          show-quick-jumper
          @change="handlePageChange"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue"
import { useRouter, useRoute } from "vue-router"
import { message, Modal } from "ant-design-vue"
import {
  ArrowLeftOutlined,
  FileImageOutlined,
  CloseOutlined,
  ReloadOutlined,
  DeleteOutlined,
  ThunderboltOutlined,
} from "@ant-design/icons-vue"
import {
  getAI3DTasks,
  retryAI3DTask,
  deleteAI3DTask,
  type AI3DTask,
  type AI3DTaskStatus,
} from "@/api/ai-3d"
import dayjs from "dayjs"

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

// 状态
const loading = ref(false)
const list = ref<AI3DTask[]>([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(12)
const statusFilter = ref<AI3DTaskStatus | "">("")

// 轮询定时器
let pollingTimer: number | null = null

// 返回上一页
const handleBack = () => {
  router.back()
}

// 去创建页
const goCreate = () => {
  const tenantCode = route.params.tenantCode as string
  router.push(`/${tenantCode}/workbench/3d-lab`)
}

// 获取列表
const fetchList = async () => {
  loading.value = true
  try {
    const params: any = {
      page: currentPage.value,
      pageSize: pageSize.value,
    }
    if (statusFilter.value) {
      params.status = statusFilter.value
    }
    const res = await getAI3DTasks(params)
    const data = res.data || res
    list.value = data.list || []
    total.value = data.total || 0
  } catch (error) {
    console.error("获取历史记录失败:", error)
    message.error("获取历史记录失败")
  } finally {
    loading.value = false
  }
}

// 筛选变化
const handleFilterChange = () => {
  currentPage.value = 1
  fetchList()
}

// 分页变化
const handlePageChange = (page: number) => {
  currentPage.value = page
  fetchList()
}

// 获取预览图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)}`
    }
    return task.previewUrl
  }
  return ""
}

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

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

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

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

// 预览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 handleRetry = async (task: AI3DTask) => {
  if (task.retryCount >= 3) {
    message.warning("已达到最大重试次数，请创建新任务")
    return
  }
  try {
    await retryAI3DTask(task.id)
    message.success("重试已提交")
    fetchList()
    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("删除成功")
        fetchList()
      } catch (error) {
        message.error("删除失败")
      }
    },
  })
}

// 开始轮询
const startPolling = () => {
  if (pollingTimer) return
  pollingTimer = window.setInterval(async () => {
    const hasProcessing = list.value.some(
      (t) => t.status === "pending" || t.status === "processing"
    )
    if (!hasProcessing) {
      stopPolling()
      return
    }
    await fetchList()
  }, 3000)
}

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

onMounted(async () => {
  await fetchList()
  const hasProcessing = list.value.some(
    (t) => t.status === "pending" || t.status === "processing"
  )
  if (hasProcessing) {
    startPolling()
  }
})

onUnmounted(() => {
  stopPolling()
})
</script>

<style scoped lang="scss">
// ==========================================
// 项目统一设计变量 - 统一色系
// ==========================================
$primary: #1890ff;
$primary-dark: #0958d9;
$primary-light: #40a9ff;
$secondary: #4096ff;
$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);

$border: #d9d9d9;
$border-light: #e8e8e8;

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

.history-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 {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 64px;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  z-index: 10;
  background: transparent;
}

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

  .count-badge {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    background: rgba($primary, 0.1);
    border: 1px solid rgba($primary, 0.2);
    border-radius: 20px;
    color: $primary;
    font-size: 11px;
    font-weight: 600;
  }
}

.header-right {
  display: flex;
  gap: 8px;
}

// ==========================================
// Content
// ==========================================
.page-content {
  flex: 1;
  padding: 24px;
  padding-top: 88px;
  overflow-y: auto;
  position: relative;
  z-index: 1;
}

// ==========================================
// Loading State
// ==========================================
.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 400px;
  gap: 24px;
  color: $text-muted;

  .loader {
    position: relative;
    width: 60px;
    height: 60px;
  }

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

    &:nth-child(1) {
      border-top-color: $primary;
    }
    &:nth-child(2) {
      width: 45px;
      height: 45px;
      top: 7.5px;
      left: 7.5px;
      border-right-color: $primary-light;
      animation-direction: reverse;
    }
    &:nth-child(3) {
      width: 30px;
      height: 30px;
      top: 15px;
      left: 15px;
      border-bottom-color: $secondary;
    }
  }
}

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

// ==========================================
// Empty State
// ==========================================
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 400px;
  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: 18px;
    font-weight: 600;
    color: $text;
    margin: 0;
  }

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

.primary-btn {
  background: $gradient-primary !important;
  border: none !important;
  color: #fff !important;
  font-weight: 500 !important;
  height: 40px;
  padding: 0 24px;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease !important;

  &:hover {
    filter: brightness(1.1);
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba($primary, 0.3);
  }
}

// ==========================================
// History Grid
// ==========================================
.history-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 24px;
}

.history-card {
  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: 240px;
  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;

  .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: 10px 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;
    gap: 10px;

    .input-thumb {
      width: 36px;
      height: 36px;
      object-fit: cover;
      border-radius: 8px;
      border: 1px solid rgba(255, 255, 255, 0.15);
      flex-shrink: 0;
    }

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

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

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

    .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.15);
      color: rgba(255, 255, 255, 0.9);
      cursor: pointer;
      transition: all 0.2s;
      font-size: 14px;

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

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

// ==========================================
// Pagination
// ==========================================
.pagination-wrapper {
  display: flex;
  justify-content: center;
  margin-top: 32px;
  padding-bottom: 24px;
}

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

    .header-left {
      gap: 12px;
    }

    .title {
      font-size: 16px;
    }

    .count-badge {
      display: none;
    }
  }

  .page-content {
    padding: 16px;
    padding-top: 80px;
  }

  .history-grid {
    grid-template-columns: 1fr;
  }
}
</style>
