<script setup>
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router';
import axios from 'axios';
import {
  BAILIAN_API_KEY,
  BAILIAN_ASR_SUBMIT_URL,
  BAILIAN_ASR_QUERY_BASE_URL,
  BAILIAN_ASR_MODEL,
  DOUBAO_KEY,
  AUDIO_TEXT_OPTIMIZE_API_URL,
  AUDIO_TEXT_OPTIMIZE_MODEL,
  AUDIO_TEXT_OPTIMIZE_TEMPERATURE,
  AUDIO_TEXT_OPTIMIZE_MAX_TOKENS,
  AUDIO_TEXT_OPTIMIZE_PROMPT
} from '@/config/index.js';

const router = useRouter();

// 状态管理
const audioUrl = ref('');
const taskId = ref('');
const taskStatus = ref(''); // PENDING, RUNNING, SUCCEEDED, FAILED
const statusText = ref('');
const transcriptionResult = ref('');
const isLoading = ref(false);
const errorMessage = ref('');
const progress = ref(0);

// 优化相关状态
const isOptimizing = ref(false);
const optimizedResult = ref('');
const showOptimized = ref(false);
const cancelTokenSource = ref(null);

// 示例音频URL
const exampleUrls = [
  'https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_female2.wav',
  'https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_male2.wav'
];

// 当前显示的结果（原始或优化后）
const displayResult = computed(() => {
  return showOptimized.value && optimizedResult.value 
    ? optimizedResult.value 
    : transcriptionResult.value;
});

// 提交识别任务
const submitTask = async () => {
  if (!audioUrl.value.trim()) {
    errorMessage.value = '请输入音频文件URL';
    return;
  }

  // 重置状态
  errorMessage.value = '';
  taskId.value = '';
  taskStatus.value = '';
  statusText.value = '';
  transcriptionResult.value = '';
  progress.value = 0;
  isLoading.value = true;
  optimizedResult.value = '';
  showOptimized.value = false;

  try {
    // 提交任务
    const response = await axios.post(
      BAILIAN_ASR_SUBMIT_URL,
      {
        model: BAILIAN_ASR_MODEL,
        input: {
          file_urls: [audioUrl.value.trim()]
        }
      },
      {
        headers: {
          'Authorization': `Bearer ${BAILIAN_API_KEY}`,
          'Content-Type': 'application/json',
          'X-DashScope-Async': 'enable'
        }
      }
    );

    if (response.data.output && response.data.output.task_id) {
      taskId.value = response.data.output.task_id;
      taskStatus.value = response.data.output.task_status || 'PENDING';
      statusText.value = '任务已提交，正在排队处理...';
      progress.value = 10;
      
      // 开始轮询查询
      await pollTaskStatus();
    } else {
      throw new Error('未获取到任务ID');
    }
  } catch (error) {
    console.error('提交任务失败:', error);
    errorMessage.value = error.response?.data?.message || error.message || '提交任务失败，请检查URL是否正确';
    isLoading.value = false;
  }
};

// 轮询查询任务状态
const pollTaskStatus = async () => {
  const maxAttempts = 300; // 最大轮询次数（300 * 2秒 = 10分钟）
  let attempts = 0;

  const poll = async () => {
    try {
      const response = await axios.post(
        `${BAILIAN_ASR_QUERY_BASE_URL}/${taskId.value}`,
        {},
        {
          headers: {
            'Authorization': `Bearer ${BAILIAN_API_KEY}`,
            'Content-Type': 'application/json'
          }
        }
      );

      const output = response.data.output;
      taskStatus.value = output.task_status;

      if (output.task_status === 'PENDING') {
        statusText.value = '排队中，请稍候...';
        progress.value = 20;
        attempts++;
        if (attempts < maxAttempts) {
          setTimeout(poll, 2000);
        } else {
          errorMessage.value = '任务超时，请稍后重试';
          isLoading.value = false;
        }
      } else if (output.task_status === 'RUNNING') {
        statusText.value = '正在处理音频，请稍候...';
        progress.value = 50;
        attempts++;
        if (attempts < maxAttempts) {
          setTimeout(poll, 2000);
        } else {
          errorMessage.value = '任务超时，请稍后重试';
          isLoading.value = false;
        }
      } else if (output.task_status === 'SUCCEEDED') {
        statusText.value = '识别完成！';
        progress.value = 90;
        
        // 获取识别结果
        if (output.results && output.results[0] && output.results[0].transcription_url) {
          await fetchTranscriptionResult(output.results[0].transcription_url);
        } else {
          errorMessage.value = '未找到识别结果';
          isLoading.value = false;
        }
      } else if (output.task_status === 'FAILED') {
        const errorMsg = output.results?.[0]?.message || '任务处理失败';
        errorMessage.value = errorMsg;
        isLoading.value = false;
      }
    } catch (error) {
      console.error('查询任务状态失败:', error);
      errorMessage.value = error.response?.data?.message || '查询任务状态失败';
      isLoading.value = false;
    }
  };

  await poll();
};

// 获取识别结果
const fetchTranscriptionResult = async (transcriptionUrl) => {
  try {
    const response = await axios.get(transcriptionUrl);
    const data = response.data;
    
    // 提取识别文本
    if (data.transcripts && data.transcripts[0]) {
      transcriptionResult.value = data.transcripts[0].text || '未识别到文本内容';
      
      // 添加更多详细信息
      if (data.properties) {
        const duration = data.properties.original_duration_in_milliseconds;
        const durationSec = (duration / 1000).toFixed(1);
        transcriptionResult.value += `\n\n[音频时长: ${durationSec}秒]`;
      }
    } else {
      transcriptionResult.value = '未识别到文本内容';
    }
    
    progress.value = 100;
    isLoading.value = false;
  } catch (error) {
    console.error('获取识别结果失败:', error);
    errorMessage.value = '获取识别结果失败';
    isLoading.value = false;
  }
};

// AI优化排版
const optimizeText = async () => {
  if (!transcriptionResult.value || isOptimizing.value) return;
  
  isOptimizing.value = true;
  optimizedResult.value = '';
  showOptimized.value = true;
  
  // 创建取消令牌
  cancelTokenSource.value = axios.CancelToken.source();
  
  const requestBody = {
    model: AUDIO_TEXT_OPTIMIZE_MODEL,
    messages: [
      { role: 'system', content: AUDIO_TEXT_OPTIMIZE_PROMPT },
      { role: 'user', content: transcriptionResult.value }
    ],
    temperature: AUDIO_TEXT_OPTIMIZE_TEMPERATURE,
    max_tokens: AUDIO_TEXT_OPTIMIZE_MAX_TOKENS,
    stream: true
  };
  
  let lastLength = 0;
  
  try {
    await axios.post(AUDIO_TEXT_OPTIMIZE_API_URL, requestBody, {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${DOUBAO_KEY}`
      },
      responseType: 'text',
      cancelToken: cancelTokenSource.value.token,
      onDownloadProgress: (event) => {
        const text = (event.target || event.event?.target)?.responseText || '';
        if (!text) return;
        
        const newChunk = text.slice(lastLength);
        lastLength = text.length;
        
        // 解析 SSE 数据
        const lines = newChunk.split('\n');
        for (const line of lines) {
          if (!line.startsWith('data: ')) continue;
          const jsonStr = line.slice(6).trim();
          if (!jsonStr || jsonStr === '[DONE]') continue;
          
          try {
            const data = JSON.parse(jsonStr);
            const delta = data?.choices?.[0]?.delta?.content;
            if (delta) {
              optimizedResult.value += delta;
            }
          } catch {
            // 忽略解析失败的行
          }
        }
      }
    });
  } catch (error) {
    if (axios.isCancel(error)) {
      console.log('优化已取消');
    } else {
      console.error('优化失败:', error);
      errorMessage.value = 'AI优化失败，请重试';
      showOptimized.value = false;
    }
  } finally {
    isOptimizing.value = false;
    cancelTokenSource.value = null;
  }
};

// 切换显示原始/优化结果
const toggleResult = () => {
  showOptimized.value = !showOptimized.value;
};

// 使用示例URL
const useExample = (url) => {
  audioUrl.value = url;
};

// 跳转到第三方上传平台
const goToUploadPlatform = () => {
  window.open('https://imgbed.cn/', '_blank');
};

// 返回首页
const goBack = () => {
  router.push('/');
};

// 复制结果
const copyResult = async () => {
  if (!displayResult.value) return;
  
  try {
    await navigator.clipboard.writeText(displayResult.value);
    alert('已复制到剪贴板');
  } catch (error) {
    console.error('复制失败:', error);
  }
};

// 清空重新开始
const reset = () => {
  audioUrl.value = '';
  taskId.value = '';
  taskStatus.value = '';
  statusText.value = '';
  transcriptionResult.value = '';
  isLoading.value = false;
  errorMessage.value = '';
  progress.value = 0;
  optimizedResult.value = '';
  showOptimized.value = false;
  isOptimizing.value = false;
};
</script>

<template>
  <div class="page-container">
    <!-- Nav Bar -->
    <div class="nav-bar">
      <button class="back-btn" @click="goBack">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
          <polyline points="15 18 9 12 15 6" />
        </svg>
        <span>返回</span>
      </button>
      <h1 class="nav-title">音频转文字</h1>
      <div style="width: 72px"></div>
    </div>

    <!-- Error Banner -->
    <div v-if="errorMessage" class="error-banner">
      <span>{{ errorMessage }}</span>
      <button class="error-close" @click="errorMessage = ''">✕</button>
    </div>

    <!-- Main Layout: Left + Right -->
    <div class="main-layout">
      <!-- Left Panel: Input -->
      <div class="left-panel">
        <!-- Input Card -->
        <div class="input-card">
          <div class="input-section">
            <label for="audio-url">音频文件URL</label>
            <textarea
              id="audio-url"
              v-model="audioUrl"
              placeholder="请输入公网可访问的音频文件URL&#10;支持 MP3、WAV、M4A 等格式"
              :disabled="isLoading"
              rows="6"
            ></textarea>
            
            <div class="example-links">
              <span>示例：</span>
              <button
                v-for="(url, index) in exampleUrls"
                :key="index"
                @click="useExample(url)"
                class="example-btn"
                :disabled="isLoading"
              >
                示例 {{ index + 1 }}
              </button>
            </div>
            
            <!-- 跳转到第三方上传平台 -->
            <div class="upload-tip">
              <span class="tip-text">没有音频URL？</span>
              <button @click="goToUploadPlatform" class="upload-btn" :disabled="isLoading">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
                  <polyline points="17 8 12 3 7 8" />
                  <line x1="12" y1="3" x2="12" y2="15" />
                </svg>
                前往上传音频
              </button>
            </div>
          </div>

          <!-- 状态显示 -->
          <div v-if="isLoading || taskStatus" class="status-section">
            <div class="progress-bar">
              <div class="progress-fill" :style="{ width: `${progress}%` }"></div>
            </div>
            <p class="status-text">{{ statusText }}</p>
          </div>
        </div>

        <!-- Action Buttons -->
        <div class="btn-wrap">
          <button @click="submitTask" :disabled="isLoading || !audioUrl.trim()" class="submit-btn">
            <span v-if="isLoading" class="btn-spinner"></span>
            <svg v-else width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
              <path stroke-linecap="round" stroke-linejoin="round" d="M5.25 5.653c0-.856.917-1.398 1.667-.986l11.54 6.347a1.125 1.125 0 010 1.972l-11.54 6.347a1.125 1.125 0 01-1.667-.986V5.653z" />
            </svg>
            <span>{{ isLoading ? '识别中...' : '开始识别' }}</span>
          </button>
          <button v-if="transcriptionResult" @click="reset" class="reset-btn">
            重新开始
          </button>
        </div>
      </div>

      <!-- Right Panel: Result -->
      <div class="right-panel">
        <!-- Empty State -->
        <div v-if="!transcriptionResult" class="empty-state">
          <div class="empty-icon">
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round">
              <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" />
              <path d="M19 10v2a7 7 0 0 1-14 0v-2" />
              <line x1="12" y1="19" x2="12" y2="23" />
              <line x1="8" y1="23" x2="16" y2="23" />
            </svg>
          </div>
          <p class="empty-title">等待识别</p>
          <p class="empty-hint">在左侧输入音频URL，点击「开始识别」</p>
          
          <div class="tips-section">
            <h4>使用说明</h4>
            <ul>
              <li>支持音频格式：MP3、WAV、M4A、FLAC、OGG 等</li>
              <li>音频文件需通过公网URL访问</li>
              <li>支持中文、英文、日语自动识别</li>
              <li>音频时长最长支持12小时</li>
            </ul>
          </div>
        </div>

        <!-- Result Area -->
        <div v-else class="result-area">
          <div class="result-header">
            <div class="result-title-wrap">
              <div class="result-dot" :class="{ pulse: isLoading || isOptimizing }"></div>
              <span class="result-title">
                <template v-if="isLoading">正在识别...</template>
                <template v-else-if="isOptimizing">AI优化中...</template>
                <template v-else>{{ showOptimized ? '优化结果' : '识别完成' }}</template>
              </span>
            </div>
            <div class="result-actions">
              <!-- 原始/优化结果切换 -->
              <button 
                v-if="optimizedResult && !isOptimizing" 
                @click="toggleResult" 
                class="toggle-btn"
                :class="{ active: showOptimized }"
              >
                <svg v-if="showOptimized" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
                  <circle cx="12" cy="12" r="3" />
                </svg>
                <svg v-else width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
                </svg>
                {{ showOptimized ? '查看原文' : '查看优化' }}
              </button>
              
              <!-- AI优化按钮 -->
              <button 
                v-if="!optimizedResult && !isOptimizing" 
                @click="optimizeText" 
                class="optimize-btn"
              >
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
                </svg>
                AI优化排版
              </button>
              
              <!-- 复制按钮 -->
              <button @click="copyResult" class="copy-btn">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
                  <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
                </svg>
                复制
              </button>
            </div>
          </div>

          <div class="result-card" :class="{ 'is-optimizing': isOptimizing }">
            <div class="result-content">
              {{ displayResult || '处理中...' }}
              <span v-if="isOptimizing" class="cursor-blink">|</span>
            </div>
          </div>
          
          <!-- 优化提示 -->
          <div v-if="showOptimized && !isOptimizing" class="optimize-tip">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
              <circle cx="12" cy="12" r="10" />
              <line x1="12" y1="16" x2="12" y2="12" />
              <line x1="12" y1="8" x2="12.01" y2="8" />
            </svg>
            <span>AI已优化文本的段落结构、标点符号和格式排版</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.page-container {
  height: 100vh;
  overflow: hidden;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  font-family: "Inter", "PingFang SC", -apple-system, sans-serif;
}

/* Nav */
.nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.5rem;
  background: rgba(255, 255, 255, 0.03);
  border-bottom: 1px solid var(--card-border);
  backdrop-filter: blur(12px);
  position: sticky;
  top: 0;
  z-index: 10;
}

.back-btn {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 0.95rem;
  padding: 0.4rem 0.75rem;
  border-radius: 8px;
  transition: all 0.2s;
}

.back-btn:hover {
  background: rgba(255, 255, 255, 0.07);
  color: var(--text-primary);
}

.nav-title {
  font-size: 1.2rem;
  font-weight: 600;
  margin: 0;
  background: linear-gradient(135deg, #8b5cf6, #7c3aed);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Main Layout */
.main-layout {
  flex: 1;
  min-height: 0;
  display: flex;
  overflow: hidden;
}

/* Left Panel */
.left-panel {
  width: 420px;
  min-width: 320px;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.5rem;
  border-right: 1px solid var(--card-border);
  overflow-y: auto;
  flex-shrink: 0;
}

/* Right Panel */
.right-panel {
  flex: 1;
  overflow-y: auto;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
}

/* 自定义滚动条 */
.right-panel::-webkit-scrollbar {
  width: 8px;
}

.right-panel::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.1);
  border-radius: 4px;
  margin: 4px 0;
}

.right-panel::-webkit-scrollbar-thumb {
  background: rgba(139, 92, 246, 0.3);
  border-radius: 4px;
  transition: background 0.2s;
}

.right-panel::-webkit-scrollbar-thumb:hover {
  background: rgba(139, 92, 246, 0.5);
}

.right-panel::-webkit-scrollbar-thumb:active {
  background: rgba(139, 92, 246, 0.7);
}

/* Empty State */
.empty-state {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  color: var(--text-secondary);
}

.empty-icon {
  color: var(--text-secondary);
  opacity: 0.4;
  margin-bottom: 0.5rem;
}

.empty-title {
  font-size: 1.1rem;
  font-weight: 600;
  margin: 0;
  color: var(--text-primary);
}

.empty-hint {
  font-size: 0.9rem;
  margin: 0 0 2rem 0;
  text-align: center;
  opacity: 0.7;
}

/* Error Banner */
.error-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: rgba(239, 68, 68, 0.12);
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-bottom: 1px solid rgba(239, 68, 68, 0.3);
  padding: 0.75rem 1.5rem;
  color: #fca5a5;
  font-size: 0.9rem;
  animation: fadeInUp 0.2s ease;
  flex-shrink: 0;
}

.error-close {
  background: none;
  border: none;
  color: #fca5a5;
  cursor: pointer;
  font-size: 1rem;
  opacity: 0.7;
  transition: opacity 0.2s;
}

.error-close:hover {
  opacity: 1;
}

/* Input Card */
.input-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--card-border);
  border-radius: 20px;
  overflow: hidden;
  backdrop-filter: blur(12px);
  padding: 1.25rem;
}

.input-section {
  display: flex;
  flex-direction: column;
  flex: 1;
}

.input-section label {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--text-primary);
  margin-bottom: 0.75rem;
}

.input-section textarea {
  width: 100%;
  flex: 1;
  min-height: 180px;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  color: var(--text-primary);
  font-size: 0.95rem;
  line-height: 1.7;
  padding: 1rem;
  resize: none;
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
  box-sizing: border-box;
  font-family: inherit;
}

.input-section textarea::placeholder {
  color: var(--text-secondary);
  opacity: 0.6;
}

.input-section textarea:focus {
  border-color: rgba(139, 92, 246, 0.5);
  box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1);
}

.input-section textarea:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.example-links {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1rem;
}

.example-links span {
  color: var(--text-secondary);
  font-size: 0.85rem;
}

.example-btn {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  background: rgba(139, 92, 246, 0.1);
  border: 1px solid rgba(139, 92, 246, 0.25);
  color: #a78bfa;
  border-radius: 8px;
  padding: 0.35rem 0.85rem;
  font-size: 0.85rem;
  cursor: pointer;
  transition: all 0.2s;
}

.example-btn:hover:not(:disabled) {
  background: rgba(139, 92, 246, 0.2);
  transform: translateY(-1px);
}

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

/* Upload Tip */
.upload-tip {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1rem;
  padding: 0.875rem 1rem;
  background: rgba(59, 130, 246, 0.08);
  border: 1px solid rgba(59, 130, 246, 0.2);
  border-radius: 10px;
}

.tip-text {
  color: var(--text-secondary);
  font-size: 0.85rem;
}

.upload-btn {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  background: rgba(59, 130, 246, 0.15);
  border: 1px solid rgba(59, 130, 246, 0.3);
  color: #60a5fa;
  border-radius: 8px;
  padding: 0.4rem 0.9rem;
  font-size: 0.85rem;
  cursor: pointer;
  transition: all 0.2s;
  margin-left: auto;
}

.upload-btn:hover:not(:disabled) {
  background: rgba(59, 130, 246, 0.25);
  transform: translateY(-1px);
}

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

/* Status Section */
.status-section {
  margin-top: 1rem;
  padding: 1rem;
  background: rgba(139, 92, 246, 0.05);
  border: 1px solid rgba(139, 92, 246, 0.2);
  border-radius: 12px;
}

.progress-bar {
  width: 100%;
  height: 6px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 0.75rem;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #8b5cf6 0%, #7c3aed 100%);
  transition: width 0.3s ease;
}

.status-text {
  margin: 0;
  color: #a78bfa;
  font-size: 0.9rem;
  text-align: center;
}

/* Action Buttons */
.btn-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
}

.submit-btn {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: linear-gradient(135deg, #8b5cf6, #7c3aed);
  border: none;
  color: white;
  font-size: 1rem;
  font-weight: 600;
  padding: 0.875rem 2.5rem;
  border-radius: 50px;
  cursor: pointer;
  transition: all 0.25s;
  box-shadow: 0 4px 20px rgba(139, 92, 246, 0.35);
}

.submit-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 8px 28px rgba(139, 92, 246, 0.5);
}

.submit-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

.reset-btn {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: var(--text-secondary);
  font-size: 0.9rem;
  padding: 0.875rem 1.5rem;
  border-radius: 50px;
  cursor: pointer;
  transition: all 0.2s;
}

.reset-btn:hover {
  background: rgba(255, 255, 255, 0.1);
  color: var(--text-primary);
}

.btn-spinner {
  width: 18px;
  height: 18px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: white;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

/* Result Area */
.result-area {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  height: 100%;
}

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

.result-title-wrap {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.result-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #8b5cf6;
}

.result-dot.pulse {
  animation: pulse 1.2s ease-in-out infinite;
}

.result-title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-primary);
}

.result-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.optimize-btn {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  background: rgba(16, 185, 129, 0.1);
  border: 1px solid rgba(16, 185, 129, 0.25);
  color: #6ee7b7;
  border-radius: 8px;
  padding: 0.5rem 1rem;
  font-size: 0.85rem;
  cursor: pointer;
  transition: all 0.2s;
}

.optimize-btn:hover {
  background: rgba(16, 185, 129, 0.2);
  transform: translateY(-1px);
}

.toggle-btn {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  background: rgba(139, 92, 246, 0.1);
  border: 1px solid rgba(139, 92, 246, 0.25);
  color: #a78bfa;
  border-radius: 8px;
  padding: 0.5rem 1rem;
  font-size: 0.85rem;
  cursor: pointer;
  transition: all 0.2s;
}

.toggle-btn:hover {
  background: rgba(139, 92, 246, 0.2);
  transform: translateY(-1px);
}

.toggle-btn.active {
  background: rgba(16, 185, 129, 0.15);
  border-color: rgba(16, 185, 129, 0.3);
  color: #6ee7b7;
}

.copy-btn {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  background: rgba(139, 92, 246, 0.1);
  border: 1px solid rgba(139, 92, 246, 0.25);
  color: #a78bfa;
  border-radius: 8px;
  padding: 0.5rem 1rem;
  font-size: 0.85rem;
  cursor: pointer;
  transition: all 0.2s;
}

.copy-btn:hover {
  background: rgba(139, 92, 246, 0.2);
}

.result-card {
  flex: 1;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--card-border);
  border-radius: 16px;
  overflow: hidden;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.result-content {
  flex: 1;
  padding: 1.5rem;
  color: var(--text-primary);
  line-height: 1.8;
  white-space: pre-wrap;
  font-size: 1rem;
  overflow-y: auto;
}

/* result-content 滚动条样式 */
.result-content::-webkit-scrollbar {
  width: 6px;
}

.result-content::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.15);
  border-radius: 3px;
}

.result-content::-webkit-scrollbar-thumb {
  background: rgba(139, 92, 246, 0.35);
  border-radius: 3px;
  transition: background 0.2s;
}

.result-content::-webkit-scrollbar-thumb:hover {
  background: rgba(139, 92, 246, 0.55);
}

.result-content::-webkit-scrollbar-thumb:active {
  background: rgba(139, 92, 246, 0.75);
}

.result-card.is-optimizing {
  border-color: rgba(16, 185, 129, 0.3);
  box-shadow: 0 0 20px rgba(16, 185, 129, 0.1);
}

/* 光标闪烁动画 */
.cursor-blink {
  display: inline-block;
  color: #6ee7b7;
  font-weight: 300;
  animation: blink 0.8s step-end infinite;
  margin-left: 1px;
}

/* 优化提示 */
.optimize-tip {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
  background: rgba(16, 185, 129, 0.08);
  border: 1px solid rgba(16, 185, 129, 0.2);
  border-radius: 10px;
  color: #6ee7b7;
  font-size: 0.85rem;
  animation: fadeInUp 0.3s ease;
}

/* Tips Section */
.tips-section {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--card-border);
  border-radius: 16px;
  padding: 1.5rem;
  width: 100%;
  max-width: 600px;
  margin-top: 1rem;
}

.tips-section h4 {
  margin: 0 0 1rem;
  color: var(--text-primary);
  font-size: 1rem;
  font-weight: 600;
}

.tips-section ul {
  margin: 0;
  padding-left: 1.5rem;
  color: var(--text-secondary);
}

.tips-section li {
  margin: 0.6rem 0;
  line-height: 1.6;
  font-size: 0.9rem;
}

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

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

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

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

@media (max-width: 768px) {
  .main-layout {
    flex-direction: column;
    height: auto;
    overflow: visible;
  }

  .left-panel {
    width: 100%;
    max-width: 100%;
    border-right: none;
    border-bottom: 1px solid var(--card-border);
    overflow-y: visible;
  }

  .right-panel {
    padding: 1.25rem 1rem;
  }

  .submit-btn {
    padding: 0.875rem 1.75rem;
  }
}
</style>
