<template>
  <div class="task-content-container">
    <div class="header">
      <div class="custom-select" v-click-outside="closeDropdown">
        <div class="select-trigger" @click="toggleDropdown">
          <span class="select-value">{{ currentLabel }}</span>
          <span v-if="statusFilter" class="clear-btn" @click.stop="clearSelection">
            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
              <path fill="currentColor" d="M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896zm0 393.664L407.936 353.6a38.4 38.4 0 1 0-54.336 54.336L457.664 512 353.6 616.064a38.4 38.4 0 1 0 54.336 54.336L512 566.336 616.064 670.4a38.4 38.4 0 1 0 54.336-54.336L566.336 512 670.4 407.936a38.4 38.4 0 1 0-54.336-54.336L512 457.664z"/>
            </svg>
          </span>
          <span class="arrow-icon" :class="{ 'is-reverse': dropdownVisible }">
            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
              <path fill="currentColor" d="M831.872 340.864 512 652.672 192.128 340.864a30.592 30.592 0 0 0-42.752 0 29.12 29.12 0 0 0 0 41.6L489.664 714.24a32 32 0 0 0 44.672 0l340.288-331.712a29.12 29.12 0 0 0 0-41.728 30.592 30.592 0 0 0-42.752 0z"/>
            </svg>
          </span>
        </div>
        <transition name="dropdown">
          <div v-show="dropdownVisible" class="select-dropdown">
            <div 
              class="select-option"
              :class="{ 'is-selected': statusFilter === '' }"
              @click="selectOption('', '全部')"
            >
              全部
            </div>
            <div 
              class="select-option"
              :class="{ 'is-selected': statusFilter === 'processing' }"
              @click="selectOption('processing', '处理中')"
            >
              处理中
            </div>
            <div 
              class="select-option"
              :class="{ 'is-selected': statusFilter === 'completed' }"
              @click="selectOption('completed', '已完成')"
            >
              已完成
            </div>
            <div 
              class="select-option"
              :class="{ 'is-selected': statusFilter === 'failed' }"
              @click="selectOption('failed', '失败')"
            >
              失败
            </div>
          </div>
        </transition>
      </div>
    </div>

    <div v-if="loading" class="state-container">
      <div class="spinner"></div>
      <p class="state-text">正在加载任务列表...</p>
    </div>

    <div v-else-if="error" class="state-container">
      <p class="state-text error">加载任务失败，请稍后重试。</p>
      <button @click="fetchTasks" class="retry-btn">重试</button>
    </div>

    <div v-else-if="filteredTasks.length === 0" class="state-container">
      <svg class="no-data-icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896z"></path><path d="M512 688a48 48 0 1 0 0-96 48 48 0 0 0 0 96zm0-160a48 48 0 1 0 0-96 48 48 0 0 0 0 96z"></path></svg>
      <p class="state-text">暂无任务</p>
      <p class="state-hint">在左侧开始创作你的第一张图片吧</p>
    </div>

    <div v-else class="task-list">
      <div v-for="task in filteredTasks" :key="task.taskNo" class="task-card">
        <div class="task-card-header">
          <svg class="task-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M16 16a4 4 0 1 0-8 0 4 4 0 0 0 8 0zM12 4v4m0 8v4m-8-8h4m8 0h4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
          <span class="task-type">{{ task.taskType === 'text_to_image' ? '文生图' : '图生图' }}</span>
          <span class="task-date">{{ formatTime(task.createTime) }}</span>
        </div>
        <div class="task-card-body">
          <p v-if="task.status !== 'failed' && task.status !== 'cancelled'" class="prompt">{{ task.promptSnippet }}</p>
          <div class="result-container">
            <div v-if="task.status === 'completed' && task.resultUrl" class="result-display">
              <!-- 生成的结果图 -->
              <div class="image-wrapper">
                <el-image 
                  :src="task.resultUrl" 
                  :preview-src-list="[task.resultUrl]"
                  class="result-image" 
                  fit="cover"
                  :preview-teleported="true"
                >
                  <template #error>
                    <div class="image-error">
                      <span>加载失败</span>
                    </div>
                  </template>
                </el-image>
                <!-- 水印层 -->
                <div class="image-watermark">1818AI生成</div>
                <ImageHoverToolbar
                  :image-url="task.resultUrl"
                  :task-no="task.taskNo"
                  @download="handleDownload"
                  @share="handleShare"
                  @image-to-video="handleImageToVideo"
                  @delete="handleDelete"
                />
              </div>
              
              <!-- 参考图 - 图生图模式显示 -->
              <div v-if="task.taskType === 'image_to_image' && (task.referenceImageUrl || task.imageUrl)" 
                   class="reference-image-wrapper">
                <div class="image-label">参考图</div>
                <el-image 
                  :src="task.referenceImageUrl || task.imageUrl" 
                  :preview-src-list="[task.referenceImageUrl || task.imageUrl]"
                  class="reference-image" 
                  fit="cover"
                  :preview-teleported="true"
                >
                  <template #error>
                    <div class="image-error-small">
                      <span>加载失败</span>
                    </div>
                  </template>
                </el-image>
              </div>
            </div>
            <div v-else-if="task.status === 'pending' || task.status === 'processing'" class="processing-wrapper">
              <div class="progress-text">
                <span class="text-content rotating-text">
                  <span class="text-item">AI正在创作中</span>
                  <span class="text-item">正在生成精彩内容</span>
                  <span class="text-item">马上就好</span>
                  <span class="text-item">创意正在路上</span>
                </span>
                <span class="dots">
                  <span class="dot">.</span>
                  <span class="dot">.</span>
                  <span class="dot">.</span>
                </span>
              </div>
            </div>
            <div v-else-if="task.status === 'failed' || task.status === 'cancelled'" class="failed-wrapper">
              <p class="failed-text">{{ task.status === 'failed' ? '生成失败' : '任务已取消' }}</p>
              <p v-if="task.errorMessage" class="error-msg">{{ task.errorMessage }}</p>
            </div>
          </div>
        </div>
        <div class="task-card-footer">
          <button v-if="task.status === 'completed' || task.status === 'failed' || task.status === 'cancelled'" @click="handleRemake(task)" class="remake-btn">
            {{ task.status === 'completed' ? '做同款' : '重新提交' }}
          </button>
           <!-- 删除按钮 -->
          <button 
            @click="handleDelete(task)" 
            class="delete-btn"
          >
          <svg viewBox="0 0 13 14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="13.000000" height="14.000000" fill="none" customFrame="#000000">
    <path id="矢量 13" d="M12.35 2.54546L11.7 2.54546L11.7 12.7273C11.7 13.4302 11.118 14 10.4 14L2.60001 14C1.88201 14 1.3 13.4302 1.3 12.7273L1.3 2.54546L0.650002 2.54546C0.291006 2.54546 0 2.26056 0 1.9091C0 1.55763 0.291006 1.27273 0.650002 1.27273L4.55 1.27273C4.55 0.569802 5.13201 0 5.85 0L7.15 0C7.86799 0 8.45001 0.569802 8.45001 1.27273L12.35 1.27273C12.709 1.27273 13 1.55763 13 1.9091C13 2.26056 12.709 2.54546 12.35 2.54546ZM10.4 2.54546L2.60001 2.54546L2.60001 12.7273L10.4 12.7273L10.4 2.54546ZM5.20001 3.81819C5.55901 3.81819 5.85001 4.1031 5.85001 4.45456L5.85001 10.8182C5.85001 11.1697 5.55901 11.4546 5.20001 11.4546C4.84102 11.4546 4.55001 11.1697 4.55001 10.8182L4.55001 4.45456C4.55001 4.1031 4.84102 3.81819 5.20001 3.81819ZM7.8 3.81819C8.159 3.81819 8.45 4.1031 8.45 4.45456L8.45 10.8182C8.45 11.1697 8.159 11.4546 7.8 11.4546C7.44101 11.4546 7.15 11.1697 7.15 10.8182L7.15 4.45456C7.15 4.1031 7.44101 3.81819 7.8 3.81819Z" fill="rgb(255,0,0)" fill-rule="nonzero"/>
</svg>

            删除
          </button>
          
          <!-- 发布按钮 -->
          <button 
            v-if="task.status === 'completed' && !task.isPublished" 
            @click="openPublishDialog(task)" 
            class="publish-btn"
          >
            <svg viewBox="0 0 24 24" fill="currentColor" class="publish-icon">
              <path d="M5 12h14M12 5l7 7-7 7"/>
            </svg>
            发布
          </button>
          
          <!-- 已发布状态 -->
          <span v-if="task.isPublished && task.publishStatus === 'published'" class="published-badge">
            <svg viewBox="0 0 24 24" fill="currentColor" class="badge-icon">
              <path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
            </svg>
            已发布
          </span>
          
          <!-- 审核中状态 -->
          <span v-if="task.isPublished && task.publishStatus === 'pending'" class="pending-badge">
            <svg viewBox="0 0 24 24" fill="currentColor" class="badge-icon">
              <path d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
            </svg>
            审核中
          </span>
          
        </div>
      </div>
    </div>
    
    <div v-if="!loading && pagination.total > pagination.pageSize" class="pagination-container">
      <el-pagination
        background
        layout="prev, pager, next"
        :total="pagination.total"
        :page-size="pagination.pageSize"
        :current-page="pagination.pageNum"
        @current-change="handlePageChange"
      />
    </div>

  </div>

  <!-- 发布对话框 - 自定义 -->
  <Teleport to="body">
    <transition name="modal">
      <div v-if="publishDialogVisible" class="publish-modal" @click="closePublishDialog">
        <div class="publish-modal-content" @click.stop>
          <!-- 标题栏 -->
          <div class="publish-modal-header">
            <h3 class="publish-modal-title">发布作品到广场</h3>
            <button class="publish-close-btn" @click="closePublishDialog">
              X
            </button>
          </div>
          
          <!-- 表单内容 -->
          <div class="publish-modal-body">
            <div class="publish-form">
              <div class="form-item">
                <label class="form-label">作品标题 <span class="required">*</span></label>
                <div class="input-wrapper">
                  <input
                    v-model="publishForm.title"
                    type="text"
                    placeholder="请输入作品标题"
                    maxlength="50"
                    class="custom-input"
                  />
                  <span class="char-count">{{ publishForm.title.length }} / 50</span>
                </div>
              </div>
              
              <div class="form-item">
                <label class="form-label">作品描述 <span class="required">*</span></label>
                <div class="textarea-wrapper">
                  <textarea
                    v-model="publishForm.description"
                    placeholder="请描述你的作品"
                    maxlength="200"
                    rows="4"
                    class="custom-textarea"
                  ></textarea>
                  <span class="char-count">{{ publishForm.description.length }} / 200</span>
                </div>
              </div>
              
              <div class="form-item">
                <label class="form-label">作品标签 <span class="required">*</span></label>
                <div class="tags-container">
                  <span
                    v-for="(tag, index) in publishForm.tags"
                    :key="index"
                    class="tag-item"
                  >
                    {{ tag }}
                    <button class="tag-close" @click="removeTag(index)">×</button>
                  </span>
                  <input
                    v-if="publishForm.tags.length < 5"
                    v-model="currentTagInput"
                    type="text"
                    placeholder="输入标签后回车"
                    @keyup.enter="addTag"
                    class="tag-input"
                    maxlength="10"
                  />
                </div>
                <div class="form-hint">最多添加5个标签，每个标签不超过10个字</div>
              </div>
            </div>
          </div>
          
          <!-- 底部按钮 -->
          <div class="publish-modal-footer">
            <button @click="closePublishDialog" class="cancel-btn">取消</button>
            <button @click="handlePublish" :disabled="publishLoading" class="confirm-btn">
              <span v-if="publishLoading">发布中...</span>
              <span v-else>确认发布</span>
            </button>
          </div>
        </div>
      </div>
    </transition>
  </Teleport>
</template>

<script setup>
import { ref, onMounted, computed, onUnmounted, watch } from 'vue';
import { useRouter } from 'vue-router';
import { getAITaskList, publishWork, deleteAITask } from '../../api';
import { ElMessage, ElPagination, ElMessageBox, ElImage } from 'element-plus';
import ImageHoverToolbar from '../ImageHoverToolbar.vue';

const props = defineProps({
  refreshTrigger: {
    type: Number,
    default: 0
  },
  taskType: {
    type: String,
    default: 'image_to_image' // 默认图生图
  }
});

const emit = defineEmits(['remake']);
const router = useRouter();

const tasks = ref([]);
const loading = ref(true);
const error = ref(null);
let fallbackPollingTimer = null;

const statusFilter = ref('');
const dropdownVisible = ref(false);
const currentLabel = ref('状态筛选');

const pagination = ref({
  pageNum: 1,
  pageSize: 10,
  total: 0,
});



// 发布相关状态
const publishDialogVisible = ref(false);
const publishForm = ref({
  taskNo: '',
  title: '',
  description: '',
  tags: [],
  isPublic: true
});
const currentTagInput = ref('');
const publishLoading = ref(false);

const filteredTasks = computed(() => tasks.value);

const toggleDropdown = () => { dropdownVisible.value = !dropdownVisible.value; };
const closeDropdown = () => { dropdownVisible.value = false; };

const selectOption = (value, label) => {
  statusFilter.value = value;
  currentLabel.value = value ? label : '状态筛选';
  dropdownVisible.value = false;
};



const clearSelection = () => {
  statusFilter.value = '';
  currentLabel.value = '状态筛选';
};

const vClickOutside = {
  mounted(el, binding) {
    el.clickOutsideEvent = (event) => {
      if (!(el === event.target || el.contains(event.target))) {
        binding.value();
      }
    };
    document.addEventListener('click', el.clickOutsideEvent);
  },
  unmounted(el) {
    document.removeEventListener('click', el.clickOutsideEvent);
  }
};

const stopFallbackPolling = () => {
  if (fallbackPollingTimer) {
    clearInterval(fallbackPollingTimer);
    fallbackPollingTimer = null;
  }
};

const startFallbackPolling = () => {
  stopFallbackPolling();
  fallbackPollingTimer = setInterval(() => {
    const hasProcessingTasks = tasks.value.some(
      task => task.status === 'pending' || task.status === 'processing'
    );
    if (hasProcessingTasks && document.visibilityState === 'visible') {
      fetchTasks(true);
    } else if (!hasProcessingTasks) {
      stopFallbackPolling();
    }
  }, 20 * 1000); // Poll every 20 seconds for images
};

const fetchTasks = async (background = false) => {
  if (!background) loading.value = true;
  error.value = null;
  try {
    const params = {
      page: pagination.value.pageNum,
      size: pagination.value.pageSize,
      taskType: props.taskType, // 使用传入的任务类型
    };
    if (statusFilter.value) {
      params.status = statusFilter.value;
    }
    const response = await getAITaskList(params);
    if (response.code === 200 && response.data) {
      tasks.value = response.data.list || [];
      pagination.value.total = response.data.total || 0;
      
      const hasProcessingTasks = (response.data.list || []).some(
        task => task.status === 'pending' || task.status === 'processing'
      );
      if (hasProcessingTasks) {
        startFallbackPolling();
      } else {
        stopFallbackPolling();
      }

    } else {
      throw new Error(response.message || 'Failed to fetch tasks');
    }
  } catch (err) {
    error.value = err;
    ElMessage.error('获取任务列表失败');
  } finally {
    if (!background) loading.value = false;
  }
};

const handleRemake = (task) => {
  ElMessage.success('已将参数填充到左侧，请检查后点击生成按钮');
  emit('remake', {
      prompt: task.promptSnippet,
      referenceImageUrl: task.referenceImageUrl || task.imageUrl // some tasks might have imageUrl
  });
};

// 打开发布对话框
const openPublishDialog = (task) => {
  publishForm.value = {
    taskNo: task.taskNo,
    title: '',
    description: task.promptSnippet || '',
    tags: [],
    isPublic: true
  };
  publishDialogVisible.value = true;
  document.body.style.overflow = 'hidden'; // 禁止背景滚动
};

// 关闭发布对话框
const closePublishDialog = () => {
  publishDialogVisible.value = false;
  document.body.style.overflow = ''; // 恢复滚动
};

// 添加标签
const addTag = () => {
  const tag = currentTagInput.value.trim();
  if (!tag) {
    return;
  }
  if (publishForm.value.tags.length >= 5) {
    ElMessage.warning('最多添加5个标签');
    return;
  }
  if (publishForm.value.tags.includes(tag)) {
    ElMessage.warning('标签已存在');
    return;
  }
  publishForm.value.tags.push(tag);
  currentTagInput.value = '';
};

// 移除标签
const removeTag = (index) => {
  publishForm.value.tags.splice(index, 1);
};

// 发布作品
const handlePublish = async () => {
  // 验证表单
  if (!publishForm.value.title.trim()) {
    ElMessage.warning('请输入作品标题');
    return;
  }
  if (!publishForm.value.description.trim()) {
    ElMessage.warning('请输入作品描述');
    return;
  }
  if (publishForm.value.tags.length === 0) {
    ElMessage.warning('请至少添加一个标签');
    return;
  }
  
  publishLoading.value = true;
  try {
    const response = await publishWork({
      taskNo: publishForm.value.taskNo,
      title: publishForm.value.title.trim(),
      description: publishForm.value.description.trim(),
      tags: publishForm.value.tags,
      isPublic: publishForm.value.isPublic
    });
    
    if (response.code === 200) {
      ElMessage.success('发布成功！作品已提交审核');
      closePublishDialog();
      // 刷新列表
      fetchTasks(true);
    } else {
      throw new Error(response.message || '发布失败');
    }
  } catch (error) {
    console.error('发布失败:', error);
    ElMessage.error(error.message || '发布失败，请重试');
  } finally {
    publishLoading.value = false;
  }
};

const handlePageChange = (newPage) => {
  pagination.value.pageNum = newPage;
  fetchTasks();
};

// 工具栏操作处理
const handleDownload = async ({ imageUrl, taskNo, withWatermark }) => {
    try {
        if (!withWatermark) {
            // 无水印下载：直接下载原图
            ElMessage.info('正在准备下载（无水印）...');
            
            try {
                const response = await fetch(imageUrl, { mode: 'cors' });
                const blob = await response.blob();
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = `1818AI_image_${taskNo}_no_watermark.png`;
                document.body.appendChild(a);
                a.click();
                a.remove();
                URL.revokeObjectURL(url);
                ElMessage.success('开始下载图片（无水印）');
                return;
            } catch (fetchError) {
                console.warn('Fetch 下载失败，尝试备用方法:', fetchError);
            }
            
            const a = document.createElement('a');
            a.href = imageUrl;
            a.download = `1818AI_image_${taskNo}_no_watermark.png`;
            a.target = '_blank';
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            ElMessage.success('开始下载图片（无水印）');
        } else {
            // 带水印下载：使用 canvas 合成水印
            ElMessage.info('正在生成带水印图片，请稍候...');
            await downloadImageWithWatermark(imageUrl, taskNo);
        }
        
    } catch (error) {
        console.error('下载图片失败:', error);
        ElMessage.error('下载失败，请重试');
    }
};

// 使用 canvas 生成带水印的图片
const downloadImageWithWatermark = async (imageUrl, taskNo) => {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.crossOrigin = 'anonymous';
        img.onload = () => {
            try {
                const canvas = document.createElement('canvas');
                canvas.width = img.width;
                canvas.height = img.height;
                const ctx = canvas.getContext('2d');
                
                // 绘制原图
                ctx.drawImage(img, 0, 0);
                
                // 绘制水印
                ctx.save();
                ctx.font = `bold ${Math.max(24, canvas.width / 30)}px Arial`;
                ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
                ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)';
                ctx.lineWidth = 2;
                ctx.textAlign = 'left';
                ctx.textBaseline = 'top';
                
                const watermarkText = '1818AI生成';
                const padding = 20;
                ctx.strokeText(watermarkText, padding, padding);
                ctx.fillText(watermarkText, padding, padding);
                ctx.restore();
                
                // 下载
                canvas.toBlob((blob) => {
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = `1818AI_image_${taskNo}_watermark.png`;
                    document.body.appendChild(a);
                    a.click();
                    a.remove();
                    URL.revokeObjectURL(url);
                    ElMessage.success('带水印图片下载完成');
                    resolve();
                }, 'image/png');
            } catch (error) {
                reject(error);
            }
        };
        img.onerror = () => {
            reject(new Error('图片加载失败'));
        };
        img.src = imageUrl;
    });
};

const handleShare = async ({ imageUrl, taskNo }) => {
    try {
        // 构建分享链接 - 指向作品详情页
        const shareUrl = `${window.location.origin}/ai-application/work/${taskNo}`;
        
        // 直接复制链接到剪贴板
        await navigator.clipboard.writeText(shareUrl);
        ElMessage.success('作品链接已复制到剪贴板');
    } catch (error) {
        console.error('分享失败:', error);
        ElMessage.error('分享失败，请重试');
    }
};

const handleDelete = async ({ imageUrl, taskNo }) => {
    try {
        await ElMessageBox.confirm(
            '确定要删除这张图片吗？删除后将无法恢复。',
            '确认删除',
            {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }
        );
        
        // 调用删除 API
        const response = await deleteAITask(taskNo);
        if (response.code === 200) {
            ElMessage.success('删除成功');
            fetchTasks(true); // 刷新列表
        } else {
            throw new Error(response.message || '删除失败');
        }
    } catch (error) {
        if (error !== 'cancel') {
            console.error('删除失败:', error);
            ElMessage.error(error.message || '删除失败，请重试');
        }
    }
};

const handleImageToVideo = ({ imageUrl }) => {
  router.push({
    path: '/ai-application/create',
    query: {
      mode: 'image',
      imageUrl: imageUrl,
      prompt: '请根据参考图生成一段精彩的视频'
    }
  });
  ElMessage.success('已跳转到图生视频模式，并填充参数');
};

const formatTime = (time) => {
  if (!time) return '';
  const date = new Date(time);
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
  }).replaceAll('/', '-');
};

// 监听 taskType 变化，切换任务类型时重新加载任务列表
watch(() => props.taskType, () => {
  pagination.value.pageNum = 1; // 重置页码
  stopFallbackPolling(); // 停止旧的轮询
  fetchTasks();
});

watch(() => props.refreshTrigger, (newVal, oldVal) => {
  if (newVal !== oldVal && newVal > 0) {
    fetchTasks(true);
  }
});

watch(statusFilter, () => {
  pagination.value.pageNum = 1;
  fetchTasks();
});

onMounted(() => {
  fetchTasks();
});

onUnmounted(() => {
  stopFallbackPolling();
});
</script>

<style scoped>
.task-content-container {
  padding: 24px;
  background-color: #1F1F1F;
  color: #fff;
  height: 100%;
  width: 95%;
  box-sizing: border-box;
  overflow-y: auto;
  margin: 20px 20px;
}
.header {
  margin-bottom: 24px;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 16px;
}
.custom-select {
  position: relative;
  width: 150px;
}
.select-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 12px;
  background-color: #2a2a2a;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 4px;
  cursor: pointer;
}
.select-value { flex: 1; color: #e0e0e0; font-size: 14px; }
.clear-btn { display: flex; align-items: center; justify-content: center; width: 16px; height: 16px; color: #aaa; }
.clear-btn svg { width: 12px; height: 12px; }
.arrow-icon { display: flex; align-items: center; justify-content: center; width: 16px; height: 16px; color: #aaa; transition: transform 0.3s; }
.arrow-icon.is-reverse { transform: rotate(180deg); }
.select-dropdown { position: absolute; top: calc(100% + 4px); left: 0; right: 0; background-color: #2a2a2a; border: 1px solid rgba(255, 255, 255, 0.15); border-radius: 4px; z-index: 1000; }
.select-option { padding: 8px 12px; color: #d0d0d0; font-size: 14px; cursor: pointer; }
.select-option:hover { background-color: rgba(255, 255, 255, 0.08); }
.select-option.is-selected { color: #1AC3FF; background-color: rgba(26, 195, 255, 0.12); }
.task-list { display: flex; flex-direction: column; gap: 24px; }
.task-card { background-color: #1F1F1F; border-radius: 8px; padding: 10px; }
.task-card-header { display: flex; align-items: center; gap: 10px; color: #909090; font-size: 14px; margin-bottom: 8px; }
.task-icon { width: 20px; height: 20px; color: #666; }
.prompt { font-size: 14px; line-height: 1.6; margin-bottom: 12px; color: #e0e0e0; text-align: left; }
.result-container { margin-bottom: 12px; }
.result-display {
  display: flex;
  gap: 20px;
  align-items: flex-end;
}
.image-wrapper { 
  position: relative; 
  width: 100%;
  max-width: 400px;
  overflow: hidden;
  border-radius: 6px;
}
.image-wrapper:hover :deep(.image-hover-toolbar) {
  opacity: 1;
}

/* 图片水印 */
.image-watermark {
  position: absolute;
  top: 16px;
  left: 16px;
  color: rgba(255, 255, 255, 0.8);
  font-size: 16px;
  font-weight: bold;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8);
  pointer-events: none;
  z-index: 10;
  background: linear-gradient(135deg, rgba(26, 195, 255, 0.2), rgba(131, 58, 180, 0.2));
  padding: 6px 12px;
  border-radius: 4px;
  backdrop-filter: blur(4px);
}
:deep(.result-image), .result-image { 
  width: 100%; 
  border-radius: 6px; 
  display: block;
  aspect-ratio: 1 / 1;
  background: #2a2a2a;
}
.image-error, .image-error-small {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: #2a2a2a;
  color: #888;
  font-size: 14px;
}
.image-error { min-height: 200px; }
.image-error-small { height: 100%; font-size: 12px; }
.delete-icon {
  width: 16px;
  height: 16px;
}


/* 参考图样式 */
.reference-image-wrapper {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.image-label {
  font-size: 13px;
  color: #a0a0a0;
  margin-bottom: 8px;
  text-align: center;
}
:deep(.reference-image) {
  width: 120px;
  height: 120px;
  border-radius: 6px;
  object-fit: cover;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid rgba(255, 255, 255, 0.15);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
:deep(.reference-image:hover) {
  transform: scale(1.05);
  border-color: rgba(26, 195, 255, 0.5);
  box-shadow: 0 4px 16px rgba(26, 195, 255, 0.3);
}
.processing-wrapper { 
  position: relative;
  padding: 40px; 
  border-radius: 12px; 
  text-align: center; 
  width: 360px; 
  aspect-ratio: 1 / 1; 
  max-height: 360px; 
  display: flex; 
  flex-direction: column; 
  align-items: center; 
  justify-content: center;
  overflow: hidden;
  background: linear-gradient(135deg, #1a1a2e 0%, #2d1b4e 100%);
  box-shadow: 0 0 60px rgba(105, 234, 203, 0.4);
  border: none;
}

/* 流动渐变光斑效果 - 第一层 */
.processing-wrapper::before {
  content: '';
  position: absolute;
  top: -30%;
  left: -30%;
  width: 150%;
  height: 150%;
  background: radial-gradient(circle, 
    rgba(105, 234, 203, 0.9) 0%, 
    rgba(234, 204, 248, 0.8) 40%, 
    rgba(102, 84, 241, 0.7) 70%,
    transparent 100%);
  animation: flowingGradient 6s ease-in-out infinite;
  z-index: 0;
  mix-blend-mode: screen;
}

/* 第二层光斑 - 反向流动 */
.processing-wrapper::after {
  content: '';
  position: absolute;
  bottom: -30%;
  right: -30%;
  width: 140%;
  height: 140%;
  background: radial-gradient(circle, 
    rgba(102, 84, 241, 0.9) 0%, 
    rgba(234, 204, 248, 0.8) 35%,
    rgba(105, 234, 203, 0.7) 65%,
    transparent 100%);
  animation: flowingGradientReverse 8s ease-in-out infinite;
  z-index: 0;
  mix-blend-mode: screen;
}

@keyframes flowingGradient {
  0% {
    transform: scale(1);
    opacity: 0.7;
  }
  50% {
    transform: scale(1.3);
    opacity: 0.95;
  }
  100% {
    transform: scale(1);
    opacity: 0.7;
  }
}

@keyframes flowingGradientReverse {
  0% {
    transform: scale(1);
    opacity: 0.6;
  }
  50% {
    transform: scale(1.25);
    opacity: 0.85;
  }
  100% {
    transform: scale(1);
    opacity: 0.6;
  }
}

.progress-text { 
  position: relative;
  z-index: 1;
  color: #ffffff; 
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 1px;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  gap: 2px;
}

.text-content {
  position: relative;
  display: inline-block;
  width: 160px;
  text-align: center;
}

.rotating-text {
  position: relative;
  display: block;
  height: 24px;
  overflow: hidden;
}

.text-item {
  display: block;
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  white-space: nowrap;
  opacity: 0;
  animation: text-rotate 12s ease-in-out infinite;
  text-shadow: 
    0 0 10px rgba(255, 255, 255, 0.8),
    0 0 20px rgba(0, 212, 147, 0.6),
    0 0 30px rgba(0, 212, 147, 0.4);
}

.text-item:nth-child(1) {
  animation-delay: 0s;
}

.text-item:nth-child(2) {
  animation-delay: 3s;
}

.text-item:nth-child(3) {
  animation-delay: 6s;
}

.text-item:nth-child(4) {
  animation-delay: 9s;
}

/* 文字轮换动画 */
@keyframes text-rotate {
  0% {
    opacity: 0;
    transform: translateX(-50%) translateY(20px);
  }
  5% {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
  20% {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
    text-shadow: 
      0 0 20px rgba(255, 255, 255, 1),
      0 0 40px rgba(0, 212, 147, 0.8),
      0 0 60px rgba(0, 212, 147, 0.6);
  }
  25% {
    opacity: 0;
    transform: translateX(-50%) translateY(-20px);
  }
  100% {
    opacity: 0;
    transform: translateX(-50%) translateY(-20px);
  }
}

.dots {
  display: inline-flex;
  gap: 2px;
}

.dot {
  animation: dot-blink 1.4s ease-in-out infinite;
  opacity: 0;
}

.dot:nth-child(1) {
  animation-delay: 0s;
}

.dot:nth-child(2) {
  animation-delay: 0.2s;
}

.dot:nth-child(3) {
  animation-delay: 0.4s;
}

/* 点点闪烁动画 */
@keyframes dot-blink {
  0%, 20% {
    opacity: 0;
    transform: translateY(0);
  }
  40% {
    opacity: 1;
    transform: translateY(-5px);
  }
  60%, 100% {
    opacity: 0;
    transform: translateY(0);
  }
}
.failed-wrapper { background-color: rgba(255, 107, 107, 0.1); border: 1px solid rgba(255, 107, 107, 0.2); padding: 20px; border-radius: 6px; max-width: 480px; }
.failed-text { color: #ff6b6b; font-weight: 500; margin: 0 0 8px 0; }
.error-msg { color: #ff9a9a; font-size: 13px; line-height: 1.5; margin: 0; }
.task-card-footer { text-align: left; display: flex; align-items: center; gap: 12px; }
.remake-btn { background-color: #383838; color: #e0e0e0; border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer; transition: all 0.3s; }
.remake-btn:hover { background-color: #4a4a4a; }

.publish-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  background-color: #383838;
  color: #e0e0e0;
  border: none;
  padding: 8px 16px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s;
}

.publish-btn:hover {
  background-color: #4a4a4a;
}

.publish-icon {
  width: 16px;
  height: 16px;
}

.published-badge, .pending-badge {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
}

.published-badge {
  background-color: rgba(16, 185, 129, 0.15);
  color: #10b981;
  border: 1px solid rgba(16, 185, 129, 0.3);
}

.pending-badge {
  background-color: rgba(245, 158, 11, 0.15);
  color: #f59e0b;
  border: 1px solid rgba(245, 158, 11, 0.3);
}

.badge-icon {
  width: 16px;
  height: 16px;
}

/* 发布对话框样式 */
.publish-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 199999 !important;
  padding: 20px;
}

.publish-modal-content {
  background-color: #2a2a2a;
  border-radius: 8px;
  width: 100%;
  max-width: 500px;
  max-height: 90vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.8);
}

.publish-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.publish-modal-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #ffffff;
}

.publish-close-btn {
  width: 32px;
  height: 32px;
  border: none;
  background: none;
  color: #999;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  transition: all 0.3s;
}

.publish-close-btn:hover {
  background-color: rgba(255, 255, 255, 0.1);
  color: #fff;
}

.publish-close-btn svg {
  width: 20px;
  height: 20px;
}

.publish-modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 24px;
}

.publish-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.form-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.form-label {
  color: #d0d0d0;
  font-size: 14px;
  font-weight: 500;
}

.required {
  color: #ff6b6b;
}

.input-wrapper,
.textarea-wrapper {
  position: relative;
}

.custom-input,
.custom-textarea {
  width: 100%;
  padding: 10px 12px;
  background-color: #1f1f1f;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 6px;
  color: #e0e0e0;
  font-size: 14px;
  transition: all 0.3s;
  outline: none;
  box-sizing: border-box;
}

.custom-input:hover,
.custom-textarea:hover {
  background-color: #252525;
  border-color: rgba(255, 255, 255, 0.18);
}

.custom-input:focus,
.custom-textarea:focus {
  background-color: #252525;
  border-color: rgba(255, 255, 255, 0.25);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.05);
}

.custom-textarea {
  resize: vertical;
  min-height: 80px;
  font-family: inherit;
  line-height: 1.6;
}

.char-count {
  position: absolute;
  bottom: 10px;
  right: 12px;
  font-size: 12px;
  color: #888;
  pointer-events: none;
}

.tags-container {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 12px;
  background-color: #1f1f1f;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 6px;
  min-height: 48px;
  transition: all 0.3s;
}

.tags-container:hover {
  background-color: #252525;
  border-color: rgba(255, 255, 255, 0.18);
}

.tag-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background-color: #383838;
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: #e0e0e0;
  border-radius: 4px;
  font-size: 13px;
}

.tag-close {
  border: none;
  background: none;
  color: #999;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  padding: 0;
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s;
}

.tag-close:hover {
  color: #fff;
}

.tag-input {
  flex: 1;
  min-width: 120px;
  padding: 4px 8px;
  background: none;
  border: none;
  color: #e0e0e0;
  font-size: 13px;
  outline: none;
}

.tag-input::placeholder {
  color: #666;
}

.form-hint {
  font-size: 12px;
  color: #888;
  margin-top: 4px;
}

.publish-modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 16px 24px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.cancel-btn,
.confirm-btn {
  padding: 8px 20px;
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s;
  border: none;
}

.cancel-btn {
  background-color: #383838;
  color: #e0e0e0;
}

.cancel-btn:hover {
  background-color: #4a4a4a;
}

.confirm-btn {
  background-color: #5a5a5a;
  color: #fff;
  font-weight: 500;
}

.confirm-btn:hover:not(:disabled) {
  background-color: #666666;
}

.confirm-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 模态框动画 */
.modal-enter-active,
.modal-leave-active {
  transition: opacity 0.3s ease;
}

.modal-enter-from,
.modal-leave-to {
  opacity: 0;
}

.modal-enter-active .modal-content,
.modal-leave-active .modal-content {
  transition: transform 0.3s ease;
}

.modal-enter-from .modal-content {
  transform: scale(0.9);
}

.modal-leave-to .modal-content {
  transform: scale(0.9);
}

.state-container { display: flex; flex-direction: column; align-items: center; justify-content: center; height: calc(100vh - 200px); color: #777; }
.no-data-icon { width: 60px; height: 60px; fill: #444; margin-bottom: 16px; }
.state-text { font-size: 16px; margin-bottom: 8px; }
.state-text.error { color: #ff6b6b; }
.state-hint { font-size: 14px; color: #555; }
.spinner { width: 40px; height: 40px; border: 4px solid #333; border-top-color: #fff; border-radius: 50%; animation: spin 1s linear infinite; margin-bottom: 16px; }
@keyframes spin { to { transform: rotate(360deg); } }
.retry-btn { background-color: #383838; color: #e0e0e0; border: 1px solid #555; padding: 8px 16px; border-radius: 6px; cursor: pointer; margin-top: 16px; }
.pagination-container { display: flex; justify-content: center; margin-top: 32px; }
:deep(.el-pagination.is-background .el-pager li) { background-color: #2c2c2c; color: #a0a0a0; }
:deep(.el-pagination.is-background .el-pager li.is-active) { background-color: #555; color: #fff; }
:deep(.el-pagination.is-background .btn-prev),
:deep(.el-pagination.is-background .btn-next) { background-color: #2c2c2c; color: #a0a0a0; }
</style>
