<template>
  <div class="create-sidebar text-to-video-sidebar">
    <!-- 加载遮罩层 -->
    <div v-if="loading" class="loading-overlay">
      <div class="loading-content">
        <div class="spinner"></div>
        <p class="loading-text">正在加载模型数据...</p>
      </div>
    </div>
    
    <!-- 模式切换按钮 -->
    <div class="mode-switcher">
      <button 
        v-for="mode in modes" 
        :key="mode.key"
        @click="handleModeSwitch(mode.key)"
        :class="['mode-btn', { active: mode.key === 'text' }]"
      >
        {{ mode.label }}
      </button>
    </div>

    <div class="sidebar-content">
      <!-- 文本输入区域 -->
      <div class="input-section">
        <textarea 
          v-model="textInput"
          placeholder="请描述您想要生成的视频内容..."
          class="text-input"
          rows="6"
        ></textarea>
      </div>

      <!-- 参数设置区域 -->
      <div class="settings-section">
        <!-- 模型选择 -->
        <div class="setting-row">
          <span class="setting-label">模型</span>
          <div class="setting-control">
            <div class="custom-select" @click="toggleModelDropdown" v-click-outside="closeModelDropdown">
              <div class="select-display">
                <svg class="model-icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
                  <path d="M646.78 186.44a63.586 63.586 0 0 0-63.59 0L262.34 371.69a63.594 63.594 0 0 0-31.79 55.07V791.7L483.2 937.56a63.586 63.586 0 0 0 63.59 0l320.85-185.25a63.594 63.594 0 0 0 31.79-55.07V332.31L646.78 186.44z" fill="#E9F1FF"/>
                  <path d="M308.28 860.59c-4.3 0-8.62-1.11-12.5-3.35l-153.91-88.86c-22.8-13.16-36.97-37.7-36.97-64.03 0-13.81 11.19-25 25-25s25 11.19 25 25c0 8.52 4.59 16.47 11.97 20.73l109.54 63.24a623.714 623.714 0 0 1-2.96-60.67c0-128.91 39.36-252.4 113.83-357.1a619.428 619.428 0 0 1 128.04-132.71c35.86-27.49 74.43-50.86 115.14-69.78l-106.5-61.48c-7.38-4.26-16.55-4.26-23.94 0l-151.99 87.75c-11.96 6.9-27.25 2.81-34.15-9.15-6.9-11.96-2.81-27.25 9.15-34.15l151.99-87.75c22.8-13.17 51.13-13.17 73.94 0l150.36 86.81c8.41 4.85 13.24 14.14 12.41 23.81-0.84 9.67-7.2 17.98-16.31 21.32-53.72 19.67-104.08 47.36-149.68 82.32a569.319 569.319 0 0 0-117.72 122.01c-68.41 96.19-104.57 209.66-104.57 328.13 0 34.71 3.17 69.5 9.42 103.41 1.77 9.59-2.2 19.33-10.17 24.95a25.194 25.194 0 0 1-14.42 4.55zM129.9 458.1c-13.81 0-25-11.19-25-25V319.65c0-26.33 14.17-50.87 36.97-64.03l101.75-58.75c11.96-6.9 27.25-2.81 34.15 9.15 6.9 11.96 2.81 27.25-9.15 34.15l-101.75 58.75c-7.38 4.26-11.97 12.2-11.97 20.73V433.1c0 13.81-11.19 25-25 25z" fill="#2C5CCB"/>
                  <path d="M711.52 863.03c-8.64 0-17.04-4.48-21.67-12.5-6.9-11.96-2.81-27.25 9.15-34.15l158.13-91.3c7.38-4.26 11.97-12.2 11.97-20.73V575.49a624.941 624.941 0 0 1-48.78 31.27c-94.53 54.58-199.75 82.76-307.42 82.76-20.03 0-40.13-0.97-60.28-2.94a619.251 619.251 0 0 1-179.54-45.27c-41.83-17.53-81.41-39.5-118.18-65.55v128.59c0 8.52 4.59 16.47 11.97 20.73l153.91 88.86c11.96 6.9 16.05 22.19 9.15 34.15-6.9 11.96-22.19 16.05-34.15 9.15l-153.91-88.86c-22.8-13.16-36.97-37.7-36.97-64.03V524.81c0-9.73 5.65-18.58 14.47-22.67 8.83-4.1 19.23-2.7 26.66 3.58 43.9 37.08 93.15 67.19 146.37 89.49 52.69 22.08 108.22 36.09 165.06 41.62 118 11.49 234.82-13.88 337.85-73.36 29.25-16.89 57.06-36.4 82.66-58a25.01 25.01 0 0 1 26.66-3.56 24.995 24.995 0 0 1 14.46 22.67v179.77c0 26.33-14.17 50.87-36.97 64.03l-158.13 91.3a24.873 24.873 0 0 1-12.47 3.35z" fill="#2C5CCB"/>
                  <path d="M512 970.61c-12.78 0-25.57-3.29-36.97-9.87l-100.04-57.76c-11.96-6.9-16.05-22.19-9.15-34.15 6.9-11.96 22.19-16.05 34.15-9.15l100.04 57.76c7.38 4.26 16.55 4.26 23.94 0l95.6-55.2c11.96-6.9 27.25-2.81 34.15 9.15 6.9 11.96 2.81 27.25-9.15 34.15l-95.6 55.2a74.06 74.06 0 0 1-36.97 9.87zM711.5 863.02c-5.09 0-10.16-1.55-14.47-4.62a25.007 25.007 0 0 1-10.09-25.05c10.81-56.94 12.77-115.11 5.82-172.9a569.326 569.326 0 0 0-45.87-165.32c-48.93-109.06-129.7-198.4-233.57-258.37-27.63-15.95-56.71-29.65-86.43-40.7a25.002 25.002 0 0 1-16.2-21.34c-0.81-9.65 4.03-18.9 12.41-23.74l151.93-87.72c22.8-13.17 51.13-13.17 73.94 0l150.36 86.81c11.96 6.9 16.05 22.19 9.15 34.15-6.9 11.96-22.19 16.05-34.15 9.15l-150.36-86.81c-7.38-4.26-16.55-4.26-23.94 0L391.7 169.12a626.826 626.826 0 0 1 46.62 24.35c113.03 65.26 200.93 162.5 254.19 281.21a619.708 619.708 0 0 1 49.9 179.82c5.45 45.36 5.86 90.95 1.25 136.1l113.47-65.51c7.38-4.26 11.97-12.2 11.97-20.73 0-13.81 11.19-25 25-25s25 11.19 25 25c0 26.33-14.17 50.87-36.97 64.03L724 859.67a24.963 24.963 0 0 1-12.5 3.35zM894.1 457.96c-13.81 0-25-11.19-25-25V319.65c0-8.52-4.59-16.47-11.97-20.73L754.04 239.4c-11.96-6.9-16.05-22.19-9.15-34.15 6.9-11.96 22.19-16.05 34.15-9.15l103.09 59.52c22.8 13.16 36.97 37.7 36.97 64.03v113.32c0 13.8-11.2 24.99-25 24.99z" fill="#2C5CCB"/>
                  <path d="M0 513.47h1024v1H0z" fill="#2C5CCB"/>
                </svg>
                <span class="select-text">{{ modelOptions.find(opt => opt.value === model)?.label || 'Sora2.0' }}</span>
                <span v-if="model === 'sora2.0'" class="model-badge-display">2.0</span>
                <svg class="dropdown-arrow" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polyline points="6,9 12,15 18,9"></polyline>
                </svg>
              </div>
              <div v-if="showModelDropdown" class="select-dropdown">
                <div 
                  v-for="option in modelOptions" 
                  :key="option.value"
                  @click.stop="selectModel(option.value)"
                  class="select-option"
                  :class="{ active: model === option.value }"
                >
                  <svg class="option-icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
                    <path d="M646.78 186.44a63.586 63.586 0 0 0-63.59 0L262.34 371.69a63.594 63.594 0 0 0-31.79 55.07V791.7L483.2 937.56a63.586 63.586 0 0 0 63.59 0l320.85-185.25a63.594 63.594 0 0 0 31.79-55.07V332.31L646.78 186.44z" fill="#E9F1FF"/>
                    <path d="M308.28 860.59c-4.3 0-8.62-1.11-12.5-3.35l-153.91-88.86c-22.8-13.16-36.97-37.7-36.97-64.03 0-13.81 11.19-25 25-25s25 11.19 25 25c0 8.52 4.59 16.47 11.97 20.73l109.54 63.24a623.714 623.714 0 0 1-2.96-60.67c0-128.91 39.36-252.4 113.83-357.1a619.428 619.428 0 0 1 128.04-132.71c35.86-27.49 74.43-50.86 115.14-69.78l-106.5-61.48c-7.38-4.26-16.55-4.26-23.94 0l-151.99 87.75c-11.96 6.9-27.25 2.81-34.15-9.15-6.9-11.96-2.81-27.25 9.15-34.15l151.99-87.75c22.8-13.17 51.13-13.17 73.94 0l150.36 86.81c8.41 4.85 13.24 14.14 12.41 23.81-0.84 9.67-7.2 17.98-16.31 21.32-53.72 19.67-104.08 47.36-149.68 82.32a569.319 569.319 0 0 0-117.72 122.01c-68.41 96.19-104.57 209.66-104.57 328.13 0 34.71 3.17 69.5 9.42 103.41 1.77 9.59-2.2 19.33-10.17 24.95a25.194 25.194 0 0 1-14.42 4.55zM129.9 458.1c-13.81 0-25-11.19-25-25V319.65c0-26.33 14.17-50.87 36.97-64.03l101.75-58.75c11.96-6.9 27.25-2.81 34.15 9.15 6.9 11.96 2.81 27.25-9.15 34.15l-101.75 58.75c-7.38 4.26-11.97 12.2-11.97 20.73V433.1c0 13.81-11.19 25-25 25z" fill="#2C5CCB"/>
                    <path d="M711.52 863.03c-8.64 0-17.04-4.48-21.67-12.5-6.9-11.96-2.81-27.25 9.15-34.15l158.13-91.3c7.38-4.26 11.97-12.2 11.97-20.73V575.49a624.941 624.941 0 0 1-48.78 31.27c-94.53 54.58-199.75 82.76-307.42 82.76-20.03 0-40.13-0.97-60.28-2.94a619.251 619.251 0 0 1-179.54-45.27c-41.83-17.53-81.41-39.5-118.18-65.55v128.59c0 8.52 4.59 16.47 11.97 20.73l153.91 88.86c11.96 6.9 16.05 22.19 9.15 34.15-6.9 11.96-22.19 16.05-34.15 9.15l-153.91-88.86c-22.8-13.16-36.97-37.7-36.97-64.03V524.81c0-9.73 5.65-18.58 14.47-22.67 8.83-4.1 19.23-2.7 26.66 3.58 43.9 37.08 93.15 67.19 146.37 89.49 52.69 22.08 108.22 36.09 165.06 41.62 118 11.49 234.82-13.88 337.85-73.36 29.25-16.89 57.06-36.4 82.66-58a25.01 25.01 0 0 1 26.66-3.56 24.995 24.995 0 0 1 14.46 22.67v179.77c0 26.33-14.17 50.87-36.97 64.03l-158.13 91.3a24.873 24.873 0 0 1-12.47 3.35z" fill="#2C5CCB"/>
                    <path d="M512 970.61c-12.78 0-25.57-3.29-36.97-9.87l-100.04-57.76c-11.96-6.9-16.05-22.19-9.15-34.15 6.9-11.96 22.19-16.05 34.15-9.15l100.04 57.76c7.38 4.26 16.55 4.26 23.94 0l95.6-55.2c11.96-6.9 27.25-2.81 34.15 9.15 6.9 11.96 2.81 27.25-9.15 34.15l-95.6 55.2a74.06 74.06 0 0 1-36.97 9.87zM711.5 863.02c-5.09 0-10.16-1.55-14.47-4.62a25.007 25.007 0 0 1-10.09-25.05c10.81-56.94 12.77-115.11 5.82-172.9a569.326 569.326 0 0 0-45.87-165.32c-48.93-109.06-129.7-198.4-233.57-258.37-27.63-15.95-56.71-29.65-86.43-40.7a25.002 25.002 0 0 1-16.2-21.34c-0.81-9.65 4.03-18.9 12.41-23.74l151.93-87.72c22.8-13.17 51.13-13.17 73.94 0l150.36 86.81c11.96 6.9 16.05 22.19 9.15 34.15-6.9 11.96-22.19 16.05-34.15 9.15l-150.36-86.81c-7.38-4.26-16.55-4.26-23.94 0L391.7 169.12a626.826 626.826 0 0 1 46.62 24.35c113.03 65.26 200.93 162.5 254.19 281.21a619.708 619.708 0 0 1 49.9 179.82c5.45 45.36 5.86 90.95 1.25 136.1l113.47-65.51c7.38-4.26 11.97-12.2 11.97-20.73 0-13.81 11.19-25 25-25s25 11.19 25 25c0 26.33-14.17 50.87-36.97 64.03L724 859.67a24.963 24.963 0 0 1-12.5 3.35zM894.1 457.96c-13.81 0-25-11.19-25-25V319.65c0-8.52-4.59-16.47-11.97-20.73L754.04 239.4c-11.96-6.9-16.05-22.19-9.15-34.15 6.9-11.96 22.19-16.05 34.15-9.15l103.09 59.52c22.8 13.16 36.97 37.7 36.97 64.03v113.32c0 13.8-11.2 24.99-25 24.99z" fill="#2C5CCB"/>
                    <path d="M0 513.47h1024v1H0z" fill="#2C5CCB"/>
                  </svg>
                  <span class="option-text">{{ option.label }}</span>
                  <span v-if="model === option.value" class="check-mark">✓</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 比例选择 -->
        <div class="setting-row">
          <span class="setting-label">比例</span>
          <div class="setting-control">
            <div class="custom-select" @click="toggleRatioDropdown" v-click-outside="closeRatioDropdown">
              <div class="select-display">
                <component :is="getRatioIcon(ratio)" class="ratio-icon" />
                <span class="select-text">{{ ratioOptions.find(opt => opt.value === ratio)?.label || '竖屏 (9:16)' }}</span>
                <svg class="dropdown-arrow" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polyline points="6,9 12,15 18,9"></polyline>
                </svg>
              </div>
              <div v-if="showRatioDropdown" class="select-dropdown">
                <div 
                  v-for="option in ratioOptions" 
                  :key="option.value"
                  @click.stop="selectRatio(option.value)"
                  class="select-option"
                  :class="{ active: ratio === option.value }"
                >
                  <component :is="getRatioIcon(option.value)" class="ratio-icon" />
                  <span class="option-text">{{ option.label }}</span>
                  <span v-if="ratio === option.value" class="check-mark">✓</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 时长选择 -->
        <div class="setting-row">
          <span class="setting-label">时长</span>
          <div class="setting-control">
            <div class="custom-select" @click="toggleDurationDropdown" v-click-outside="closeDurationDropdown">
              <div class="select-display">
                <span class="select-text">{{ durationOptions.find(opt => opt.value === duration)?.label || '10秒' }}</span>
                <svg class="dropdown-arrow" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polyline points="6,9 12,15 18,9"></polyline>
                </svg>
              </div>
              <div v-if="showDurationDropdown" class="select-dropdown">
                <div 
                  v-for="option in durationOptions" 
                  :key="option.value"
                  @click.stop="selectDuration(option.value)"
                  class="select-option"
                  :class="{ active: duration === option.value }"
                >
                  <span class="option-text">{{ option.label }}</span>
                  <span v-if="duration === option.value" class="check-mark">✓</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 高清模式 -->
        <div class="setting-row quality-row">
          <div class="quality-left">
            <span class="setting-label">高清模式 (1080P)</span>
            <label class="switch">
              <input type="checkbox" v-model="highQuality" :disabled="isHighQualityDisabled">
              <span class="slider"></span>
            </label>
          </div>
        
        </div>
      </div>

      <!-- 操作按钮区域 -->
      <div class="action-section">
        <button 
          @click="handleGenerate" 
          :disabled="!textInput.trim() || !matchedModel || submitting"
          class="generate-btn"
        >
          <span>{{ submitting ? '提交中...' : '生成视频' }}</span>
          <span v-if="requiredPoints > 0 && !submitting" class="points-cost">
            消耗 {{ requiredPoints }} 积分
          </span>
          <span v-else-if="!matchedModel && !loading && !submitting" class="points-cost error">
            未找到模型
          </span>
          <span v-else-if="loading && !submitting" class="points-cost">
            加载中...
          </span>
        </button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch, h } from 'vue'
import { getAIModels, submitAITask, getAITaskDetail } from '../../api'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useUserStore } from '../../store/user'

const props = defineProps({
  remakePrompt: {
    type: String,
    default: ''
  },
  remakeAspectRatio: {
    type: String,
    default: ''
  },
  remakeModelName: {
    type: String,
    default: ''
  }
})

// 定义emit
const emit = defineEmits(['switch-mode', 'task-update', 'remake-done'])

// 模式数据
const modes = [
  { key: 'text', label: '文生视频' },
  { key: 'image', label: '图生视频' }
]

// 响应式数据
const textInput = ref('')
const model = ref('Sora2_text_video') // 固定显示的模型名称
const ratio = ref('portrait') // 竖屏(portrait) 或 横屏(landscape)
const duration = ref(10) // 10秒 或 15秒
const highQuality = ref(false) // 是否高清
const showModelDropdown = ref(false)
const showRatioDropdown = ref(false)
const showDurationDropdown = ref(false)
const availableModels = ref([]) // 从API获取的模型列表
const loading = ref(false)
const submitting = ref(false) // 是否正在提交任务

// 用户store
const userStore = useUserStore()

watch(() => props.remakePrompt, (newPrompt) => {
  if (newPrompt) {
    textInput.value = newPrompt;
    // 只填充数据，不自动调用生成
    // Reset the prompt in the parent to avoid re-triggering
    emit('remake-done');
  }
});

// 监听 aspectRatio 参数变化
watch(() => props.remakeAspectRatio, (newAspectRatio) => {
  if (newAspectRatio) {
    // 将 aspectRatio 转换为 ratio 值
    if (newAspectRatio === '9:16') {
      ratio.value = 'portrait'
    } else if (newAspectRatio === '16:9') {
      ratio.value = 'landscape'
    }
    console.log('应用做同款尺寸:', newAspectRatio, '转换为:', ratio.value)
  }
});

// 应用模型配置的函数
const applyModelConfig = (modelName) => {
  if (!modelName || availableModels.value.length === 0) return
  
  const targetModel = availableModels.value.find(m => m.modelName === modelName)
  if (targetModel && targetModel.extendedConfig) {
    const config = targetModel.extendedConfig

    const lowerName = (targetModel.modelName || '').toLowerCase()
    const isSora2ProModel = lowerName.includes('sora2pro')
    model.value = isSora2ProModel ? 'sora2-pro' : 'Sora2_text_video'
    
    // 设置尺寸比例
    if (config.aspectRatio === '9:16') {
      ratio.value = 'portrait'
    } else if (config.aspectRatio === '16:9') {
      ratio.value = 'landscape'
    }
    
    // 设置时长
    if (config.duration) {
      duration.value = Number.parseInt(config.duration, 10)
    }
    
    // 设置高清选项
    if (config.size === 'large') {
      highQuality.value = true
    } else if (config.size === 'small') {
      highQuality.value = false
    }
    
    console.log('应用做同款模型:', modelName, '配置:', config, 'isSora2Pro:', isSora2ProModel)
  } else {
    console.warn(`未找到匹配的模型: ${modelName}`)
  }
}

// 监听 modelName 参数变化
watch(() => props.remakeModelName, (newModelName) => {
  if (newModelName) {
    applyModelConfig(newModelName)
  }
})

// 监听模型列表加载完成后，如果有待应用的模型名称，则应用它
watch(availableModels, (models) => {
  if (models.length > 0 && props.remakeModelName) {
    applyModelConfig(props.remakeModelName)
  }
})

// 监听模型和时长的变化，如果切换到 sora2-pro 且时长为 25秒，自动关闭高清模式
watch([() => model.value, () => duration.value], ([newModel, newDuration]) => {
  if (newModel === 'sora2-pro' && newDuration === 25) {
    highQuality.value = false
  }
})

// 模型选项
const modelOptions = [
  { value: 'Sora2_text_video', label: 'Sora2_text_video' },
  { value: 'sora2-pro', label: 'Sora2-Pro' }
]

// 比例选项
const ratioOptions = [
  { value: 'portrait', label: '竖屏 (9:16)' },
  { value: 'landscape', label: '横屏 (16:9)' }
]

// 根据选择的模型动态计算时长选项
const durationOptions = computed(() => {
  if (model.value === 'sora2-pro') {
    return [
      { value: 15, label: '15秒' },
      { value: 25, label: '25秒' }
    ]
  } else {
    return [
      { value: 10, label: '10秒' },
      { value: 15, label: '15秒' }
    ]
  }
})

// 根据用户选择匹配实际的模型
const matchedModel = computed(() => {
  if (availableModels.value.length === 0) return null
  
  // 构建模型匹配条件
  const targetAspectRatio = ratio.value === 'portrait' ? '9:16' : '16:9'
  const targetDuration = duration.value.toString()
  
  // 判断是否为 Sora2Pro 模型
  const isSora2Pro = model.value === 'sora2-pro'
  
  // Sora2Pro 的 25秒不支持高清，强制使用 small
  // 其他情况根据 highQuality 选择
  const targetSize = (isSora2Pro && duration.value === 25) ? 'small' : (highQuality.value ? 'large' : 'small')
  
  // 查找匹配的模型
  const found = availableModels.value.find(m => {
    const config = m.extendedConfig
    const modelName = m.modelName || ''
    
    // 检查模型名称是否匹配选择的模型类型
    if (isSora2Pro && !modelName.includes('sora2pro')) {
      return false
    }
    if (!isSora2Pro && modelName.includes('sora2pro')) {
      return false
    }
    
    // 匹配 aspectRatio 和 duration
    if (config.aspectRatio !== targetAspectRatio || config.duration !== targetDuration) {
      return false
    }
    
    // 对于 Sora2Pro，size 字段可能不存在，忽略 size 匹配
    // 对于 Sora2，必须匹配 size
    if (isSora2Pro) {
      // Sora2Pro 模型可能没有 size 字段，或者有但可以忽略
      // 但 25秒的模型只有 small，所以如果选择了 large 但 duration 是 25，应该找不到匹配
      // 实际上由于上面已经强制 targetSize 为 small，所以这里直接返回 true 即可
      return true
    } else {
      // Sora2 模型必须匹配 size
      return config.size === targetSize
    }
  })
  
  console.log('匹配模型:', {
    selectedModel: model.value,
    targetAspectRatio,
    targetDuration,
    targetSize,
    isSora2Pro,
    found: found ? found.modelName : 'null'
  })
  
  return found
})

// 计算需要消耗的积分
const requiredPoints = computed(() => {
  return matchedModel.value ? matchedModel.value.pointsCost : 0
})

// 判断高清模式是否应该被禁用（sora2-pro 的 25秒不支持高清）
const isHighQualityDisabled = computed(() => {
  return model.value === 'sora2-pro' && duration.value === 25
})

// 方法
const handleModeSwitch = (modeKey) => {
  if (modeKey !== 'text') {
    emit('switch-mode', modeKey)
  }
}

const toggleModelDropdown = () => {
  showModelDropdown.value = !showModelDropdown.value
}

const closeModelDropdown = () => {
  showModelDropdown.value = false
}

const selectModel = (value) => {
  model.value = value
  showModelDropdown.value = false
  
  // 切换模型时，重置时长到该模型的第一个选项
  if (value === 'sora2-pro') {
    duration.value = 15
  } else {
    duration.value = 10
  }
}

// 根据比例生成对应的 SVG 图标
const getRatioIcon = (ratioValue) => {
  const ratioSvgs = {
    'portrait': () => h('svg', { 
      viewBox: '0 0 24 24', 
      fill: 'none', 
      xmlns: 'http://www.w3.org/2000/svg',
      style: { width: '20px', height: '20px' }
    }, [
      h('rect', { x: '7', y: '2', width: '10', height: '20', rx: '1', stroke: 'currentColor', 'stroke-width': '1.5', fill: 'none' })
    ]),
    'landscape': () => h('svg', { 
      viewBox: '0 0 24 24', 
      fill: 'none', 
      xmlns: 'http://www.w3.org/2000/svg',
      style: { width: '20px', height: '20px' }
    }, [
      h('rect', { x: '2', y: '7', width: '20', height: '10', rx: '1', stroke: 'currentColor', 'stroke-width': '1.5', fill: 'none' })
    ])
  }
  
  return ratioSvgs[ratioValue] || ratioSvgs['portrait']
}

const toggleRatioDropdown = () => {
  showRatioDropdown.value = !showRatioDropdown.value
}

const closeRatioDropdown = () => {
  showRatioDropdown.value = false
}

const selectRatio = (value) => {
  ratio.value = value
  showRatioDropdown.value = false
}

const toggleDurationDropdown = () => {
  showDurationDropdown.value = !showDurationDropdown.value
}

const closeDurationDropdown = () => {
  showDurationDropdown.value = false
}

const selectDuration = (value) => {
  duration.value = value
  showDurationDropdown.value = false
  
  // 如果选择了 sora2-pro 的 25秒，自动关闭高清模式
  if (model.value === 'sora2-pro' && value === 25) {
    highQuality.value = false
  }
}

// v-click-outside directive
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 fetchModels = async () => {
  loading.value = true
  try {
    const response = await getAIModels({
      taskType: 'text_to_video',
      provider: 'suchuang',
      enabledOnly: true
    })
    
    if (response.code === 200 && response.data) {
      availableModels.value = response.data
      console.log('获取到的模型列表:', response.data)
    } else {
      ElMessage.error('获取模型列表失败')
    }
  } catch (error) {
    console.error('获取模型列表错误:', error)
    ElMessage.error('获取模型列表失败，请刷新页面重试')
  } finally {
    loading.value = false
  }
}

const handleGenerate = async () => {
  if (!matchedModel.value) {
    ElMessage.warning('未找到匹配的模型，请检查参数设置')
    return
  }
  
  // 检查用户积分
  if (userStore.userInfo?.points < requiredPoints.value) {
    ElMessage.warning(`积分不足，需要 ${requiredPoints.value} 积分，当前仅有 ${userStore.userInfo?.points || 0} 积分`)
    return
  }
  
  submitting.value = true
  
  try {
    // 构建任务提交数据
    const taskData = {
      modelName: matchedModel.value.modelName,
      prompt: textInput.value,
      aspectRatio: ratio.value === 'portrait' ? '9:16' : '16:9',
      imageToVideo: false
    }
    
    console.log('提交任务数据:', taskData)
    
    // 提交任务
    const response = await submitAITask(taskData)
    
    if (response.code === 200 && response.data) {
      const taskNo = response.data.taskNo || response.data.id
      
      ElMessage.success('任务提交成功，正在生成视频...')
      
      // 通知父组件任务已提交
      emit('task-update')
      
      // 开始轮询任务状态
      pollTaskStatus(taskNo)
      
      // 清空输入
      textInput.value = ''
    } else {
      ElMessage.error(response.message || '任务提交失败')
    }
  } catch (error) {
    console.error('提交任务错误:', error)
    ElMessage.error(error.response?.data?.message || '任务提交失败，请稍后重试')
  } finally {
    submitting.value = false
  }
}

// 轮询任务状态
// 每20秒轮询一次，最大轮询15分钟 (15 * 60 / 20 = 45次)
const pollTaskStatus = async (taskNo, maxAttempts = 45) => {
  let attempts = 0
  const pollInterval = 20000 // 20秒
  
  // 立即通知内容区刷新，确保新提交的任务能被显示
  emit('task-update')
  
  const checkStatus = async () => {
    try {
      const response = await getAITaskDetail(taskNo)
      
      if (response.code === 200 && response.data) {
        const task = response.data
        const status = task.status
        
        console.log(`轮询任务状态 (${attempts + 1}/${maxAttempts}):`, {
          taskNo,
          status,
          progress: task.progress
        })
        
        // 每次轮询后都通知内容区刷新，保持状态同步
        emit('task-update')
        
        // 每次轮询都更新用户信息（积分），实现实时显示
        if (userStore.fetchUserInfo) {
          userStore.fetchUserInfo().catch(err => console.error('更新用户信息失败:', err))
        }
        
        // 任务状态: pending(待处理), processing(处理中), completed(已完成), failed(失败)
        if (status === 'completed') {
          ElMessage.success('视频生成成功！')
          console.log('任务完成:', task)
          
          // 刷新用户信息（包括积分）
          if (userStore.fetchUserInfo) {
            try {
              await userStore.fetchUserInfo()
              console.log('用户信息已更新，当前积分:', userStore.userInfo?.points)
            } catch (error) {
              console.error('刷新用户信息失败:', error)
            }
          }
          
          // 通知父组件任务已完成
          emit('task-update')
          
          return
        } else if (status === 'failed') {
          ElMessage.error(task.errorMessage || '视频生成失败')
          
          // 任务失败时也刷新用户信息（因为积分会被退回）
          if (userStore.fetchUserInfo) {
            try {
              await userStore.fetchUserInfo()
              console.log('任务失败，积分已退回，当前积分:', userStore.userInfo?.points)
            } catch (error) {
              console.error('刷新用户信息失败:', error)
            }
          }
          
          // 通知父组件任务失败
          emit('task-update')
          
          return
        } else if (status === 'pending' || status === 'processing') {
          // 继续轮询
          attempts++
          if (attempts < maxAttempts) {
            setTimeout(checkStatus, pollInterval) // 每20秒检查一次
          } else {
            ElMessage.warning('任务处理超时（15分钟），请稍后在任务列表中查看')
            console.warn('任务轮询超时:', { taskNo, attempts, maxAttempts })
          }
        }
      }
    } catch (error) {
      console.error('查询任务状态错误:', error)
      // 继续轮询（除非达到最大次数）
      attempts++
      if (attempts < maxAttempts) {
        setTimeout(checkStatus, pollInterval)
      } else {
        ElMessage.error('查询任务状态失败，请稍后在任务列表中查看')
      }
    }
  }
  
  // 开始首次检查（5秒后开始第一次检查，给后端一些处理时间）
  setTimeout(checkStatus, 5000)
}

const handleClear = () => {
  textInput.value = ''
  model.value = 'Sora2_text_video'
  ratio.value = 'portrait'
  duration.value = 10
  highQuality.value = false
}

// 组件挂载时获取模型列表
onMounted(() => {
  fetchModels()
})
</script>

<style scoped>
.create-sidebar {
  position: relative;
  width: 480px;
  height: 100vh;
  background: rgba(21, 21, 21, 1);
  border-right: 1px solid rgba(255, 255, 255, 0.08);
  padding: 0;
  box-sizing: border-box;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  /* 隐藏滚动条 */
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE and Edge */
}

.create-sidebar::-webkit-scrollbar {
  display: none; /* Chrome, Safari, Opera */
}

/* 模式切换按钮 */
.mode-switcher {
  display: flex;
  padding: 16px 24px 0 24px;
  gap: 8px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  margin-bottom: 24px;
}

.mode-btn {
  flex: 1;
  padding: 12px 16px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px 8px 0 0;
  color: rgba(255, 255, 255, 0.6);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  position: relative;
}

.mode-btn:hover {
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.8);
}

.mode-btn.active {
  background: rgba(26, 195, 255, 0.1);
  border-color: #1AC3FF;
  color: #1AC3FF;
}

.mode-btn.active::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 0;
  right: 0;
  height: 2px;
  background: #1AC3FF;
}

.sidebar-header {
  padding: 0 24px;
  margin-bottom: 32px;
}

.sidebar-title {
  font-size: 24px;
  font-weight: 600;
  color: #ffffff;
  margin: 0 0 8px 0;
}

.sidebar-subtitle {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.6);
  margin: 0;
}

.sidebar-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 0 0 20px 0;
  flex: 1;
  overflow-y: auto;
  /* 隐藏滚动条 */
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE and Edge */
}

.sidebar-content::-webkit-scrollbar {
  display: none; /* Chrome, Safari, Opera */
}

.input-section {
  display: flex;
  flex-direction: column;
  gap: 0;
  width: 448px;
  height: 280px;
  margin: 0 16px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(26, 28, 32, 1);
  padding: 12px;
  box-sizing: border-box;
  transition: border-color 0.3s ease;
}

.input-section:focus-within {
  border-color: rgba(26, 195, 255, 0.4);
  box-shadow: 0 0 0 1px rgba(26, 195, 255, 0.2);
}

.input-label {
  font-size: 14px;
  font-weight: 500;
  color: #ffffff;
}

.text-input {
  width: 100%;
  height: 100%;
  padding: 12px;
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(30px);
  border: none;
  border-radius: 8px;
  color: #ffffff;
  font-size: 14px;
  line-height: 1.6;
  resize: none;
  box-sizing: border-box;
  transition: background-color 0.3s ease;
}

.text-input:hover {
  background: rgba(0, 0, 0, 0.4);
}

.text-input::placeholder {
  color: rgba(255, 255, 255, 0.4);
}

.text-input:focus {
  outline: none;
  background: rgba(0, 0, 0, 0.4);
}

/* 参数设置区域 */
.settings-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0 16px;
}

.setting-row {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: rgba(255, 255, 255, 0.02);
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  transition: all 0.3s ease;
}

.setting-row:hover {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.1);
}

.setting-label {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.9);
  font-weight: 400;
  min-width: 80px;
  flex-shrink: 0;
}

.setting-control {
  flex: 1;
  display: flex;
  justify-content: flex-end;
}

/* 自定义下拉选择器 */
.custom-select {
  position: relative;
  width: 222px;
  cursor: pointer;
  user-select: none;
}

.select-display {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 12px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  color: #ffffff;
  font-family: 'PingFang SC', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 14px;
  font-weight: 400;
  line-height: 24px;
  transition: all 0.2s ease;
}

.select-display:hover {
  background-color: rgba(0, 0, 0, 0.4);
  border-color: rgba(255, 255, 255, 0.2);
}

.model-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.select-text {
  flex: 1;
}

.model-badge-display {
  display: inline-block;
  padding: 2px 6px;
  background: #1AC3FF;
  color: #000;
  font-size: 11px;
  font-weight: 600;
  border-radius: 3px;
  margin-left: auto;
}

.dropdown-arrow {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  margin-left: 4px;
}

/* 下拉选项容器 */
.select-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  width: 222px;
  background: rgba(44, 50, 61, 1);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  z-index: 1000;
  overflow: hidden;
}

.select-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  color: #ffffff;
  font-family: 'PingFang SC', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 14px;
  font-weight: 400;
  line-height: 24px;
  letter-spacing: 0%;
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.select-option:hover {
  background: rgba(255, 255, 255, 0.1);
}

.select-option.active {
  background: rgba(26, 195, 255, 0.15);
}

.option-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.ratio-icon {
  width: 20px;
  height: 20px;
  color: #1AC3FF;
  flex-shrink: 0;
}

.option-text {
  flex: 1;
}

.check-mark {
  color: #1AC3FF;
  font-size: 16px;
  font-weight: 600;
  margin-left: auto;
}

/* 高清模式行 */
.quality-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

.quality-left {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.quality-tip {
  font-size: 12px;
  color: #1AC3FF;
  padding-left: 0;
}

/* 开关样式 */
.switch {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 24px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.2);
  transition: 0.3s;
  border-radius: 24px;
}

.slider:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 3px;
  bottom: 3px;
  background-color: white;
  transition: 0.3s;
  border-radius: 50%;
}

input:checked + .slider {
  background-color: #1AC3FF;
}

input:checked + .slider:before {
  transform: translateX(20px);
}

input:disabled + .slider {
  background-color: rgba(255, 255, 255, 0.1);
  cursor: not-allowed;
  opacity: 0.5;
}

input:disabled + .slider:before {
  background-color: rgba(255, 255, 255, 0.5);
}

.action-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 8px;
  padding: 0 16px;
}

.generate-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 14px 24px;
  background: linear-gradient(135deg, #1AC3FF 0%, #0F9CFF 100%);
  border: none;
  border-radius: 8px;
  color: #ffffff;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(26, 195, 255, 0.2);
}

.generate-btn:hover:not(:disabled) {
  background: linear-gradient(135deg, #33DDE5 0%, #1AC3FF 100%);
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(26, 195, 255, 0.4);
}

.generate-btn:disabled {
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.4);
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.points-cost {
  font-size: 12px;
  font-weight: 400;
  opacity: 0.9;
}

.points-cost.error {
  color: #ff6b6b;
}

.clear-btn {
  padding: 12px 24px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 8px;
  color: rgba(255, 255, 255, 0.8);
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.clear-btn:hover {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.4);
}

/* 加载遮罩层 */
.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(21, 21, 21, 0.95);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

.loading-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.spinner {
  width: 48px;
  height: 48px;
  border: 4px solid rgba(26, 195, 255, 0.2);
  border-top-color: #1AC3FF;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

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

.loading-text {
  color: #1AC3FF;
  font-size: 14px;
  font-weight: 500;
  margin: 0;
  letter-spacing: 0.5px;
}
</style>
