<script setup>
import { onMounted, reactive, ref, computed } from 'vue'
import { message } from 'ant-design-vue'

import TikhubService, { InterfaceType, MethodType, ParamType } from '@/api/tikhub'
import { rewriteStream } from '@/api/forecast'
import { getAgentList } from '@/api/agent'
import { useUserStore } from '@/stores/user'
import { usePointsConfigStore } from '@/stores/pointsConfig'
import { getVoiceText } from '@gold/hooks/web/useVoiceText'
import { copyToClipboard } from '@/utils/clipboard'

defineOptions({ name: 'ForecastView' })

// 状态管理
const userStore = useUserStore()
const pointsConfigStore = usePointsConfigStore()
const searchKeyword = ref('')
const isLoading = ref(false)
const isGenerating = ref(false)
const isAnalyzing = ref(false)
const hotTopics = ref([])
const selectedTopic = ref(null)
const currentCursor = ref(null)
const generatedContent = ref('')

// 搜索参数
const searchParams = reactive({
  keyword: '',
  cursor: 0,
  sort_type: '0',
  publish_time: '0',
  filter_duration: '0',
  content_type: '0',
  search_id: '',
  backtrace: ''
})

// 创作详情
const topicDetails = reactive({
  copywriting: '',
  selectedAgentId: null,
  modelType: 'forecast_standard',
  level: 50
})

// 智能体列表
const agentList = ref([])
const loadingAgents = ref(false)
const agentSearchKeyword = ref('')

// 当前选中的智能体
const selectedAgent = ref(null)

// 过滤后的智能体列表
const filteredAgentList = computed(() => {
  if (!agentSearchKeyword.value.trim()) {
    return agentList.value
  }
  const keyword = agentSearchKeyword.value.trim().toLowerCase()
  return agentList.value.filter(agent =>
    agent.name.toLowerCase().includes(keyword) ||
    (agent.description && agent.description.toLowerCase().includes(keyword))
  )
})

// 工具函数
function formatNumber(num) {
  if (!num) return '0'
  return num >= 10000 ? `${(num / 10000).toFixed(1)}w` : String(num)
}

function truncateTitle(title, maxLength = 28) {
  if (!title) return ''
  return title.length <= maxLength ? title : `${title.substring(0, maxLength)}...`
}

function handleImageError(event) {
  event.target.style.display = 'none'
}

function openVideo(topic, event) {
  event.stopPropagation()
  if (topic.videoUrl) window.open(topic.videoUrl, '_blank')
}

function handleSearchKeypress(event) {
  if (event.key === 'Enter' && !isLoading.value) {
    handleSearch()
  }
}

async function copyContent() {
  const success = await copyToClipboard(generatedContent.value)
  if (success) {
    message.success('已复制')
  } else {
    message.error('复制失败')
  }
}

// 加载智能体列表
async function loadAgentList() {
  loadingAgents.value = true
  try {
    const res = await getAgentList()
    if (res.code === 0 && res.data) {
      agentList.value = res.data.map(item => ({
        id: item.id,
        agentId: item.agentId,
        name: item.agentName,
        description: item.description,
        systemPrompt: item.systemPrompt,
        avatar: item.icon,
        categoryName: item.categoryName || '其他'
      }))
      // 默认选中第一个
      if (agentList.value.length > 0 && !topicDetails.selectedAgentId) {
        topicDetails.selectedAgentId = agentList.value[0].id
        selectedAgent.value = agentList.value[0]
      }
    }
  } catch (error) {
    console.error('加载智能体列表失败:', error)
  } finally {
    loadingAgents.value = false
  }
}

// 处理智能体选择
function handleAgentChange(agentId) {
  const agent = agentList.value.find(a => a.id === agentId)
  if (agent) {
    selectedAgent.value = agent
    topicDetails.selectedAgentId = agentId
  }
}

// 语音分析
async function analyzeVoice(audioUrl) {
  if (!audioUrl?.trim()) {
    console.warn('音频链接为空，无法分析')
    return
  }

  isAnalyzing.value = true
  try {
    const transcriptions = await getVoiceText([{ audio_url: audioUrl }])
    const transcript = transcriptions?.[0]?.value?.trim() || ''

    if (transcript) {
      const hasExistingContent = topicDetails.copywriting?.trim()
      topicDetails.copywriting = hasExistingContent
        ? `${topicDetails.copywriting}\n\n${transcript}`
        : transcript
    } else {
      message.warning('未获取到可用文案')
    }
  } catch (error) {
    console.error('分析语音失败:', error)
  } finally {
    isAnalyzing.value = false
  }
}

// 选择话题
function handleSelectTopic(topic) {
  selectedTopic.value = topic.id
}

// 创作处理
async function handleCreate(topic) {
  selectedTopic.value = topic.id

  if (topic.audioUrl?.trim()) {
    await analyzeVoice(topic.audioUrl)
  }
}

// 生成文案（流式）
async function handleGenerate() {
  if (!topicDetails.copywriting?.trim()) {
    message.warning('请输入文案内容')
    return
  }

  if (!selectedAgent.value?.id) {
    message.warning('请先选择文案风格')
    return
  }

  isGenerating.value = true
  generatedContent.value = ''

  try {
    const ctrl = new AbortController()
    let fullText = ''
    let completed = false

    await new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        if (!completed) {
          completed = true
          ctrl.abort()
          reject(new Error('请求超时'))
        }
      }, 180000)

      rewriteStream({
        agentId: selectedAgent.value.id,
        userText: topicDetails.copywriting.trim(),
        level: topicDetails.level,
        modelType: topicDetails.modelType,
        ctrl,
        onMessage: (data) => {
          if (completed) return

          // 处理 Dify 响应格式
          if (data.event === 'message' && data.content) {
            fullText += data.content
            generatedContent.value = fullText
          } else if (data.event === 'done') {
            completed = true
            clearTimeout(timeout)
            resolve()
          } else if (data.event === 'error') {
            completed = true
            clearTimeout(timeout)
            reject(new Error(data.errorMessage || '生成失败'))
          }
        },
        onError: (err) => {
          if (!completed) {
            completed = true
            clearTimeout(timeout)
            ctrl.abort()
            message.error(err?.message || '网络请求失败')
            reject(new Error(err?.message || '网络请求失败'))
          }
        },
        onClose: () => {
          if (!completed) {
            completed = true
            clearTimeout(timeout)
            resolve()
          }
        }
      })
    })

    generatedContent.value = fullText.trim()
    message.success('文案生成成功')
  } catch (error) {
    console.error('生成文案失败:', error)
    message.error('生成文案失败')
  } finally {
    isGenerating.value = false
  }
}

// 数据处理
function extractAudioUrl(video) {
  const urlList = video?.play_addr?.url_list
  if (Array.isArray(urlList) && urlList.length > 0) {
    const lastUrl = urlList[urlList.length - 1]?.trim()
    const firstUrl = urlList[0]?.trim()
    return lastUrl || firstUrl || ''
  }
  return video?.play_addr?.url?.trim() || ''
}

function extractCover(video) {
  return video?.origin_cover?.url_list?.[0]
    || video?.cover?.url_list?.[0]
    || video?.dynamic_cover?.url_list?.[0]
    || video?.animated_cover?.url_list?.[0]
    || ''
}

function processSearchResults(response, startId = 1) {
  try {
    // 保存分页信息用于下次请求
    const responseData = response?.data || {}
    currentCursor.value = responseData.cursor || null
    searchParams.search_id = responseData.search_id || ''
    searchParams.backtrace = responseData.backtrace || ''

    const dataList = responseData.data || []

    return dataList
      .map(el => el.aweme_info)
      .filter(Boolean)
      .map((item, index) => ({
        id: startId + index,
        title: item.desc || '无标题',
        videoId: item.aweme_id,
        videoUrl: `https://www.douyin.com/video/${item.aweme_id}`,
        audioUrl: extractAudioUrl(item.video),
        cover: extractCover(item.video) || item?.cover?.url_list?.[0] || '',
        author: item.author?.nickname || item.author?.unique_id || '未知',
        authorAvatar: item.author?.avatar_thumb?.url_list?.[0]
          || item.author?.avatar_larger?.url_list?.[0]
          || '',
        playCount: item.statistics?.play_count || 0,
        diggCount: item.statistics?.digg_count || 0,
        commentCount: item.statistics?.comment_count || 0,
        shareCount: item.statistics?.share_count || 0,
        collectCount: item.statistics?.collect_count || 0,
      }))
  } catch (error) {
    console.error('处理搜索结果失败:', error)
    return []
  }
}

// 搜索功能
async function handleSearch() {
  const keyword = searchKeyword.value.trim()
  if (!keyword) {
    message.warning('请输入搜索关键词')
    return
  }

  // 重置分页参数
  searchParams.keyword = keyword
  searchParams.cursor = 0
  searchParams.search_id = ''
  searchParams.backtrace = ''
  currentCursor.value = null
  hotTopics.value = []
  isLoading.value = true

  try {
    const urlParams = {
      keyword: searchParams.keyword,
      cursor: searchParams.cursor,
      sort_type: searchParams.sort_type,
      publish_time: searchParams.publish_time,
      filter_duration: searchParams.filter_duration,
      content_type: searchParams.content_type,
      search_id: searchParams.search_id,
      backtrace: searchParams.backtrace
    }

    const response = await TikhubService.postTikHup({
      type: InterfaceType.DOUYIN_SEARCH_GENERAL_SEARCH,
      methodType: MethodType.POST,
      urlParams,
      paramType: ParamType.JSON
    })

    const searchResults = processSearchResults(response)

    if (searchResults.length === 0) {
      message.warning('未找到相关结果')
      return
    }

    hotTopics.value = searchResults
    message.success(`找到 ${searchResults.length} 个结果`)
  } catch (error) {
    console.error('搜索失败:', error)
    message.error(error?.message || '搜索失败')
    hotTopics.value = []
  } finally {
    isLoading.value = false
  }
}

// 初始化
onMounted(() => {
  loadAgentList()
  pointsConfigStore.loadConfig()
})
</script>

<template>
  <div class="forecast-page">
    <!-- 左侧：热点搜索 -->
    <section class="search-panel">
      <div class="panel-header">
        <h2 class="panel-title">热点预测</h2>
      </div>

      <!-- 搜索栏 -->
      <div class="search-bar">
        <div class="search-input-wrap">
          <svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <circle cx="11" cy="11" r="8"/>
            <path d="M21 21l-4.35-4.35"/>
          </svg>
          <input
            v-model="searchKeyword"
            type="text"
            placeholder="搜索热门内容..."
            class="search-input"
            :disabled="isLoading"
            @keypress="handleSearchKeypress"
          />
        </div>
        <button
          @click="handleSearch"
          :disabled="isLoading || !searchKeyword.trim()"
          class="search-btn"
        >
          <span v-if="isLoading" class="btn-spinner"></span>
          <span v-else>搜索</span>
        </button>
      </div>

      <!-- 筛选器 -->
      <div class="filters-row">
        <div class="filter-item">
          <span class="filter-label">排序</span>
          <a-select v-model:value="searchParams.sort_type" size="small">
            <a-select-option value="0">综合</a-select-option>
            <a-select-option value="1">最多点赞</a-select-option>
            <a-select-option value="2">最新发布</a-select-option>
          </a-select>
        </div>
        <div class="filter-item">
          <span class="filter-label">时间</span>
          <a-select v-model:value="searchParams.publish_time" size="small">
            <a-select-option value="0">不限</a-select-option>
            <a-select-option value="1">一天</a-select-option>
            <a-select-option value="7">一周</a-select-option>
            <a-select-option value="180">半年</a-select-option>
          </a-select>
        </div>
        <div class="filter-item">
          <span class="filter-label">时长</span>
          <a-select v-model:value="searchParams.filter_duration" size="small">
            <a-select-option value="0">不限</a-select-option>
            <a-select-option value="0-1">1分钟内</a-select-option>
            <a-select-option value="1-5">1-5分钟</a-select-option>
            <a-select-option value="5-10000">5分钟+</a-select-option>
          </a-select>
        </div>
      </div>

      <!-- 结果列表 -->
      <div class="results-area">
        <!-- 空状态 -->
        <div v-if="hotTopics.length === 0 && !isLoading" class="empty-state">
          <svg class="empty-icon" viewBox="0 0 48 48" fill="none">
            <circle cx="20" cy="20" r="14" stroke="currentColor" stroke-width="2" opacity="0.3"/>
            <path d="M32 32L42 42" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.4"/>
          </svg>
          <p class="empty-text">搜索热门内容获取灵感</p>
        </div>

        <!-- 加载状态 -->
        <div v-else-if="isLoading" class="loading-state">
          <div class="loading-ring"></div>
          <span>搜索中</span>
        </div>

        <!-- 结果卡片 -->
        <div v-else class="topic-list">
          <div
            v-for="topic in hotTopics"
            :key="topic.id"
            @click="handleSelectTopic(topic)"
            class="topic-card"
            :class="{ selected: selectedTopic === topic.id }"
          >
            <div class="topic-cover">
              <img
                v-if="topic.cover"
                :src="topic.cover"
                alt=""
                @error="handleImageError"
              />
              <div v-else class="cover-fallback">
                <svg viewBox="0 0 24 24" fill="currentColor">
                  <path d="M4 4h16a2 2 0 012 2v12a2 2 0 01-2 2H4a2 2 0 01-2-2V6a2 2 0 012-2zm0 2v12h16V6H4zm6 2l5 4-5 4V8z"/>
                </svg>
              </div>
              <span class="topic-num">{{ topic.id }}</span>
            </div>

            <div class="topic-content">
              <h3 class="topic-title" @click.stop="openVideo(topic, $event)" :title="topic.title">
                {{ truncateTitle(topic.title, 32) }}
              </h3>
              <div class="topic-meta">
                <img v-if="topic.authorAvatar" :src="topic.authorAvatar" alt="" class="author-avatar" @error="handleImageError"/>
                <span class="author-name">{{ topic.author }}</span>
              </div>
              <div class="topic-stats">
                <span class="stat-item">
                  <svg viewBox="0 0 20 20" fill="currentColor"><path d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z"/></svg>
                  {{ formatNumber(topic.playCount) }}
                </span>
                <span class="stat-item">
                  <svg viewBox="0 0 20 20" fill="currentColor"><path d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.834a1 1 0 001.555.832L12 13.202a5 5 0 001.196-.599l.707-.707a1 1 0 00.293-.707V8.465a1 1 0 00-1.707-.707L12 8.465V5a2 2 0 00-2-2H7a1 1 0 000 2h3v3z"/></svg>
                  {{ formatNumber(topic.diggCount) }}
                </span>
              </div>
            </div>

            <button class="action-btn" @click.stop="handleCreate(topic)" title="提取文案">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M12 5v14M5 12h14"/>
              </svg>
            </button>
          </div>
        </div>
      </div>
    </section>

    <!-- 右侧：创作工具 -->
    <section class="create-panel">
      <div class="panel-header">
        <h2 class="panel-title">创作工具</h2>
      </div>

      <div class="create-form">
        <!-- 文案输入 -->
        <div class="form-block">
          <div class="block-header">
            <label>文案内容</label>
            <span v-if="isAnalyzing" class="status-tag analyzing">
              <span class="tag-dot"></span>
              分析中
            </span>
          </div>
          <a-textarea
            v-model:value="topicDetails.copywriting"
            :rows="5"
            placeholder="输入文案或点击热点卡片自动提取..."
            :disabled="isAnalyzing"
            class="content-input"
          />
        </div>

        <!-- 风格选择 -->
        <div class="form-block">
          <label>文案风格</label>
          <a-select
            v-model:value="topicDetails.selectedAgentId"
            placeholder="选择风格"
            style="width: 100%"
            :loading="loadingAgents"
            show-search
            :filter-option="false"
            @change="handleAgentChange"
            @search="agentSearchKeyword = $event"
          >
            <a-select-option
              v-for="agent in filteredAgentList"
              :key="agent.id"
              :value="agent.id"
            >
              <span>{{ agent.name }}</span>
              <span class="agent-category">{{ agent.categoryName }}</span>
            </a-select-option>
          </a-select>
        </div>

        <!-- 模式 & 幅度 -->
        <div class="form-row">
          <div class="form-block half">
            <label>生成模式</label>
            <div class="mode-switch">
              <button
                :class="['mode-btn', { active: topicDetails.modelType === 'forecast_standard' }]"
                @click="topicDetails.modelType = 'forecast_standard'"
              >标准</button>
              <button
                :class="['mode-btn', { active: topicDetails.modelType === 'forecast_pro' }]"
                @click="topicDetails.modelType = 'forecast_pro'"
              >PRO</button>
            </div>
          </div>
          <div class="form-block half">
            <div class="block-header">
              <label>改写幅度</label>
              <span class="level-num">{{ topicDetails.level }}%</span>
            </div>
            <input
              type="range"
              v-model.number="topicDetails.level"
              min="10"
              max="100"
              step="10"
              class="level-slider"
            />
          </div>
        </div>

        <!-- 生成按钮 -->
        <button
          class="generate-btn"
          :class="{ loading: isGenerating }"
          :disabled="!topicDetails.copywriting?.trim() || !topicDetails.selectedAgentId || isGenerating"
          @click="handleGenerate"
        >
          <template v-if="isGenerating">
            <span class="btn-spinner light"></span>
            <span>生成中</span>
          </template>
          <template v-else>
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/>
            </svg>
            <span>生成爆款</span>
          </template>
        </button>
        <p class="points-hint">生成爆款文案将消耗积分</p>

        <!-- 生成结果 -->
        <Transition name="slide-up">
          <div v-if="generatedContent" class="result-block">
            <div class="result-header">
              <span class="result-title">生成结果</span>
              <button class="copy-btn" @click="copyContent">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                  <rect x="9" y="9" width="13" height="13" rx="2"/>
                  <path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/>
                </svg>
                复制
              </button>
            </div>
            <div class="result-content">{{ generatedContent }}</div>
          </div>
        </Transition>
      </div>
    </section>
  </div>
</template>

<style scoped lang="less">
// 使用设计系统变量
// 主色: var(--color-primary-500) = #3B82F6

// 页面布局
.forecast-page {
  display: grid;
  grid-template-columns: 1fr 400px;
  gap: var(--space-4);
  height: 100%;
  background: var(--color-gray-50);
}

// 面板基础
.search-panel,
.create-panel {
  background: var(--color-bg-card);
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.panel-header {
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-gray-200);
}

.panel-title {
  font-size: var(--font-size-md);
  font-weight: 600;
  color: var(--color-gray-900);
  margin: 0;
  letter-spacing: -0.01em;
}

// ========== 搜索面板 ==========
.search-bar {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
}

.search-input-wrap {
  flex: 1;
  position: relative;
}

.search-icon {
  position: absolute;
  left: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  color: var(--color-gray-400);
  pointer-events: none;
}

.search-input {
  width: 100%;
  height: 38px;
  padding: 0 var(--space-3) 0 38px;
  font-size: var(--font-size-base);
  color: var(--color-gray-900);
  background: var(--color-gray-50);
  border: 1px solid var(--color-gray-300);
  border-radius: var(--radius-base);
  transition: all var(--duration-fast);

  &::placeholder { color: var(--color-gray-400); }
  &:focus {
    outline: none;
    border-color: var(--color-primary-500);
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
  }
  &:disabled { opacity: 0.5; }
}

.search-btn {
  padding: 0 18px;
  height: 38px;
  font-size: var(--font-size-base);
  font-weight: 500;
  color: #fff;
  background: var(--color-primary-500);
  border: none;
  border-radius: var(--radius-base);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  transition: all var(--duration-fast);

  &:hover:not(:disabled) { background: var(--color-primary-400); }
  &:disabled { opacity: 0.5; cursor: not-allowed; }
}

.btn-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(255,255,255,0.3);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 0.6s linear infinite;

  &.light {
    border-color: rgba(255,255,255,0.2);
    border-top-color: #fff;
  }
}

// 筛选器
.filters-row {
  display: flex;
  gap: var(--space-3);
  padding: 0 var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--color-gray-200);
}

.filter-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.filter-label {
  font-size: var(--font-size-xs);
  color: var(--color-gray-400);
}

:deep(.ant-select) {
  width: 88px;

  .ant-select-selector {
    background: var(--color-gray-50) !important;
    border-color: var(--color-gray-300) !important;
    border-radius: var(--radius-base) !important;
    height: 26px !important;

    .ant-select-selection-item {
      color: var(--color-gray-900) !important;
      font-size: var(--font-size-xs) !important;
      line-height: 24px !important;
    }
  }
}

// 结果区域
.results-area {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-3);

  &::-webkit-scrollbar { width: 4px; }
  &::-webkit-scrollbar-track { background: transparent; }
  &::-webkit-scrollbar-thumb { background: var(--color-gray-300); border-radius: 2px; }
}

// 空状态
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px var(--space-5);
}

.empty-icon {
  width: 48px;
  height: 48px;
  color: var(--color-gray-400);
  margin-bottom: var(--space-3);
  opacity: 0.6;
}

.empty-text {
  font-size: var(--font-size-base);
  color: var(--color-gray-600);
  margin: 0;
}

// 加载状态
.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px var(--space-5);
  gap: var(--space-3);
  color: var(--color-gray-600);
  font-size: var(--font-size-sm);
}

.loading-ring {
  width: 28px;
  height: 28px;
  border: 2px solid var(--color-gray-300);
  border-top-color: var(--color-primary-500);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

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

// 热点卡片
.topic-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.topic-card {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  background: var(--color-bg-card);
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all var(--duration-fast);

  &:hover {
    border-color: var(--color-gray-300);
    box-shadow: var(--shadow-md);
  }

  &.selected {
    border-color: var(--color-primary-500);
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
  }
}

.topic-cover {
  position: relative;
  flex-shrink: 0;
  width: 88px;
  height: 50px;
  background: var(--color-gray-50);
  border-radius: var(--radius-base);
  overflow: hidden;

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

  .cover-fallback {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-gray-400);

    svg { width: 20px; height: 20px; opacity: 0.4; }
  }
}

.topic-num {
  position: absolute;
  top: var(--space-1);
  left: var(--space-1);
  min-width: 16px;
  height: 16px;
  padding: 0 var(--space-1);
  font-size: 10px;
  font-weight: 600;
  color: #fff;
  background: rgba(0, 0, 0, 0.6);
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.topic-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.topic-title {
  font-size: var(--font-size-sm);
  font-weight: 500;
  color: var(--color-gray-900);
  margin: 0;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  cursor: pointer;
  transition: color var(--duration-fast);

  &:hover { color: var(--color-primary-500); }
}

.topic-meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.author-avatar {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  object-fit: cover;
}

.author-name {
  font-size: 11px;
  color: var(--color-gray-600);
}

.topic-stats {
  display: flex;
  gap: 10px;
}

.stat-item {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  color: var(--color-gray-500);

  svg { width: 11px; height: 11px; }
}

.action-btn {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-primary-500);
  background: rgba(59, 130, 246, 0.1);
  border: none;
  border-radius: var(--radius-base);
  cursor: pointer;
  transition: all var(--duration-fast);

  svg { width: 16px; height: 16px; }

  &:hover {
    background: var(--color-primary-500);
    color: #fff;
  }
}

// ========== 创作面板 ==========
.create-form {
  flex: 1;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overflow-y: auto;

  &::-webkit-scrollbar { width: 4px; }
  &::-webkit-scrollbar-track { background: transparent; }
  &::-webkit-scrollbar-thumb { background: var(--color-gray-300); border-radius: 2px; }
}

.form-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);

  &.half { flex: 1; }

  label {
    font-size: var(--font-size-xs);
    font-weight: 500;
    color: var(--color-gray-600);
  }
}

.block-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.status-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  color: var(--color-primary-500);

  &.analyzing .tag-dot {
    width: 5px;
    height: 5px;
    background: var(--color-primary-500);
    border-radius: 50%;
    animation: pulse 1s ease-in-out infinite;
  }
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

.content-input {
  :deep(.ant-input) {
    background: var(--color-gray-50) !important;
    border-color: var(--color-gray-300) !important;
    color: var(--color-gray-900) !important;
    border-radius: var(--radius-base) !important;
    font-size: var(--font-size-sm) !important;
    line-height: 1.6 !important;

    &::placeholder { color: var(--color-gray-400) !important; }
    &:focus {
      border-color: var(--color-primary-500) !important;
      box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1) !important;
    }
  }
}

// 下拉选择器
:deep(.ant-select) {
  .ant-select-selector {
    background: var(--color-gray-50) !important;
    border-color: var(--color-gray-300) !important;
    border-radius: var(--radius-base) !important;
    height: 36px !important;

    .ant-select-selection-item,
    .ant-select-selection-placeholder {
      color: var(--color-gray-900) !important;
      font-size: var(--font-size-sm) !important;
      line-height: 34px !important;
    }
  }

  &.ant-select-focused .ant-select-selector {
    border-color: var(--color-primary-500) !important;
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1) !important;
  }
}

.agent-category {
  margin-left: var(--space-2);
  font-size: 11px;
  color: var(--color-gray-500);
}

// 表单行
.form-row {
  display: flex;
  gap: var(--space-3);
}

// 模式切换
.mode-switch {
  display: flex;
  gap: var(--space-2);
}

.mode-btn {
  flex: 1;
  height: 36px;
  font-size: var(--font-size-sm);
  font-weight: 500;
  color: var(--color-gray-600);
  background: var(--color-gray-50);
  border: 1px solid var(--color-gray-300);
  border-radius: var(--radius-base);
  cursor: pointer;
  transition: all var(--duration-fast);

  &:hover { border-color: var(--color-gray-200); color: var(--color-gray-900); }
  &.active {
    color: #fff;
    background: var(--color-primary-500);
    border-color: var(--color-primary-500);
  }
}

// 幅度滑块
.level-num {
  font-size: var(--font-size-xs);
  font-weight: 600;
  color: var(--color-primary-500);
}

.level-slider {
  width: 100%;
  height: 4px;
  -webkit-appearance: none;
  appearance: none;
  background: var(--color-gray-50);
  border-radius: 2px;
  outline: none;

  &::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    background: var(--color-primary-500);
    border-radius: 50%;
    cursor: pointer;
    transition: transform var(--duration-fast), box-shadow var(--duration-fast);

    &:hover {
      transform: scale(1.15);
      box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.15);
    }
  }
}

// 生成按钮
.generate-btn {
  width: 100%;
  height: 44px;
  font-size: var(--font-size-base);
  font-weight: 600;
  color: #fff;
  background: var(--color-primary-500);
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  transition: all var(--duration-fast);
  margin-top: auto;

  svg { width: 16px; height: 16px; }

  &:hover:not(:disabled) {
    background: var(--color-primary-400);
    transform: translateY(-1px);
    box-shadow: 0 6px 20px rgba(59, 130, 246, 0.15);
  }

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

  &.loading {
    background: var(--color-primary-500);
  }
}

.points-hint {
  text-align: center;
  font-size: var(--font-size-xs);
  color: var(--color-gray-500);
  margin: var(--space-2) 0 0;
}

// 结果区域
.result-block {
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-gray-200);
}

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

.result-title {
  font-size: var(--font-size-xs);
  font-weight: 500;
  color: var(--color-gray-600);
}

.copy-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) 10px;
  font-size: var(--font-size-xs);
  color: var(--color-gray-600);
  background: var(--color-gray-50);
  border: 1px solid var(--color-gray-300);
  border-radius: var(--radius-base);
  cursor: pointer;
  transition: all var(--duration-fast);

  svg { width: 12px; height: 12px; }

  &:hover {
    color: var(--color-gray-900);
    border-color: var(--color-gray-500);
  }
}

.result-content {
  padding: 14px;
  font-size: var(--font-size-sm);
  line-height: 1.7;
  color: var(--color-gray-900);
  background: var(--color-gray-50);
  border-radius: var(--radius-base);
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: 240px;
  overflow-y: auto;

  &::-webkit-scrollbar { width: 4px; }
  &::-webkit-scrollbar-track { background: transparent; }
  &::-webkit-scrollbar-thumb { background: var(--color-gray-300); border-radius: 2px; }
}

// 过渡动画
.slide-up-enter-active,
.slide-up-leave-active {
  transition: all 0.25s ease;
}

.slide-up-enter-from,
.slide-up-leave-to {
  opacity: 0;
  transform: translateY(-8px);
}

// 响应式
@media (max-width: 900px) {
  .forecast-page {
    grid-template-columns: 1fr;
  }

  .create-panel {
    min-height: 400px;
  }
}
</style>
