<template>
  <!-- 顶部锚点 -->
  <div id="top-anchor" class="top-anchor"></div>

  <!-- 主容器：包含对话框和main容器 -->
  <div class="page-container">
    <!-- 对话框区域 -->
    <div class="ai-emotion-container" ref="userInputDisplayRef">
      <!-- 金轮 -->
      <div class="golden-wheel">
        <img
          src="@/assets/img/AiEmotion/金轮.png"
          class="golden-wheel-img"
          alt="金轮图标"
          :class="{ 'rotating-image': isRotating }"
        />
      </div>

      <!-- 对话消息显示区域 -->
      <div
        class="conversation-area"
        v-if="messages.length > 0 && !isHistoryMode"
      >
        <div class="message-list">
          <div
            v-for="(message, index) in messages"
            :key="index"
            class="message-item"
            :class="{
              'user-message-item': message.sender === 'user',
              'ai-message-item': message.sender === 'ai',
            }"
          >
            <!-- 用户消息 -->
            <div v-if="message.sender === 'user'" class="user-message-wrapper">
              <div class="message-bubble user-message">
                {{ message.text }}
              </div>
            </div>

            <!-- AI消息（包括思考过程） -->
            <div v-else class="ai-message-wrapper">
              <div class="ai-message-container">
                <img
                  v-if="message.gif"
                  :src="message.gif"
                  alt="思考过程"
                  class="thinking-gif"
                />
                <div class="message-bubble ai-message">
                  <div v-if="message.flag">
                    <span>{{ message.text }}</span>
                    <span class="loading-dots">
                      <span class="dot">.</span>
                      <span class="dot">.</span>
                      <span class="dot">.</span>
                      <span class="dot">.</span>
                      <span class="dot">.</span>
                      <span class="dot">.</span>
                    </span>
                  </div>
                  <div v-else>
                    <div v-if="message.isHtml" v-html="message.text"></div>
                    <div v-else>{{ message.text }}</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 加载提示 -->
    <div v-if="isLoading" class="loading-container">
      <div class="loading-content">
        <div class="loading-spinner"></div>
        <div class="loading-text">AI情绪大模型正在努力为您加载，请稍候...</div>
      </div>
    </div>

    <!-- main容器区域 -->
    <!-- 移除股票标签页，改为对话形式展示 -->

    <!-- 渲染整个页面 - 遍历过滤后的股票列表显示所有股票 -->
    <div
      class="master"
      v-for="(stock, stockIndex) in filteredStockList"
      :key="`stock-${stockIndex}-${stock.timestamp}`"
      v-if="isPageLoaded"
    >
      <!-- 对应股票的消息显示区域 -->
      <div class="user-input-display">
        <div class="message-container">
          <!-- 显示该股票对应的用户输入内容 -->
          <div class="user-message-container">
            <div class="user-content">
              <img
                :src="
                  isVoice && getStockAudioState(stock).isPlaying
                    ? voice
                    : voiceNoActive
                "
                class="user-message-speaker"
                :class="{
                  'speaker-active':
                    isVoice && getStockAudioState(stock).isPlaying,
                }"
                @click="() => toggleVoiceForUser(stock)"
                alt="喇叭"
              />
              <div class="message-bubble user-message">
                {{ stock.queryText }}
              </div>
            </div>
            <div class="user-sendTime" v-if="isHistoryMode">
              {{ moment(stock.timestamp).format("YYYY-MM-DD HH:mm:ss") }}
            </div>
          </div>
        </div>
      </div>

      <div class="main">
        <div class="main-content-wrapper">
          <!-- 四维矩阵图 -->
          <div class="matrix-header">
            <!-- <img class="item" :src="item" alt="思维矩阵图片" /> -->
            <div class="market-temperature-label">
              {{ stock.stockInfo.name
              }}{{ stock.stockInfo.name ? "量子四维矩阵图" : "" }}
            </div>
            <div class="market-temperature-value">
              {{ getDisplayDate(stock) }}
            </div>
          </div>
          <div
            class="market-temperature-icon"
            v-if="chartVisibility.marketTemperature"
          >
            <img src="@/assets/img/AiEmotion/L1.png" alt="情绪监控图标" />
          </div>
          <!-- 温度计图表 -->
          <div
            class="market-temperature-section"
            v-if="chartVisibility.marketTemperature"
          >
            <div class="temperature-content">
              <div class="content1">
                <img src="@/assets/img/AiEmotion/温度计.png" alt="温度计图标" />
                <span class="matrix-main-title">股市温度计</span>
              </div>
              <div class="temperature-display">
                <div class="temperature-cold">
                  股票温度：{{ getStockData2(stock) ?? "NA" }}
                </div>
                <div class="temperature-hot">
                  市场温度：{{ getStockData1(stock) }}
                </div>
              </div>
            </div>
            <marketTemperature
              :ref="(el) => (marketTemperatureRef[stockIndex] = el)"
              :companyName="stock.stockInfo.name"
              :stockCode="stock.stockInfo.code"
            />
          </div>
        </div>
        <div class="emotion-decoder-icon" v-if="chartVisibility.emotionDecod">
          <img src="@/assets/img/AiEmotion/L2.png" alt="情绪解码图标" />
        </div>
        <!-- 情绪解码器图表 -->
        <div
          class="emotion-decoder-section"
          v-if="chartVisibility.emotionDecod"
        >
          <div class="emotion-decoder-header">
            <img
              src="@/assets/img/AiEmotion/emotionDecod.png"
              alt="情绪解码器图标"
            />
            <span class="emotion-decoder-text">情绪解码器</span>
          </div>
          <div class="emotion-decoder-content">
            <emotionDecod
              :ref="(el) => (emotionDecodRef[stockIndex] = el)"
            ></emotionDecod>
          </div>
        </div>
        <div
          class="bottom-radar-icon"
          v-if="chartVisibility.emotionalBottomRadar"
        >
          <img src="@/assets/img/AiEmotion/L3.png" alt="情绪推演图标" />
        </div>
        <!-- 情绪探底雷达图表 -->
        <div
          class="bottom-radar-section"
          v-if="chartVisibility.emotionalBottomRadar"
        >
          <div class="bottom-radar-header">
            <img src="@/assets/img/AiEmotion/探底雷达.png" alt="探底雷达图表" />
            <span class="bottom-radar-text">情绪探底雷达</span>
          </div>
          <div class="bottom-radar-content">
            <emotionalBottomRadar
              :ref="(el) => (emotionalBottomRadarRef[stockIndex] = el)"
            ></emotionalBottomRadar>
          </div>
        </div>
        <div
          class="energy-converter-icon"
          v-if="chartVisibility.emoEnergyConverter"
        >
          <img src="@/assets/img/AiEmotion/L4.png" alt="情绪套利" />
        </div>
        <!-- 情绪能量转化器图表 -->
        <div
          class="energy-converter-section"
          v-if="chartVisibility.emoEnergyConverter"
        >
          <div class="energy-converter-header">
            <img
              src="@/assets/img/AiEmotion/能量转化器.png"
              alt="能量转化器图标"
            />
            <span class="energy-converter-text">情绪能量转化器</span>
          </div>
          <div class="energy-converter-content">
            <emoEnergyConverter
              :ref="(el) => (emoEnergyConverterRef[stockIndex] = el)"
            ></emoEnergyConverter>
          </div>
        </div>
        <!-- 核心看点 -->
        <div class="core-highlights-header">
          <img src="@/assets/img/AiEmotion/核心看点.png" alt="核心看点字样" />
        </div>
        <div class="bk-image">
          <div class="text-container">
            <p>
              <span class="title">情绪监控-金融宇宙的【量子检测网络】</span>
              <span class="content"
                >核心任务:构建全市场情绪引力场雷达，实时监测资金流向和情绪波动</span
              >
            </p>
            <p>
              <span class="title">情绪解码-主力思维的【神经破译矩阵】</span>
              <span class="content"
                >核心任务:解构资金行为的量子密码，破译主力操盘意图和策略布局</span
              >
            </p>
            <p>
              <span class="title">情绪推演-未来战争的【时空推演舱】</span>
              <span class="content"
                >核心任务:基于情绪数据推演未来走势，预测市场转折点和机会窗口</span
              >
            </p>
            <p>
              <span class="title">情绪套利-财富裂变的【粒子对撞机】</span>
              <span class="content"
                >核心任务:将情绪差转化为收益粒子流，实现情绪能量的价值转换</span
              >
            </p>
          </div>
        </div>
        <!-- 核心逻辑 -->
        <div class="core-logic-header">
          <img src="@/assets/img/AiEmotion/核心逻辑.png" alt="核心逻辑字样" />
        </div>
        <div class="decision-tree-section">
          <div class="lz-img">
            <img src="@/assets/img/AiEmotion/量子神经决策树.png" alt="树标题" />
          </div>
          <div class="scaled-img">
            <!-- <img src="@/assets/img/AiEmotion/tree02.jpg" alt="树图片"> -->
          </div>
        </div>
        <!-- 场景应用 -->
        <div class="scenario-application-section" ref="scenarioApplicationRef">
          <img src="@/assets/img/AiEmotion/场景应用.png" alt="场景应用标题" />
          <div class="bk-image">
            <!-- 只有在状态准备好时才显示结论内容 -->
            <div class="conclusion-container" v-if="isStockStateReady(stock)">
              <!-- 使用当前股票项的结论数据显示内容，支持打字机效果 -->
              <!-- L1: 情绪监控 -->
              <div class="conclusion-item" v-if="(getStockTypewriterVisibility(stock) && getStockTypewriterVisibility(stock).one) || (getStockConclusion(stock) && !getStockTypewriterTexts(stock) && (getStockConclusion(stock).one1 || getStockConclusion(stock).one2))">
                <h4 class="conclusion-title">L1: 情绪监控</h4>
                <!-- 打字机效果文本 -->
                <p class="conclusion-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).one1">
                  {{ getStockTypewriterTexts(stock).one1 }}
                </p>
                <p class="conclusion-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).one2">
                  {{ getStockTypewriterTexts(stock).one2 }}
                </p>
                <!-- 完整文本 -->
                <p class="conclusion-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock) && getStockConclusion(stock).one1">
                  {{ getStockConclusion(stock).one1 }}
                </p>
                <p class="conclusion-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock) && getStockConclusion(stock).one2">
                  {{ getStockConclusion(stock).one2 }}
                </p>
              </div>
              <!-- L2: 情绪解码 -->
              <div class="conclusion-item" v-if="(getStockTypewriterVisibility(stock) && getStockTypewriterVisibility(stock).two) || (getStockConclusion(stock) && !getStockTypewriterTexts(stock) && getStockConclusion(stock).two)">
                <h4 class="conclusion-title">L2: 情绪解码</h4>
                <!-- 打字机效果文本 -->
                <p class="conclusion-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).two">
                  {{ getStockTypewriterTexts(stock).two }}
                </p>
                <!-- 完整文本 -->
                <p class="conclusion-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock) && getStockConclusion(stock).two">
                  {{ getStockConclusion(stock).two }}
                </p>
              </div>
              <!-- L3: 情绪推演 -->
              <div class="conclusion-item" v-if="(getStockTypewriterVisibility(stock) && getStockTypewriterVisibility(stock).three) || (getStockConclusion(stock) && !getStockTypewriterTexts(stock) && getStockConclusion(stock).three)">
                <h4 class="conclusion-title">L3: 情绪推演</h4>
                <!-- 打字机效果文本 -->
                <p class="conclusion-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).three">
                  {{ getStockTypewriterTexts(stock).three }}
                </p>
                <!-- 完整文本 -->
                <p class="conclusion-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock) && getStockConclusion(stock).three">
                  {{ getStockConclusion(stock).three }}
                </p>
              </div>
              <!-- L4: 情绪套利 -->
              <div class="conclusion-item" v-if="(getStockTypewriterVisibility(stock) && getStockTypewriterVisibility(stock).four) || (getStockConclusion(stock) && !getStockTypewriterTexts(stock) && getStockConclusion(stock).four)">
                <h4 class="conclusion-title">L4: 情绪套利</h4>
                <!-- 打字机效果文本 -->
                <p class="conclusion-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).four">
                  {{ getStockTypewriterTexts(stock).four }}
                </p>
                <!-- 完整文本 -->
                <p class="conclusion-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock) && getStockConclusion(stock).four">
                  {{ getStockConclusion(stock).four }}
                </p>
              </div>

            </div>
            <!-- 状态准备中的提示 -->
            <div class="conclusion-placeholder" v-if="!isStockStateReady(stock) && getStockConclusion(stock)">
              <p>请稍候...</p>
            </div>
            <!-- 等待数据加载的提示 -->
            <div
              class="conclusion-placeholder"
              v-if="!getStockConclusion(stock) || (!getStockConclusion(stock).one1 && !getStockConclusion(stock).one2 && !getStockConclusion(stock).two && !getStockConclusion(stock).three && !getStockConclusion(stock).four)"
            >
              <p>等待股票分析结论...</p>
            </div>
          </div>
          <!-- AI生成内容免责声明 -->
          <div class="disclaimer-item" v-if="(getStockTypewriterVisibility(stock) && getStockTypewriterVisibility(stock).disclaimer) || (getStockConclusion(stock) && !getStockTypewriterTexts(stock))">
            <!-- 打字机效果文本 -->
            <p class="disclaimer-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).disclaimer">
              {{ getStockTypewriterTexts(stock).disclaimer }}
            </p>
            <!-- 完整文本 -->
            <p class="disclaimer-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock)">
              该内容由AI生成，请注意甄别
            </p>
          </div>
        </div>

      </div>
    </div>
    
    <!-- 全局返回顶部按钮 -->
    <div class="back-to-top" @click="scrollToTop" v-if="(filteredStockList.length > 0 || messages.length > 0)">
      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M12 4L12 20M12 4L6 10M12 4L18 10" stroke="currentColor" stroke-width="2" stroke-linecap="round"
          stroke-linejoin="round" />
      </svg>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from "vue";
import { getReplyAPI, getConclusionAPI } from "@/api/AiEmotionApi.js"; // 导入工作流接口方法
import axios from "axios";
import moment from "moment";
import item from "@/assets/img/AiEmotion/bk01.png"; // 导入思维矩阵图片
import emotionDecod from "@/views/components/emotionDecod.vue"; // 导入情绪解码组件
import emotionalBottomRadar from "@/views/components/emotionalBottomRadar.vue"; // 导入情绪探底雷达图组件
import emoEnergyConverter from "@/views/components/emoEnergyConverter.vue"; // 导入情绪能量转化器组件
import marketTemperature from "@/views/components/marketTemperature.vue";
import StockTabs from "@/views/components/StockTabs.vue"; // 导入股票标签页组件
import blueBorderImg from "@/assets/img/AiEmotion/blueBorder.png"; //导入蓝色背景框图片
import { ElMessage } from "element-plus"; // 接口失败提示已改为对话形式，保留用于输入验证
import { useEmotionStore } from "@/store/emotion"; // 导入Pinia store
import { useEmotionAudioStore } from "@/store/emotionAudio.js"; // 导入音频store
import { useChatStore } from "@/store/chat.js"; // 导入聊天store
// 导入思考过程GIF
import thinkingGif from "@/assets/img/gif/思考.gif";
import analyzeGif from "@/assets/img/gif/解析.gif";
import generateGif from "@/assets/img/gif/生成.gif";
import getCountAll from "../assets/img/homePage/get-count-all.png";
import voice from "../assets/img/homePage/tail/voice.png";
import voiceNoActive from "../assets/img/homePage/tail/voice-no-active.png";
import { Howl, Howler } from "howler"; // 导入音频播放库
import { reactive } from "vue";
import { marked } from "marked"; // 引入marked库
import { useUserStore } from "../store/userPessionCode";
const APIurl = import.meta.env.VITE_APP_API_BASE_URL;

// 使用Pinia store
const emotionStore = useEmotionStore();
const emotionAudioStore = useEmotionAudioStore();

// 语音播放控制函数
const toggleVoiceForUser = (stock) => {
  if (!emotionAudioStore.isVoiceEnabled) {
    // 如果语音功能关闭，先开启语音功能
    emotionAudioStore.toggleVoice();
  } else {
    // 获取该股票的结论数据和当前状态
    const stockConclusion = getStockConclusion(stock);
    const currentState = getStockAudioState(stock);

    // 检查是否有任何音频正在播放（包括全局播放状态和当前股票状态）
    const isAnyAudioPlaying =
      emotionAudioStore.isPlaying || currentState.isPlaying;

    // 如果当前点击的股票正在播放，则暂停播放（不重置打字机状态）
    if (currentState.isPlaying) {
      console.log("暂停当前股票音频:", stock.stockInfo?.name);
      // 暂停音频播放但不重置打字机状态
      if (emotionAudioStore.nowSound && emotionAudioStore.nowSound.playing()) {
        emotionAudioStore.nowSound.pause();
        emotionAudioStore.isPaused = true;
        emotionAudioStore.isPlaying = false;
      }
      setStockAudioState(stock, { isPlaying: false, isPaused: true });
    } else if (currentState.isPaused) {
      // 如果当前股票处于暂停状态，则继续播放（不重置打字机状态）
      console.log("继续播放当前股票音频:", stock.stockInfo?.name);
      if (emotionAudioStore.nowSound) {
        // 从暂停位置继续播放，不重新开始
        if (emotionAudioStore.playbackPosition > 0) {
          emotionAudioStore.nowSound.seek(emotionAudioStore.playbackPosition);
        }
        emotionAudioStore.nowSound.play();
        emotionAudioStore.isPaused = false;
        emotionAudioStore.isPlaying = true;
      }
      setStockAudioState(stock, { isPlaying: true, isPaused: false });
    } else {
      // 如果有其他音频正在播放，先停止
      if (isAnyAudioPlaying) {
        console.log(
          "停止其他正在播放的音频，准备播放新音频:",
          stock.stockInfo?.name
        );
        stopAudio();
        emotionAudioStore.resetAudioState();
      }

      // 清除所有股票的播放状态
      clearAllStockAudioStates();

      // 如果有音频数据，开始播放
      if (
        stockConclusion &&
        (stockConclusion.one1_url ||
          stockConclusion.two_url ||
          stockConclusion.three_url ||
          stockConclusion.four_url)
      ) {
        console.log("开始播放股票音频:", stock.stockInfo?.name);
        setStockAudioState(stock, { isPlaying: true, isPaused: false });

        // 播放音频队列
        playAudioQueue(stockConclusion, false, () => {
          // 音频播放完成后重置状态
          setStockAudioState(stock, { isPlaying: false, isPaused: false });
        });
      } else {
        console.log("该股票没有可播放的音频数据");
      }
    }
  }
};

// 计算属性：判断语音是否启用
const isVoice = computed(() => {
  return emotionAudioStore.isVoiceEnabled;
});
const chatStore = useChatStore();
// 获取权限
const userStore = useUserStore();
// 处理refuse数据的函数
function processRefuseMessage(refuseData) {
  if (!refuseData) return "未知错误";

  // 如果refuse数据包含Markdown格式，进行转换
  try {
    // 配置marked选项
    marked.setOptions({
      breaks: true, // 支持换行符转换为 <br>
      gfm: true, // 启用 GitHub Flavored Markdown
      sanitize: false, // 不清理 HTML
      smartLists: true, // 智能列表
      smartypants: true, // 智能标点符号
      xhtml: false, // 不使用 XHTML 输出
    });

    // 将Markdown转换为HTML
    const htmlContent = marked(refuseData);

    // 移除HTML标签，只保留纯文本用于ElMessage显示
    const tempDiv = document.createElement("div");
    tempDiv.innerHTML = htmlContent;
    return tempDiv.textContent || tempDiv.innerText || refuseData;
  } catch (error) {
    console.error("处理refuse消息时出错:", error);
    return refuseData;
  }
}

// 组件引用 - 修改为数组形式支持多个股票
const marketTemperatureRef = ref([]); // 引用市场温度计组件数组
const emoEnergyConverterRef = ref([]);
const emotionDecodRef = ref([]);
const emotionalBottomRadarRef = ref([]);
const userInputDisplayRef = ref(null); //消息区域的引用

// 响应式数据
const messages = ref([]);

// 从emotion store中恢复对话记录
const loadConversationsFromStore = () => {
  const storedConversations = emotionStore.getConversations();
  messages.value = storedConversations.map((conv) => ({
    sender: conv.sender,
    text: conv.text,
    isHtml: conv.isHtml || false,
  }));
};

// 记录已经添加到对话中的股票，避免重复添加
const addedStocks = ref(new Set());

// 从stockList生成对话历史
const loadConversationsFromStockList = () => {
  // 如果当前正在处理用户发送的消息，跳过加载以避免重复
  if (isRotating.value) {
    console.log("正在处理用户消息，跳过对话历史加载");
    return;
  }

  // 检查是否有新的股票需要添加到对话中
  emotionStore.stockList.forEach((stock) => {
    // 验证股票数据完整性
    if (!stock?.stockInfo?.code || !stock?.timestamp || !stock?.queryText) {
      console.warn('股票数据不完整，跳过添加:', stock);
      return;
    }

    // 使用统一的唯一标识生成方法
    const stockKey = getStockUniqueId(stock);
    if (!stockKey) {
      console.warn('无法生成股票唯一标识，跳过添加:', stock);
      return;
    }

    // 多重检查避免重复添加
    if (!addedStocks.value.has(stockKey)) {
      const existingInMessages = messages.value.find(
        (msg) => msg.sender === "user" && msg.text === stock.queryText
      );
      
      const storeConversations = emotionStore.getConversations();
      const existingInStore = storeConversations.find(
        (conv) => conv.sender === "user" && conv.text === stock.queryText
      );

      // if (!existingInMessages && !existingInStore) {
      //   const userMessage = {
      //     sender: "user",
      //     text: stock.queryText,
      //   };
      //   messages.value.push(userMessage);
      //   emotionStore.addConversation(userMessage);
      // }

      addedStocks.value.add(stockKey);
    }
  });
};

// 清空对话记录
const clearConversations = () => {
  messages.value = [];
  emotionStore.clearConversations();
  // 清空已添加股票的记录
  addedStocks.value.clear();
};

// 添加股票数据的包装方法
const addStock = (stockData) => {
  console.log("AiEmotion组件接收到股票数据:", stockData);

  // 验证股票数据完整性
  if (!stockData || !stockData.stockInfo || !stockData.stockInfo.code) {
    console.error('addStock: 股票数据不完整', stockData);
    emit('enableInput');
    return;
  }

  // 设置为历史记录模式，并重置用户主动搜索标志
  isHistoryMode.value = true;
  isUserInitiated.value = false;
  // 历史记录恢复场景，不启用自动滚动
  shouldEnableAutoScroll.value = false;

  // 1. 先清空页面显示节点和stockList中的数据
  isPageLoaded.value = false; // 隐藏页面显示节点
  emotionStore.clearAllStocks(); // 清空stockList中的数据
  emotionStore.clearConversations(); // 清空对话记录
  messages.value = []; // 清空页面对话显示

  // 清理已添加股票的记录
  addedStocks.value.clear();

  // 停止音频播放和清理状态
  stopAudio();
  audioUrl.value = "";
  emotionAudioStore.resetAudioState();
  clearTypewriterTimers();
  hasTriggeredAudio.value = false;
  hasTriggeredTypewriter.value = false;
  stockTypewriterShown.value.clear();
  stockAudioPlayed.value.clear();

  // 清理状态变量（保留用于其他功能的变量）

  // 隐藏所有图表组件
  chartVisibility.value = {
    marketTemperature: false,
    emotionDecod: false,
    emotionalBottomRadar: false,
    emoEnergyConverter: false,
  };

  // 2. 将新的数据存储到stockList中
  emotionStore.addStock(stockData);
  // 3. 设置页面为已加载状态，重新渲染页面
  isPageLoaded.value = true;

  // 4. 标记历史记录股票已显示过，避免重复触发
  if (stockData.conclusionData) {
    const stockUniqueId = getStockUniqueId(stockData);
    if (stockUniqueId) {
      stockTypewriterShown.value.set(stockUniqueId, true);
      stockAudioPlayed.value.set(stockUniqueId, true);
    }
    console.log("历史记录股票已标记为已显示");
  }

  // 5. 使用nextTick确保DOM更新后完成历史记录恢复
  nextTick(() => {
    // 历史记录恢复时不启动内部滚动监听器，完全依赖父组件管理
    // 历史记录恢复时不滚动到底部，保持在顶部
    
    // 6. 历史记录加载完成后，通知父组件重新启用输入框
    emit('enableInput');
  });
};

// 暴露方法给父组件
defineExpose({
  handleSendMessage,
  clearConversations,
  addStock,
});
const isPageLoaded = ref(false); // 控制页面是否显示
const isHistoryMode = ref(false); // 控制是否为历史记录模式
// const isLoading = ref(false); // 控制加载状态
const isRotating = ref(false); //控制旋转
const version1 = ref(1); // 版本号
const conclusionData = ref(""); // 存储第二个工作流接口返回的结论数据

// 自动滚动相关数据
const isAutoScrolling = ref(false);
const currentSection = ref(0);
const sectionRefs = ref([]);
const scenarioApplicationRef = ref(null); // 场景应用部分的引用
const hasTriggeredAudio = ref(false); // 是否已触发音频播放
const hasTriggeredTypewriter = ref(false); // 是否已触发打字机效果
const intersectionObserver = ref(null); // 存储observer实例
const isUserInitiated = ref(false); // 标记是否为用户主动搜索
const shouldEnableAutoScroll = ref(false); // 标记是否应该启动自动滚动（仅在搜索新数据成功后为true）
const isUserScrolling = ref(false); // 标记用户是否正在手动滚动
const userScrollTimer = ref(null); // 用户滚动检测定时器

// 打字机效果相关的变量已移除，现在直接使用parsedConclusion显示内容

// 图表组件显示状态
const chartVisibility = ref({
  marketTemperature: true,
  emotionDecod: true,
  emotionalBottomRadar: true,
  emoEnergyConverter: true,
});
const typewriterTimers = ref([]);
// 记录每个股票是否已经显示过打字机效果
const stockTypewriterShown = ref(new Map());
// 记录每个股票的打字机显示状态
const stockTypewriterTexts = ref(new Map());
// 记录每个股票的打字机模块可见性
const stockTypewriterVisibility = ref(new Map());
// 记录每个股票是否已经播放过音频
const stockAudioPlayed = ref(new Map());
// 跟踪每个股票的音频播放状态
const stockAudioStates = ref(new Map());

// 生成股票唯一标识符的辅助函数
const getStockUniqueId = (stock) => {
  // 验证输入参数
  if (!stock || typeof stock !== 'object') {
    console.warn('getStockUniqueId: 无效的股票对象');
    return null;
  }

  // 优先使用预设的uniqueId
  if (stock.uniqueId) {
    return stock.uniqueId;
  }
  
  // 兼容旧的生成方式
  const stockCode = stock.stockInfo?.code || stock.stockInfo?.symbol;
  const timestamp = stock.timestamp;
  
  if (!stockCode || !timestamp) {
    console.warn('getStockUniqueId: 缺少必要字段', { stockCode, timestamp });
    return null;
  }
  
  return `${stockCode}_${timestamp}`;
};
// 存储当前的完成回调函数
const currentOnCompleteCallback = ref(null);

// 音频播放相关数据
const audioUrl = ref("");
const isAudioPlaying = ref(false);

// 获取股票的音频播放状态
const getStockAudioState = (stock) => {
  const stockUniqueId = getStockUniqueId(stock);
  if (!stockUniqueId) {
    console.warn('getStockAudioState: 无法获取股票唯一标识');
    return { isPlaying: false, isPaused: false };
  }

  return (
    stockAudioStates.value.get(stockUniqueId) || {
      isPlaying: false,
      isPaused: false,
    }
  );
};

// 设置股票的音频播放状态
const setStockAudioState = (stock, state) => {
  const stockUniqueId = getStockUniqueId(stock);
  if (!stockUniqueId) {
    console.warn('setStockAudioState: 无法获取股票唯一标识');
    return;
  }

  if (!state || typeof state !== 'object') {
    console.warn('setStockAudioState: 无效的状态对象');
    return;
  }

  stockAudioStates.value.set(stockUniqueId, { ...state });
};

// 清除所有股票的播放状态（当开始播放新音频时）
const clearAllStockAudioStates = () => {
  for (const [key, value] of stockAudioStates.value.entries()) {
    stockAudioStates.value.set(key, { isPlaying: false, isPaused: false });
  }
};

// 返回顶部按钮相关数据
const showBackToTop = ref(false);

// 计算属性 - 从store获取当前股票数据
const currentStock = computed(() => emotionStore.activeStock);
const stockName = computed(() => currentStock.value?.stockInfo.name || "");
const stockCode = computed(
  () =>
    currentStock.value?.stockInfo.code ||
    currentStock.value?.stockInfo.symbol ||
    ""
);
const currentStockUniqueId = computed(() => {
  if (!currentStock.value) return "";
  return getStockUniqueId(currentStock.value);
});
const displayDate = computed(() => {
  if (!currentStock.value?.apiData) return "";
  const lastData = currentStock.value.apiData.GSWDJ?.at(-1);
  if (!lastData || !lastData[0]) return "";

  const dateStr = lastData[0];
  // 假设原格式为 YYYY-MM-DD 或 YYYY/MM/DD
  const dateMatch = dateStr.match(/(\d{4})[\-\/](\d{1,2})[\-\/](\d{1,2})/);
  if (dateMatch) {
    const [, year, month, day] = dateMatch;
    // 转换为 DD/MM/YYYY 格式
    return `更新时间：${day.padStart(2, "0")}/${month.padStart(
      2,
      "0"
    )}/${year}`;
  }

  // 如果不匹配预期格式，返回原始值
  return dateStr;
});
const data1 = computed(() => {
  if (!currentStock.value?.apiData) return null;
  const lastData = currentStock.value.apiData.GSWDJ?.at(-1);
  return lastData ? Math.round(lastData[1]) : null;
});
const data2 = computed(() => {
  if (!currentStock.value?.apiData) return null;
  const lastData = currentStock.value.apiData.GSWDJ?.at(-1);
  return lastData ? Math.round(lastData[2]) : null;
});
const currentConclusion = computed(() => {
  return currentStock.value?.conclusionData || "";
});
const parsedConclusion = computed(() => {
  if (!currentConclusion.value) return null;

  // 如果conclusionData已经是对象，直接返回
  if (typeof currentConclusion.value === "object") {
    return currentConclusion.value;
  }

  // 如果是字符串，尝试解析JSON
  try {
    return JSON.parse(currentConclusion.value);
  } catch (error) {
    console.error("解析结论数据失败:", error);
    return null;
  }
});

// 多股票数据显示的计算属性
// 过滤和排序后的股票列表
const filteredStockList = computed(() => {
  return emotionStore.stockList
    .filter((stock) => {
      // 过滤掉数据不完整的股票
      return stock.stockInfo?.name && stock.apiData && stock.queryText;
    })
    .sort((a, b) => {
      // 按时间戳降序排序，最新的在前
      return new Date(a.timestamp) - new Date(b.timestamp);
    });
});

// 辅助函数：获取股票的显示日期
const getDisplayDate = (stock) => {
  if (!stock?.apiData) return "";
  const lastData = stock.apiData.GSWDJ?.at(-1);
  if (!lastData || !lastData[0]) return "";

  const dateStr = lastData[0];
  // 假设原格式为 YYYY-MM-DD 或 YYYY/MM/DD
  const dateMatch = dateStr.match(/(\d{4})[\-\/](\d{1,2})[\-\/](\d{1,2})/);
  if (dateMatch) {
    const [, year, month, day] = dateMatch;
    // 转换为 DD/MM/YYYY 格式
    return `更新时间：${day.padStart(2, "0")}/${month.padStart(
      2,
      "0"
    )}/${year}`;
  }

  // 如果不匹配预期格式，返回原始值
  return dateStr;
};

// 辅助函数：获取股票的市场温度数据
const getStockData1 = (stock) => {
  if (!stock?.apiData) return null;
  const lastData = stock.apiData.GSWDJ?.at(-1);
  return lastData ? Math.round(lastData[1]) : null;
};

// 辅助函数：获取股票的股票温度数据
const getStockData2 = (stock) => {
  if (!stock?.apiData) return null;
  const lastData = stock.apiData.GSWDJ?.at(-1);
  return lastData ? Math.round(lastData[2]) : null;
};

// 辅助函数：获取股票的结论数据
const getStockConclusion = (stock) => {
  if (!stock?.conclusionData) return null;

  // 如果conclusionData已经是对象，直接返回
  if (typeof stock.conclusionData === "object") {
    return stock.conclusionData;
  }

  // 如果是字符串，尝试解析JSON
  try {
    return JSON.parse(stock.conclusionData);
  } catch (error) {
    console.error("解析股票结论数据失败:", error);
    return null;
  }
};

// 辅助函数：获取股票的打字机文本状态
const getStockTypewriterTexts = (stock) => {
  const stockUniqueId = getStockUniqueId(stock);
  if (!stockUniqueId) {
    console.warn('getStockTypewriterTexts: 无法获取股票唯一标识');
    return null;
  }
  const texts = stockTypewriterTexts.value.get(stockUniqueId);
  return texts || null;
};

// 辅助函数：获取股票的打字机可见性状态
const getStockTypewriterVisibility = (stock) => {
  const stockUniqueId = getStockUniqueId(stock);
  if (!stockUniqueId) {
    console.warn('getStockTypewriterVisibility: 无法获取股票唯一标识');
    return null;
  }
  return stockTypewriterVisibility.value.get(stockUniqueId) || null;
};

// 辅助函数：检查股票是否正在进行打字机效果
const isStockTypewriting = (stock) => {
  const stockUniqueId = getStockUniqueId(stock);
  if (!stockUniqueId) {
    console.warn('isStockTypewriting: 无法获取股票唯一标识');
    return false;
  }
  return stockTypewriterShown.value.has(stockUniqueId) && !stockTypewriterTexts.value.has(stockUniqueId);
};

// 辅助函数：检查股票状态是否准备好显示
const isStockStateReady = (stock) => {
  const stockUniqueId = getStockUniqueId(stock);
  if (!stockUniqueId) {
    return false;
  }
  
  const conclusion = getStockConclusion(stock);
  if (!conclusion) {
    return false;
  }
  
  const isFirstTime = !stockTypewriterShown.value.has(stockUniqueId);
  
  // 如果是第一次且用户主动搜索，提前初始化状态并返回true
  if (isFirstTime && isUserInitiated.value) {
    // 提前初始化打字机状态，避免渲染时的状态闪烁
    if (!stockTypewriterTexts.value.has(stockUniqueId)) {
      stockTypewriterTexts.value.set(stockUniqueId, {
        one1: "", one2: "", two: "", three: "", four: "", disclaimer: ""
      });
    }
    if (!stockTypewriterVisibility.value.has(stockUniqueId)) {
      stockTypewriterVisibility.value.set(stockUniqueId, {
        one: false, two: false, three: false, four: false, disclaimer: false
      });
    }
    return true;
  }
  
  // 其他情况下，只要有结论数据就可以显示
  return true;
};

// 监听股票列表变化，当列表为空时隐藏页面数据
watch(
  () => emotionStore.stockList,
  (newStockList) => {
    if (newStockList.length === 0) {
      // 当股票列表为空时，隐藏页面数据
      isPageLoaded.value = false;
      // 停止音频播放
      stopAudio();
      // 清理音频URL
      audioUrl.value = "";
      emotionAudioStore.resetAudioState();
      // 清理打字机效果
      clearTypewriterTimers();
      // 重置所有状态
      hasTriggeredAudio.value = false;
      hasTriggeredTypewriter.value = false;
      stockTypewriterShown.value.clear();
      stockAudioPlayed.value.clear();
      // 清理已添加股票的记录
      addedStocks.value.clear();
      // 隐藏所有图表组件
      chartVisibility.value = {
        marketTemperature: false,
        emotionDecod: false,
        emotionalBottomRadar: false,
        emoEnergyConverter: false,
      };
      console.log("股票列表已清空，页面数据已隐藏");
    } else {
      // 当stockList有数据时，更新对话记录
      loadConversationsFromStockList();
    }
  },
  { deep: true }
);

// 监听当前股票变化，重新渲染图表和显示对应结论
watch(
  currentStock,
  (newStock) => {
    if (newStock && newStock.apiData) {
      // 页面加载状态现在由 handleSendMessage 统一控制
      // 停止当前播放的音频
      stopAudio();
      // 清理音频URL，确保不会播放之前股票的音频
      audioUrl.value = "";
      // 清理store中的音频URL，确保不会播放之前股票的音频
      emotionAudioStore.resetAudioState();
      // 清理正在进行的打字机效果定时器
      clearTypewriterTimers();
      // 重置触发状态，让每个股票都能独立触发效果
      hasTriggeredAudio.value = false;
      hasTriggeredTypewriter.value = false;

      // 获取股票唯一标识（使用预设的uniqueId）
      const stockUniqueId = getStockUniqueId(newStock);

      // 处理当前股票的音频URL
      if (newStock.conclusionData) {
        try {
          // 如果conclusionData已经是对象，直接使用；否则解析JSON
          const conclusion =
            typeof newStock.conclusionData === "object"
              ? newStock.conclusionData
              : JSON.parse(newStock.conclusionData);

          // 基于预设状态处理音频URL
          const shouldShowTypewriter = stockUniqueId && stockTypewriterTexts.value.has(stockUniqueId);
          
          if (!shouldShowTypewriter) {
            // 提取音频URL但不自动播放，等待用户手动点击
            let voiceUrl = null;
            // 优先使用one1_url，如果没有则尝试其他音频URL
            if (conclusion.one1_url) {
              voiceUrl = conclusion.one1_url
                .toString()
                .trim()
                .replace(/[`\s]/g, "");
            } else if (conclusion.one2_url) {
              voiceUrl = conclusion.one2_url
                .toString()
                .trim()
                .replace(/[`\s]/g, "");
            } else if (conclusion.two_url) {
              voiceUrl = conclusion.two_url
                .toString()
                .trim()
                .replace(/[`\s]/g, "");
            } else if (conclusion.three_url) {
              voiceUrl = conclusion.three_url
                .toString()
                .trim()
                .replace(/[`\s]/g, "");
            } else if (conclusion.four_url) {
              voiceUrl = conclusion.four_url
                .toString()
                .trim()
                .replace(/[`\s]/g, "");
            } else if (conclusion.url) {
              voiceUrl = conclusion.url.toString().trim().replace(/[`\s]/g, "");
            } else if (conclusion.audioUrl) {
              voiceUrl = conclusion.audioUrl
                .toString()
                .trim()
                .replace(/[`\s]/g, "");
            } else if (conclusion.voice_url) {
              voiceUrl = conclusion.voice_url
                .toString()
                .trim()
                .replace(/[`\s]/g, "");
            } else if (conclusion.audio) {
              voiceUrl = conclusion.audio
                .toString()
                .trim()
                .replace(/[`\s]/g, "");
            } else if (conclusion.tts_url) {
              voiceUrl = conclusion.tts_url
                .toString()
                .trim()
                .replace(/[`\s]/g, "");
            }

            if (voiceUrl && voiceUrl.startsWith("http")) {
              console.log(
                "切换到已显示股票，准备音频URL但不自动播放:",
                voiceUrl
              );
              audioUrl.value = voiceUrl;
              // 同时更新store中的音频URL
              emotionAudioStore.setCurrentAudioUrl(voiceUrl);
              // 不自动播放，等待用户手动点击
            }
          }
        } catch (error) {
            console.error("解析股票结论数据失败:", error);
          }
        } else {
          // 如果没有结论数据，清空音频URL
          audioUrl.value = "";
          emotionAudioStore.resetAudioState();
          console.log("当前股票没有结论数据，已清空音频");
        }

      // 只有在页面已加载的情况下才渲染图表
      if (isPageLoaded.value) {
        nextTick(() => {
          renderCharts(newStock.apiData);
          console.log("图表数据已准备完成，开始渲染:", newStock.apiData);
          // 检查场景应用部分是否已经在视口中，如果是则立即触发效果
          setTimeout(() => {
            // 检查 scenarioApplicationRef.value 是否存在且是有效的 DOM 元素
            if (
              !scenarioApplicationRef.value ||
              !(scenarioApplicationRef.value instanceof Element)
            ) {
              console.warn(
                "scenarioApplicationRef.value 不是有效的 DOM 元素，跳过处理"
              );
              return;
            }

            if (parsedConclusion.value) {
              // 如果该股票已经显示过，不需要再处理
              if (stockUniqueId && stockTypewriterShown.value.has(stockUniqueId)) {
                return;
              }

              const rect = scenarioApplicationRef.value.getBoundingClientRect();
              const isInViewport =
                rect.top < window.innerHeight && rect.bottom > 0;

              if (isInViewport) {
                console.log("股票切换后检测到场景应用部分在视口中");

                if (stockUniqueId) {
                  // 检查该股票是否是第一次触发
                  if (!stockTypewriterShown.value.has(stockUniqueId)) {
                    // 如果是用户主动搜索，启动打字机效果和音频播放
                    if (isUserInitiated.value && audioUrl.value) {
                      console.log(
                        "用户主动搜索，该股票第一次进入场景应用，开始打字机效果和音频播放"
                      );
                      hasTriggeredTypewriter.value = true;
                      hasTriggeredAudio.value = true;

                      if (!stockAudioPlayed.value.has(stockUniqueId)) {
                        console.log("开始音频播放和打字机效果");
                        stockAudioPlayed.value.set(stockUniqueId, true);
                        playAudioQueue(parsedConclusion.value, true);
                      } else {
                        // 如果音频已播放过，只启动打字机效果
                        startTypewriterEffect(parsedConclusion.value, stockUniqueId);
                      }

                      stockTypewriterShown.value.set(stockUniqueId, true);
                    } else if (isUserInitiated.value && !audioUrl.value) {
                      console.log(
                        "音频尚未准备好，等待音频加载完成后再触发效果（股票切换后）"
                      );
                      return;
                    } else {
                      // 非用户主动搜索（如历史记录恢复），直接显示完整内容
                      console.log(
                        "非用户主动搜索，该股票第一次进入场景应用，直接显示完整内容"
                      );

                      const conclusion = parsedConclusion.value;
                      // 结论内容现在直接通过parsedConclusion计算属性显示

                      stockTypewriterShown.value.set(stockUniqueId, true);
                      stockAudioPlayed.value.set(stockUniqueId, true);
                    }
                  } else {
                    // 非第一次或已经触发过：直接显示完整内容，不播放音频和打字机效果
                    console.log("非第一次股票切换或已触发过，直接显示完整内容");

                    // 直接显示完整内容
                    const conclusion = parsedConclusion.value;
                    displayedTexts.value = {
                      one1: conclusion.one1 || "",
                      one2: conclusion.one2 || "",
                      two: conclusion.two || "",
                      three: conclusion.three || "",
                      four: conclusion.four || "",
                      disclaimer: "该内容由AI生成，请注意甄别",
                    };
                    displayedTitles.value = {
                      one: "L1: 情绪监控",
                      two: "L2: 情绪解码",
                      three: "L3: 情绪推演",
                      four: "L4: 情绪套利",
                    };
                    moduleVisibility.value = {
                      one: !!(conclusion.one1 || conclusion.one2),
                      two: !!conclusion.two,
                      three: !!conclusion.three,
                      four: !!conclusion.four,
                      disclaimer: true,
                    };
                  }
                }
              }
            }
          }, 500); // 延迟500ms确保数据完全加载
        });
      } else {
        console.log("页面尚未加载完成，等待数据加载完成后再渲染图表");
      }
    } else {
      console.log("股票数据不存在或API数据未加载");
      // 隐藏所有图表组件
      chartVisibility.value = {
        marketTemperature: false,
        emotionDecod: false,
        emotionalBottomRadar: false,
        emoEnergyConverter: false,
      };
    }
  },
  { immediate: true }
);

// 监听parsedConclusion变化，准备数据但不立即触发打字机效果
watch(
  parsedConclusion,
  (newConclusion) => {
    if (newConclusion) {
      console.log("场景应用结论数据:", newConclusion);
      // 不再立即开始打字机效果，等待滚动到场景应用部分时触发

      // 尝试多种可能的语音URL字段名，优先使用新的数据结构
      let voiceUrl = null;
      if (newConclusion.one1_url) {
        voiceUrl = newConclusion.one1_url
          .toString()
          .trim()
          .replace(/[`\s]/g, "");
      } else if (newConclusion.one2_url) {
        voiceUrl = newConclusion.one2_url
          .toString()
          .trim()
          .replace(/[`\s]/g, "");
      } else if (newConclusion.two_url) {
        voiceUrl = newConclusion.two_url
          .toString()
          .trim()
          .replace(/[`\s]/g, "");
      } else if (newConclusion.three_url) {
        voiceUrl = newConclusion.three_url
          .toString()
          .trim()
          .replace(/[`\s]/g, "");
      } else if (newConclusion.four_url) {
        voiceUrl = newConclusion.four_url
          .toString()
          .trim()
          .replace(/[`\s]/g, "");
      } else if (newConclusion.url) {
        // 清理URL字符串，去除空格、反引号等特殊字符
        voiceUrl = newConclusion.url.toString().trim().replace(/[`\s]/g, "");
      } else if (newConclusion.audioUrl) {
        voiceUrl = newConclusion.audioUrl
          .toString()
          .trim()
          .replace(/[`\s]/g, "");
      } else if (newConclusion.voice_url) {
        voiceUrl = newConclusion.voice_url
          .toString()
          .trim()
          .replace(/[`\s]/g, "");
      } else if (newConclusion.audio) {
        voiceUrl = newConclusion.audio.toString().trim().replace(/[`\s]/g, "");
      } else if (newConclusion.tts_url) {
        voiceUrl = newConclusion.tts_url
          .toString()
          .trim()
          .replace(/[`\s]/g, "");
      }

      if (voiceUrl && voiceUrl.startsWith("http")) {
        console.log("找到并清理后的语音URL:", voiceUrl);
        audioUrl.value = voiceUrl;
        // 同时更新store中的音频URL
        emotionAudioStore.setCurrentAudioUrl(voiceUrl);
        console.log("音频URL已准备，检查是否需要立即触发效果");

        // 音频准备好后，只有在用户主动搜索时才自动触发效果
        // 数据恢复时不自动播放音频和打字机效果
        console.log("音频URL已准备完成，等待用户手动触发播放");
      } else {
        console.log("未找到有效的语音URL，原始URL:", newConclusion.url);
        console.log("结论数据中的所有字段:", Object.keys(newConclusion));
      }
    }
  },
  { immediate: true }
);

// 打字机效果函数
function startTypewriterEffect(conclusion, stockId, onComplete) {
  // 如果没有传入stockId，使用当前活跃股票的唯一标识符
  if (!stockId && emotionStore.activeStock) {
    stockId = getStockUniqueId(emotionStore.activeStock);
  }
  
  if (!stockId) {
    console.warn("无法确定股票ID，跳过打字机效果");
    return;
  }

  console.log("开始打字机效果，结论数据:", conclusion, "股票ID:", stockId);

  // 保存当前的完成回调函数
  currentOnCompleteCallback.value = onComplete;

  // 详细调试各个字段
  console.log("L1字段 - one1:", conclusion.one1);
  console.log("L1字段 - one2:", conclusion.one2);
  console.log("L2字段 - two:", conclusion.two);
  console.log("L3字段 - three:", conclusion.three);
  console.log("L4字段 - four:", conclusion.four);

  // 清除之前的定时器
  typewriterTimers.value.forEach((timer) => clearTimeout(timer));
  typewriterTimers.value = [];

  // 初始化该股票的打字机状态
  if (!stockTypewriterTexts.value.has(stockId)) {
    stockTypewriterTexts.value.set(stockId, {
      one1: "",
      one2: "",
      two: "",
      three: "",
      four: "",
      disclaimer: "",
    });
  }
  if (!stockTypewriterVisibility.value.has(stockId)) {
    stockTypewriterVisibility.value.set(stockId, {
      one: false,
      two: false,
      three: false,
      four: false,
      disclaimer: false,
    });
  }

  // 重置该股票的显示文本和状态
  stockTypewriterTexts.value.set(stockId, {
    one1: "",
    one2: "",
    two: "",
    three: "",
    four: "",
    disclaimer: "",
  });

  stockTypewriterVisibility.value.set(stockId, {
    one: false,
    two: false,
    three: false,
    four: false,
    disclaimer: false,
  });

  // 定义打字速度（毫秒）
  const typeSpeed = 200;
  let totalDelay = 0;

  // 定义模块配置
  const modules = [
    {
      key: "one",
      title: "L1: 情绪监控",
      contents: [
        { key: "one1", text: conclusion.one1 },
        { key: "one2", text: conclusion.one2 },
      ],
    },
    {
      key: "two",
      title: "L2: 情绪解码",
      contents: [{ key: "two", text: conclusion.two }],
    },
    {
      key: "three",
      title: "L3: 情绪推演",
      contents: [{ key: "three", text: conclusion.three }],
    },
    {
      key: "four",
      title: "L4: 情绪套利",
      contents: [{ key: "four", text: conclusion.four }],
    },
  ];

  // 按模块顺序处理
  modules.forEach((module) => {
    // 检查模块是否有内容
    const hasContent = module.contents.some(
      (content) => content.text && content.text.trim()
    );
    console.log(
      `模块 ${module.key} 是否有内容:`,
      hasContent,
      "内容:",
      module.contents.map((c) => c.text)
    );
    if (!hasContent) return;

    console.log(`开始显示模块 ${module.key}`);
    
    // 显示模块
    const showModuleTimer = setTimeout(() => {
      const visibility = stockTypewriterVisibility.value.get(stockId);
      if (visibility) {
        visibility[module.key] = true;
        stockTypewriterVisibility.value.set(stockId, { ...visibility });
      }
    }, totalDelay);
    typewriterTimers.value.push(showModuleTimer);
    totalDelay += 100;

    // 为每个内容项添加打字机效果
    module.contents.forEach((content) => {
      if (content.text && content.text.trim()) {
        for (let i = 0; i <= content.text.length; i++) {
          const timer = setTimeout(() => {
            const texts = stockTypewriterTexts.value.get(stockId);
            if (texts) {
              texts[content.key] = content.text.substring(0, i);
              stockTypewriterTexts.value.set(stockId, { ...texts });
            }
          }, totalDelay + i * typeSpeed);
          typewriterTimers.value.push(timer);
        }
        totalDelay += content.text.length * typeSpeed + 200; // 内容间间隔
      }
    });

    totalDelay += 800; // 模块间间隔
  });

  // 添加免责声明的打字机效果（在所有模块显示完成后）
  const disclaimerText = "该内容由AI生成，请注意甄别";

  // 显示免责声明模块
  const showDisclaimerTimer = setTimeout(() => {
    const visibility = stockTypewriterVisibility.value.get(stockId);
    if (visibility) {
      visibility.disclaimer = true;
      stockTypewriterVisibility.value.set(stockId, { ...visibility });
    }
  }, totalDelay);
  typewriterTimers.value.push(showDisclaimerTimer);
  totalDelay += 100;

  // 打字机效果显示免责声明
  for (let i = 0; i <= disclaimerText.length; i++) {
    const timer = setTimeout(() => {
      const texts = stockTypewriterTexts.value.get(stockId);
      if (texts) {
        texts.disclaimer = disclaimerText.substring(0, i);
        stockTypewriterTexts.value.set(stockId, { ...texts });
      }
      // 在免责声明打字机效果完成后调用回调函数
      if (i === disclaimerText.length) {
        console.log("打字机效果完成，调用onComplete回调");
        if (onComplete && typeof onComplete === "function") {
          onComplete();
          // 清除保存的回调函数
          currentOnCompleteCallback.value = null;
        }
      }
    }, totalDelay + i * typeSpeed);
    typewriterTimers.value.push(timer);
  }
}

// 清理定时器的函数
function clearTypewriterTimers() {
  typewriterTimers.value.forEach((timer) => clearTimeout(timer));
  typewriterTimers.value = [];
}

// 音频队列管理
const audioQueue = ref([]);
const isPlayingQueueAudio = ref(false);
let currentPlayIndex = 0;
let isCallingPlayNext = false;

// 音频队列顺序管理
const audioQueueOrder = {
  one1_url: 1,
  one2_url: 2,
  two_url: 3,
  three_url: 4,
  four_url: 5,
  url: 6,
  audioUrl: 7,
  voice_url: 8,
  audio: 9,
  tts_url: 10,
};

// 播放音频队列中的下一个音频
const playNextAudio = () => {
  console.log("=== playNextAudio 被调用 ===");
  console.log("当前队列状态:", {
    queueLength: audioQueue.value.length,
    queueItems: audioQueue.value.map((item) => item.name),
    currentPlayIndex: currentPlayIndex,
    isPlayingQueueAudio: isPlayingQueueAudio.value,
    isCallingPlayNext: isCallingPlayNext,
    audioStoreIsPlaying: emotionAudioStore.isPlaying,
  });

  if (
    audioQueue.value.length === 0 ||
    isPlayingQueueAudio.value ||
    isCallingPlayNext
  ) {
    console.log(
      "❌ 播放条件不满足 - 队列长度:",
      audioQueue.value.length,
      "正在播放:",
      isPlayingQueueAudio.value,
      "正在调用:",
      isCallingPlayNext
    );
    return;
  }

  // 检查是否已播放完所有音频
  if (
    currentPlayIndex >= audioQueue.value.length &&
    audioQueue.value.length > 0
  ) {
    console.log("🔄 所有音频播放完成，重置索引从第一个开始");
    currentPlayIndex = 0;
    isCallingPlayNext = false; // 重置调用标志
  }

  isCallingPlayNext = true;
  isPlayingQueueAudio.value = true;
  const audioInfo = audioQueue.value[currentPlayIndex];

  console.log(
    `✅ 开始播放${audioInfo.name}音频 (索引:${currentPlayIndex})，队列总长度:`,
    audioQueue.value.length
  );

  // 停止之前的音频
  if (emotionAudioStore.nowSound && emotionAudioStore.nowSound.playing()) {
    emotionAudioStore.nowSound.stop();
  }

  // 创建新的音频实例
  const audio = new Howl({
    src: [audioInfo.url],
    html5: false,
    format: ["mp3", "wav"],
    onplay: () => {
      isAudioPlaying.value = true;
      isPlayingQueueAudio.value = true;
      emotionAudioStore.isPlaying = true;
      console.log(`开始播放${audioInfo.name}音频`);

      // 设置当前股票的音频播放状态为播放中
      const currentStock = emotionStore.activeStock;
      if (currentStock) {
        setStockAudioState(currentStock, { isPlaying: true, isPaused: false });
        console.log('设置当前股票音频状态为播放中:', currentStock.stockInfo?.name);
      }

      // 如果是第一个音频且需要启动打字机效果，且不是从暂停状态恢复播放，则启动
      if (
        currentPlayIndex === 0 &&
        audioInfo.shouldStartTypewriter &&
        parsedConclusion.value &&
        !emotionAudioStore.isPaused && // 不是从暂停状态恢复
        emotionAudioStore.playbackPosition === 0 // 从头开始播放
      ) {
        console.log("🎬 第一个音频开始播放，同时启动打字机效果");
        const stockId = currentStock ? getStockUniqueId(currentStock) : null;
        startTypewriterEffect(parsedConclusion.value, stockId, audioInfo.onComplete);
      } else if (currentPlayIndex === 0 && audioInfo.shouldStartTypewriter) {
        console.log("🔄 从暂停状态恢复播放，不重新启动打字机效果");
      }
    },
    onpause: () => {
      emotionAudioStore.isPlaying = false;
      emotionAudioStore.isPaused = true;
      // 保存当前播放位置
      if (audio && audio.seek) {
        emotionAudioStore.playbackPosition = audio.seek() || 0;
      }
      console.log(`${audioInfo.name}音频暂停播放，位置:`, emotionAudioStore.playbackPosition);
      
      // 设置当前股票的音频播放状态为暂停
      const currentStock = emotionStore.activeStock;
      if (currentStock) {
        setStockAudioState(currentStock, { isPlaying: false, isPaused: true });
        console.log('设置当前股票音频状态为暂停:', currentStock.stockInfo?.name);
      }
    },
    onresume: () => {
      emotionAudioStore.isPlaying = true;
      emotionAudioStore.isPaused = false;
      // 如果有保存的播放位置，从该位置继续播放
      if (emotionAudioStore.playbackPosition > 0 && audio && audio.seek) {
        audio.seek(emotionAudioStore.playbackPosition);
      }
      console.log(`${audioInfo.name}音频继续播放，位置:`, emotionAudioStore.playbackPosition);
      
      // 设置当前股票的音频播放状态为播放中
      const currentStock = emotionStore.activeStock;
      if (currentStock) {
        setStockAudioState(currentStock, { isPlaying: true, isPaused: false });
        console.log('设置当前股票音频状态为播放中:', currentStock.stockInfo?.name);
      }
    },
    onend: () => {
      console.log(`${audioInfo.name}音频播放完成，准备播放下一个`);
      emotionAudioStore.isPaused = false;
      emotionAudioStore.playbackPosition = 0;

      // 移动到下一个音频索引
      currentPlayIndex++;

      // 确保只有在音频真正播放完成时才播放下一个
      if (currentPlayIndex < audioQueue.value.length) {
        console.log(
          `队列中还有音频，500ms后播放下一个 (索引:${currentPlayIndex})`
        );
        // 重置调用标志，但保持播放状态，直到所有音频播放完成
        setTimeout(() => {
          isCallingPlayNext = false;
          isPlayingQueueAudio.value = false; // 重置队列播放状态，允许播放下一个音频
          // 保持emotionAudioStore.isPlaying为true，确保喇叭图片保持voice状态
          emotionAudioStore.isPlaying = true;
          // 设置下一个音频的URL，确保togglePlayPause能正确工作
          const nextAudioInfo = audioQueue.value[currentPlayIndex];
          if (nextAudioInfo && nextAudioInfo.url) {
            emotionAudioStore.setCurrentAudioUrl(nextAudioInfo.url);
          }
          playNextAudio();
        }, 500);
      } else {
        console.log("🎉 所有音频播放完成");
        emotionAudioStore.nowSound = null;
        isCallingPlayNext = false;
        
        // 重置音频store的播放状态
        emotionAudioStore.isPlaying = false;
        emotionAudioStore.isPaused = false;
        emotionAudioStore.playbackPosition = 0;
        isAudioPlaying.value = false;
        isPlayingQueueAudio.value = false;

        // 重置当前股票的音频播放状态（所有音频播放完成后按钮应该变暗）
        const currentStock = emotionStore.activeStock;
        if (currentStock) {
          console.log('所有音频播放完成，重置当前股票音频状态:', currentStock.stockInfo?.name);
          setStockAudioState(currentStock, { isPlaying: false, isPaused: false });
        }

        // 调用完成回调（如果有的话）
        if (
          audioInfo.onComplete &&
          typeof audioInfo.onComplete === "function"
        ) {
          console.log("调用音频播放完成回调");
          audioInfo.onComplete();
        }
      }
    },
    onstop: () => {
      console.log(`${audioInfo.name}音频被停止`);
      emotionAudioStore.isPlaying = false;
      emotionAudioStore.isPaused = false;
      emotionAudioStore.playbackPosition = 0;
      isAudioPlaying.value = false;
      isPlayingQueueAudio.value = false;
      
      // 重置当前股票的音频播放状态（音频被停止时按钮应该变暗）
      const currentStock = emotionStore.activeStock;
      if (currentStock) {
        console.log('音频被停止，重置当前股票音频状态:', currentStock.stockInfo?.name);
        setStockAudioState(currentStock, { isPlaying: false, isPaused: false });
      }
    },
    onerror: (error) => {
      console.error(`${audioInfo.name}音频播放失败:`, error);
      isAudioPlaying.value = false;
      isPlayingQueueAudio.value = false;
      isCallingPlayNext = false;
      // 播放下一个音频
      setTimeout(() => {
        playNextAudio();
      }, 100);
    },
    onload: () => {
      emotionAudioStore.duration = audio.duration();
      console.log(
        `${audioInfo.name}音频加载完成，时长:`,
        emotionAudioStore.duration
      );
    },
  });

  // 设置当前音频URL到store
  emotionAudioStore.setCurrentAudioUrl(audioInfo.url);
  emotionAudioStore.nowSound = audio;
  emotionAudioStore.setAudioInstance(audio);

  console.log(`尝试播放${audioInfo.name}音频`);
  audio.play();
};

// 添加音频到播放队列
const addToAudioQueue = (
  url,
  name,
  shouldStartTypewriter = false,
  onComplete = null
) => {
  console.log(`=== 添加音频到队列 ===`);
  console.log("URL:", url);
  console.log("Name:", name);
  console.log("是否启动打字机效果:", shouldStartTypewriter);
  console.log("音频启用状态:", emotionAudioStore.isVoiceEnabled);

  if (url && emotionAudioStore.isVoiceEnabled) {
    const audioItem = {
      url,
      name,
      order: audioQueueOrder[name] || 999,
      shouldStartTypewriter, // 添加打字机效果标志
      onComplete, // 添加完成回调
    };
    audioQueue.value.push(audioItem);

    // 按顺序排序队列
    audioQueue.value.sort((a, b) => a.order - b.order);

    console.log(`音频${name}已添加到播放队列，顺序:${audioItem.order}`);
    console.log(
      "当前队列顺序:",
      audioQueue.value.map((item) => `${item.name}(${item.order})`)
    );

    // 只有在确实没有音频在播放且这是第一个音频时才开始播放
    if (
      !isPlayingQueueAudio.value &&
      !emotionAudioStore.isPlaying &&
      audioQueue.value.length === 1
    ) {
      console.log("✅ 条件满足：没有音频在播放且这是第一个音频，立即开始播放");
      playNextAudio();
    } else {
      console.log("⏳ 等待条件：", {
        isPlayingQueueAudio: isPlayingQueueAudio.value,
        audioStoreIsPlaying: emotionAudioStore.isPlaying,
        queueLength: audioQueue.value.length,
        reason:
          audioQueue.value.length > 1 ? "队列中已有其他音频" : "有音频正在播放",
      });
    }
  } else {
    console.log("❌ 跳过添加音频：", {
      hasUrl: !!url,
      voiceEnabled: emotionAudioStore.isVoiceEnabled,
    });
  }
};

// 修改后的音频播放函数 - 支持多音频播放和同步打字机效果
function playAudioQueue(
  conclusionData,
  shouldStartTypewriter = false,
  onComplete = null
) {
  if (!conclusionData) {
    console.log("没有结论数据，跳过播放");
    return;
  }

  // 检查是否启用了语音功能
  console.log("语音功能状态:", emotionAudioStore.isVoiceEnabled);
  if (!emotionAudioStore.isVoiceEnabled) {
    console.log("语音功能已关闭，跳过播放");
    return;
  }

  console.log(
    "开始处理多音频播放...",
    shouldStartTypewriter ? "同时启动打字机效果" : ""
  );

  try {
    // 解析结论数据
    const conclusion =
      typeof conclusionData === "object"
        ? conclusionData
        : JSON.parse(conclusionData);

    // 清空之前的音频队列
    audioQueue.value = [];
    currentPlayIndex = 0;
    isCallingPlayNext = false;
    isPlayingQueueAudio.value = false;

    // 按优先级顺序检查并添加所有可用的音频URL
    const audioSources = [
      { key: "one1_url", name: "one1_url" },
      { key: "one2_url", name: "one2_url" },
      { key: "two_url", name: "two_url" },
      { key: "three_url", name: "three_url" },
      { key: "four_url", name: "four_url" },
      { key: "url", name: "url" },
      { key: "audioUrl", name: "audioUrl" },
      { key: "voice_url", name: "voice_url" },
      { key: "audio", name: "audio" },
      { key: "tts_url", name: "tts_url" },
    ];

    audioSources.forEach((source) => {
      if (conclusion[source.key]) {
        const voiceUrl = conclusion[source.key]
          .toString()
          .trim()
          .replace(/[`\s]/g, "");
        if (voiceUrl && voiceUrl.startsWith("http")) {
          console.log(`找到音频URL: ${source.name} = ${voiceUrl}`);
          addToAudioQueue(
            voiceUrl,
            source.name,
            shouldStartTypewriter && audioQueue.value.length === 0,
            onComplete
          );
        }
      }
    });

    if (audioQueue.value.length === 0) {
      console.log("未找到有效的音频URL");
      // 如果没有音频但需要启动打字机效果，直接启动
      if (shouldStartTypewriter) {
        console.log("没有音频但需要启动打字机效果");
        const currentStock = emotionStore.activeStock;
        const stockId = currentStock ? getStockUniqueId(currentStock) : null;
        startTypewriterEffect(conclusion, stockId, onComplete);
      }
    } else {
      console.log(`总共找到 ${audioQueue.value.length} 个音频，准备播放`);
      
      // 设置当前股票的音频播放状态为播放中（自动播放时按钮应该是亮的）
      const currentStock = emotionStore.activeStock;
      if (currentStock) {
        console.log('设置当前股票音频状态为播放中:', currentStock.stockInfo?.name);
        setStockAudioState(currentStock, { isPlaying: true, isPaused: false });
      }
    }
  } catch (error) {
    console.error("处理音频播放失败:", error);
  }
}

// 原有的单音频播放函数（保持兼容性）
function playAudio(url) {
  console.log("尝试播放音频:", url);

  if (!url) {
    console.warn("音频URL为空，跳过播放");
    isAudioPlaying.value = false;
    return;
  }

  // 检查是否启用了语音功能
  console.log("语音功能状态:", emotionAudioStore.isVoiceEnabled);
  if (!emotionAudioStore.isVoiceEnabled) {
    console.log("语音功能已关闭，跳过播放");
    return;
  }

  console.log("开始创建音频实例...");

  try {
    // 设置当前音频URL
    emotionAudioStore.setCurrentAudioUrl(url);

    // 停止之前的音频
    if (emotionAudioStore.nowSound && emotionAudioStore.nowSound.playing()) {
      emotionAudioStore.nowSound.stop();
    }

    // 创建新的音频实例
    const newSound = new Howl({
      src: [url],
      html5: true,
      format: ["mp3", "wav"],
      onplay: () => {
        isAudioPlaying.value = true;
        emotionAudioStore.isPlaying = true;
        console.log("开始播放场景应用语音");
        
        // 设置当前股票的音频播放状态为播放中
        const currentStock = emotionStore.activeStock;
        if (currentStock) {
          setStockAudioState(currentStock, { isPlaying: true, isPaused: false });
          console.log('设置当前股票音频状态为播放中:', currentStock.stockInfo?.name);
        }
        // 音频开始播放时的自动滚动已移除
      },
      onend: () => {
        isAudioPlaying.value = false;
        emotionAudioStore.isPlaying = false;
        emotionAudioStore.isPaused = false;
        emotionAudioStore.playbackPosition = 0;
        console.log("场景应用语音播放结束");
        
        // 重置当前股票的音频播放状态
        const currentStock = emotionStore.activeStock;
        if (currentStock) {
          setStockAudioState(currentStock, { isPlaying: false, isPaused: false });
          console.log('重置当前股票音频状态:', currentStock.stockInfo?.name);
        }
      },
      onstop: () => {
        isAudioPlaying.value = false;
        emotionAudioStore.isPlaying = false;
        console.log("场景应用语音播放停止");
        
        // 重置当前股票的音频播放状态
        const currentStock = emotionStore.activeStock;
        if (currentStock) {
          setStockAudioState(currentStock, { isPlaying: false, isPaused: false });
          console.log('重置当前股票音频状态:', currentStock.stockInfo?.name);
        }
      },
      onpause: () => {
        isAudioPlaying.value = false;
        emotionAudioStore.isPlaying = false;
        console.log("场景应用语音播放暂停");
        
        // 设置当前股票的音频播放状态为暂停
        const currentStock = emotionStore.activeStock;
        if (currentStock) {
          setStockAudioState(currentStock, { isPlaying: false, isPaused: true });
          console.log('设置当前股票音频状态为暂停:', currentStock.stockInfo?.name);
        }
      },
      onerror: (error) => {
        isAudioPlaying.value = false;
        emotionAudioStore.isPlaying = false;
        console.error("音频播放错误:", error);
      },
      onload: () => {
        // 音频加载完成，获取时长
        emotionAudioStore.duration = newSound.duration();
        console.log("音频加载完成，时长:", emotionAudioStore.duration);
      },
    });

    // 保存音频实例到store
    emotionAudioStore.nowSound = newSound;
    emotionAudioStore.setAudioInstance(newSound);

    // 播放音频
    newSound.play();
  } catch (error) {
    console.error("创建音频实例失败:", error);
    isAudioPlaying.value = false;
  }
}

// 停止音频播放
function stopAudio() {
  if (emotionAudioStore.nowSound) {
    emotionAudioStore.nowSound.stop();
  }
  isAudioPlaying.value = false;
}
// 触发图片旋转的方法
function startImageRotation() {
  isRotating.value = true;
  // 如果你想在一段时间后停止旋转，可以添加以下代码
  setTimeout(() => {
    isRotating.value = false;
  }, 5000); // 5 秒后停止旋转
}

// 显示思考过程
async function showThinkingProcess(stockName = null) {
  // 第一步：正在思考
  const thinkingMessage1 = reactive({
    sender: "ai",
    text: "AI情绪大模型正在思考",
    gif: thinkingGif,
    flag: true, // 添加flag属性以显示动态加载点
  });
  messages.value.push(thinkingMessage1);
  await new Promise((resolve) => setTimeout(resolve, 1500));
  messages.value.pop();

  // 第二步：正在解析关键数据（持续显示直到获取到股票名称）
  const thinkingMessage2 = reactive({
    sender: "ai",
    text: "正在解析关键数据",
    gif: analyzeGif,
    flag: true, // 添加flag属性以显示动态加载点
  });
  messages.value.push(thinkingMessage2);

  // 如果没有股票名称，保持第二步显示
  if (!stockName) {
    return thinkingMessage2; // 返回消息引用，以便后续更新
  }

  // 有股票名称后，继续后续步骤
  await new Promise((resolve) => setTimeout(resolve, 1500));
  messages.value.pop();

  // 第三步：生成具体股票的量子四维矩阵图
  const thinkingMessage3 = reactive({
    sender: "ai",
    text: `正在生成${stockName}量子四维矩阵图`,
    gif: generateGif,
    flag: true, // 添加flag属性以显示动态加载点
  });
  messages.value.push(thinkingMessage3);
  await new Promise((resolve) => setTimeout(resolve, 1500));
  messages.value.pop();

  // 第四步：报告已生成
  const thinkingMessage4 = reactive({ sender: "ai", text: "报告已生成！" });
  messages.value.push(thinkingMessage4);
  await new Promise((resolve) => setTimeout(resolve, 1500));
  messages.value.pop();

  return null;
}

// 继续思考过程（当获取到股票名称后调用）
async function continueThinkingProcess(thinkingMessageRef, stockName) {
  if (!thinkingMessageRef || !stockName) return;

  // 等待一段时间后继续
  await new Promise((resolve) => setTimeout(resolve, 1500));

  // 移除第二步消息
  const index = messages.value.indexOf(thinkingMessageRef);
  if (index > -1) {
    messages.value.splice(index, 1);
  }

  // 第三步：生成具体股票的量子四维矩阵图
  const thinkingMessage3 = reactive({
    sender: "ai",
    text: `正在生成${stockName}量子四维矩阵图`,
    gif: generateGif,
    flag: true, // 添加flag属性以显示动态加载点
  });
  messages.value.push(thinkingMessage3);

  // 返回第三步消息的引用，以便后续处理
  return thinkingMessage3;
}

// 完成思考过程（当第二个工作流接口成功后调用）
async function finishThinkingProcess(thinkingMessage3Ref) {
  if (!thinkingMessage3Ref) return;

  // 等待一段时间
  await new Promise((resolve) => setTimeout(resolve, 1500));

  // 移除第三步消息
  const index = messages.value.indexOf(thinkingMessage3Ref);
  if (index > -1) {
    messages.value.splice(index, 1);
  }

  // 第四步：报告已生成
  const thinkingMessage4 = reactive({ sender: "ai", text: "报告已生成！" });
  messages.value.push(thinkingMessage4);
  await new Promise((resolve) => setTimeout(resolve, 1500));
  messages.value.pop();
}

// 发送消息方法
async function handleSendMessage(input, onComplete) {
  console.log("发送内容:", input);
  // 标记为用户主动搜索
  isUserInitiated.value = true;
  // 重置历史记录模式状态，确保正常对话时显示conversation-area
  isHistoryMode.value = false;

  // 检查用户输入内容是否为空
  if (!input || !input.trim()) {
    ElMessage.warning("输入内容不能为空");
    // 调用完成回调，重新启用输入框
    if (onComplete && typeof onComplete === "function") {
      onComplete();
      // 清除保存的回调函数
      currentOnCompleteCallback.value = null;
    }
    return;
  }

  // 用户输入不为空，立即清空页面内容并触发图片旋转逻辑
  isPageLoaded.value = false; // 立即隐藏页面内容
  isRotating.value = true;
  const previousMessages = [...messages.value]; // 保存历史消息
  messages.value = []; // 清空历史数据

  // 添加用户消息（只添加一次）
  const userMessage = reactive({ sender: "user", text: input });
  messages.value.push(userMessage);

  // 将用户消息添加到emotion store中
  emotionStore.addConversation({
    sender: "user",
    text: input,
    timestamp: new Date().toISOString(),
  });

  // 检查用户剩余次数
  // await chatStore.getUserCount(); // 获取最新的用户次数
  // if (chatStore.UserCount <= 0) {
  //   const aiMessage = reactive({
  //     sender: "ai",
  //     text: "您的剩余次数为0，无法使用情绪大模型，请联系客服或购买服务包。",
  //   });
  //   messages.value.push(aiMessage);

  //   // 将AI消息添加到emotion store中
  //   emotionStore.addConversation({
  //     sender: "ai",
  //     text: "您的剩余次数为0，无法使用情绪大模型，请联系客服或购买服务包。",
  //     timestamp: new Date().toISOString(),
  //   });
  //   // 停止图片旋转，恢复历史数据
  //   isRotating.value = false;
  //   messages.value = [...previousMessages, ...messages.value];
  //   // 调用完成回调，重新启用输入框
  //   if (onComplete && typeof onComplete === "function") {
  //     onComplete();
  //     // 清除保存的回调函数
  //     currentOnCompleteCallback.value = null;
  //   }
  //   return;
  // }

  // 开始思考过程（不带股票名称）
  const thinkingMessageRef = await showThinkingProcess();
  let thinkingMessage3Ref = null;

  try {
    // 第一步：调用第一个接口验证用户输入内容是否合法
    // const params = {
    //   content: userMessage.text,
    //   userData: {
    //     token: localStorage.getItem('localToken'),
    //     language: "cn",
    //     brainPrivilegeState: '1',
    //     swordPrivilegeState: '1',
    //     stockForecastPrivilegeState: '1',
    //     spaceForecastPrivilegeState: '1',
    //     aibullPrivilegeState: '1',
    //     aigoldBullPrivilegeState: '1',
    //     airadarPrivilegeState: '1',
    //     marketList: "hk,cn,usa,my,sg,vi,in,gb",
    //   },
    // };

    const result = await getReplyAPI({
      token: localStorage.getItem("localToken"),
      language: "cn",
      marketList: "hk,cn,usa,my,sg,vi,in,gb",
      content: userMessage.text,
    });
    const parsedData = result.data;
    console.log("第一个接口返回的完整数据:", parsedData);
    
    // 根据状态码判断并处理不同情况
    if (result.code === 400) {
      // 状态码400：用户输入内容不合法
      if (thinkingMessageRef) {
        const index = messages.value.indexOf(thinkingMessageRef);
        if (index > -1) {
          messages.value.splice(index, 1);
        }
      }

      isPageLoaded.value = false;
      const refuseMessage = result.msg || "用户输入内容不合法，请重新输入";
      const aiMessage = reactive({
        sender: "ai",
        text: processRefuseMessage(refuseMessage),
      });
      messages.value.push(aiMessage);

      emotionStore.addConversation({
        sender: "ai",
        text: processRefuseMessage(refuseMessage),
        timestamp: new Date().toISOString(),
      });
      isRotating.value = false;
      messages.value = [...previousMessages, ...messages.value];
      
      nextTick(() => {
        scrollToBottom();
      });
      
      if (onComplete && typeof onComplete === "function") {
        onComplete();
        currentOnCompleteCallback.value = null;
      }
      return;
    } else if (result.code === 406) {
      // 状态码406：token为0
      if (thinkingMessageRef) {
        const index = messages.value.indexOf(thinkingMessageRef);
        if (index > -1) {
          messages.value.splice(index, 1);
        }
      }

      isPageLoaded.value = false;
      const refuseMessage = result.msg || "您的使用次数已用完，请联系客服或购买服务包";
      
      // 处理消息中的"获取token次数"文字，将其转换为可点击的链接
      const processedMessage = processRefuseMessage(refuseMessage).replace(
        /获取token次数/g,
        '<span class="token-link" style="color: blue; cursor: pointer; text-decoration: underline;" onclick="window.handleTokenClick()">获取token次数</span>'
      );
      
      const aiMessage = reactive({
        sender: "ai",
        text: processedMessage,
        isHtml: true, // 标记这是HTML内容
      });
      messages.value.push(aiMessage);

      emotionStore.addConversation({
        sender: "ai",
        text: processedMessage,
        isHtml: true, // 保存HTML标记
        timestamp: new Date().toISOString(),
      });
      isRotating.value = false;
      messages.value = [...previousMessages, ...messages.value];
      
      nextTick(() => {
        scrollToBottom();
      });
      
      if (onComplete && typeof onComplete === "function") {
        onComplete();
        currentOnCompleteCallback.value = null;
      }
      return;
    } else if (result.code !== 200) {
      // 其他非200状态码，显示通用错误信息
      if (thinkingMessageRef) {
        const index = messages.value.indexOf(thinkingMessageRef);
        if (index > -1) {
          messages.value.splice(index, 1);
        }
      }

      isPageLoaded.value = false;
      const refuseMessage = result.msg || "系统异常，请稍后再试";
      const aiMessage = reactive({
        sender: "ai",
        text: processRefuseMessage(refuseMessage),
      });
      messages.value.push(aiMessage);

      emotionStore.addConversation({
        sender: "ai",
        text: processRefuseMessage(refuseMessage),
        timestamp: new Date().toISOString(),
      });
      isRotating.value = false;
      messages.value = [...previousMessages, ...messages.value];
      
      nextTick(() => {
        scrollToBottom();
      });
      
      if (onComplete && typeof onComplete === "function") {
        onComplete();
        currentOnCompleteCallback.value = null;
      }
      return;
    }
    
    // 状态码200：用户输入内容合法，检查数据完整性
    if (!parsedData || !parsedData.market || !parsedData.code) {
      // 输入不合法，先清理思考过程消息
      if (thinkingMessageRef) {
        const index = messages.value.indexOf(thinkingMessageRef);
        if (index > -1) {
          messages.value.splice(index, 1);
        }
      }

      // 关闭加载状态和等待提示，返回refuse信息，停止图片旋转，恢复历史数据
      // isLoading.value = false;
      isPageLoaded.value = false;
      const refuseMessage = result && result.msg ? result.msg : "系统正在为您努力加载中，请稍后再试";
      const aiMessage = reactive({
        sender: "ai",
        text: processRefuseMessage(refuseMessage),
      });
      messages.value.push(aiMessage);

      // 将AI消息添加到emotion store中
      emotionStore.addConversation({
        sender: "ai",
        text: processRefuseMessage(refuseMessage),
        timestamp: new Date().toISOString(),
      });
      isRotating.value = false;
      messages.value = [...previousMessages, ...messages.value];
      
      // 第一个接口请求失败后触发自动滚动
      nextTick(() => {
        scrollToBottom();
      });
      
      // 调用完成回调，重新启用输入框
      if (onComplete && typeof onComplete === "function") {
        onComplete();
        // 清除保存的回调函数
        currentOnCompleteCallback.value = null;
      }
      return;
    }

    // 输入合法，继续执行后续处理
    // 获取到股票名称后，继续思考过程
    if (thinkingMessageRef && parsedData.name) {
      thinkingMessage3Ref = await continueThinkingProcess(
        thinkingMessageRef,
        parsedData.name
      );
    }
    // 设置加载状态，隐藏图表页面
    // isLoading.value = true;

    isPageLoaded.value = false;

    // 调用第二个工作流接口
    const conclusionParams = {
      recordId: parsedData.recordId,
      parentId: parsedData.parentId,
      stockId: parsedData.stockId,
      token: localStorage.getItem("localToken"),
      language: "cn",
    };

    console.log("第二个接口参数:", conclusionParams);
    // 在Promise.all调用前添加股票唯一标识生成和判断逻辑
    const stockUniqueId = `${parsedData.code}_${parsedData.market}_${new Date().toISOString()}`;
    const isFirstTime = !stockTypewriterShown.value.has(stockUniqueId);

    // 提前设置打字机状态，避免渲染时机问题
    if (isFirstTime && isUserInitiated.value) {
      // 预设为打字机模式
      console.log('预设股票为打字机模式:', parsedData.name);
      stockTypewriterTexts.value.set(stockUniqueId, {
        one1: "", one2: "", two: "", three: "", four: "", disclaimer: ""
      });
      stockTypewriterVisibility.value.set(stockUniqueId, {
        one: false, two: false, three: false, four: false, disclaimer: false
      });
    } else {
      // 预设为完整显示模式
      console.log('预设股票为完整显示模式:', parsedData.name);
      stockTypewriterTexts.value.delete(stockUniqueId);
      stockTypewriterVisibility.value.delete(stockUniqueId);
      
      // 如果是第一次但非用户主动搜索，标记为已显示
      if (isFirstTime) {
        stockTypewriterShown.value.set(stockUniqueId, true);
        stockAudioPlayed.value.set(stockUniqueId, true);
      }
    }

    // 同时调用第二个数据流接口和fetchData方法
    const [conclusionResult, fetchDataResult] = await Promise.all([
      getConclusionAPI(conclusionParams),
      fetchData(
          parsedData.code,
          parsedData.market,
          parsedData.name || "未知股票",
          input.trim(),
          parsedData.stockId,
          stockUniqueId // 传递预生成的唯一标识
        ),
    ]);

    // 处理结论接口返回的数据
    const conclusionResponse = conclusionResult;
    
    // 检查getConclusionAPI是否成功
    if (conclusionResponse && conclusionResponse.code !== 200) {
      // getConclusionAPI失败，清理第三步思考过程消息
      if (thinkingMessage3Ref) {
        const index = messages.value.indexOf(thinkingMessage3Ref);
        if (index > -1) {
          messages.value.splice(index, 1);
        }
      }
      
      // 使用getConclusionAPI返回的msg在对话界面中输出
      const errorMsg = conclusionResponse.msg || "系统正在为您努力加载中，请稍后再试";
      const aiMessage = reactive({
        sender: "ai",
        text: errorMsg,
      });
      messages.value.push(aiMessage);
      
      // 停止图片旋转，恢复历史数据
      isRotating.value = false;
      messages.value = [...previousMessages, ...messages.value];
      
      // 如果有之前的股票数据且页面已加载，重新渲染图表
      // if (
      //   isPageLoaded.value &&
      //   emotionStore.activeStock &&
      //   emotionStore.activeStock.apiData
      // ) {
      //   nextTick(() => {
      //     renderCharts(emotionStore.activeStock.apiData);
      //     console.log(
      //       "第二个接口失败，恢复显示之前股票的图表:",
      //       emotionStore.activeStock.stockInfo.name
      //     );
      //   });
      // }
      
      // 调用完成回调，重新启用输入框
      if (onComplete && typeof onComplete === "function") {
        onComplete();
        currentOnCompleteCallback.value = null;
      }
      return;
    }
    
    // 检查所有数据是否都加载成功
    if (conclusionResponse && conclusionResponse.data && fetchDataResult) {
      // 第二个工作流接口成功，完成思考过程
      if (thinkingMessage3Ref) {
        await finishThinkingProcess(thinkingMessage3Ref);
      }

      // 将结论数据存储到响应式变量和store中
      conclusionData.value = conclusionResponse.data;
      console.log("第二个接口返回的完整数据结构:", conclusionResponse.data);
      // 将结论数据存储到store中的当前激活股票
      emotionStore.updateActiveStockConclusion(conclusionResponse.data);

      // 状态初始化现在由isStockStateReady方法自动处理，避免重复设置
      const stockUniqueId = getStockUniqueId(parsedData);
      if (stockUniqueId) {
        // 强制触发响应式更新，确保状态准备就绪
        nextTick(() => {
          console.log('数据加载完成，股票状态准备就绪:', parsedData.name, 'isReady:', isStockStateReady(parsedData));
        });
      }

      // 所有数据加载完成，关闭加载状态，显示页面
      // isLoading.value = false;
      isPageLoaded.value = true;

      // 使用nextTick确保DOM更新后清空对话显示
  nextTick(() => {
    messages.value = [];
    // 清空已添加股票的记录，避免重复添加
    addedStocks.value.clear();
    // 搜索新数据成功，但不启用内部自动滚动监听器，避免与父组件冲突
    shouldEnableAutoScroll.value = false;
    // 只通知父组件滚动到底部，不启动内部监听器
    scrollToBottom();
  });

      // 数据获取成功后，重新获取用户次数以实现实时更新
      try {
        await chatStore.getUserCount();
        console.log("数据获取成功后，用户次数已更新");
      } catch (error) {
        console.error("更新用户次数失败:", error);
      }

      // 重新调用获取历史记录的接口
      try {
        chatStore.searchRecord = true;
        console.log("getConclusionAPI成功后，已触发历史记录更新");
      } catch (error) {
        console.error("触发历史记录更新失败:", error);
      }

      // 确保页面状态更新后触发图表渲染和音频文本
      nextTick(() => {
        if (currentStock.value && currentStock.value.apiData) {
          renderCharts(currentStock.value.apiData);

          // 只有在用户主动搜索时才自动触发音频和文本
          if (
            isUserInitiated.value &&
            parsedConclusion.value &&
            audioUrl.value
          ) {
            const stockUniqueId = getStockUniqueId(currentStock.value);
            if (stockUniqueId && !stockTypewriterShown.value.has(stockUniqueId)) {
              if (!stockAudioPlayed.value.has(stockUniqueId)) {
                stockAudioPlayed.value.set(stockUniqueId, true);
                playAudioQueue(parsedConclusion.value, true, onComplete);
              } else {
                // 如果音频已播放过，只启动打字机效果
                startTypewriterEffect(parsedConclusion.value, stockUniqueId, onComplete);
              }
              stockTypewriterShown.value.set(stockUniqueId, true);
            } else {
              // 如果不需要打字机效果，直接调用完成回调
              if (onComplete && typeof onComplete === "function") {
                onComplete();
                // 清除保存的回调函数
                currentOnCompleteCallback.value = null;
              }
            }
          }

          // 重置用户主动搜索标志
          isUserInitiated.value = false;
        }
      });
    } else {
      // 数据加载失败，清理第三步思考过程消息
      if (thinkingMessage3Ref) {
        const index = messages.value.indexOf(thinkingMessage3Ref);
        if (index > -1) {
          messages.value.splice(index, 1);
        }
      }

      // 数据加载失败，停止图片旋转，恢复历史数据
      // isLoading.value = false;
      // 如果 fetchDataResult 为 false，说明数据不完整的错误信息已经在 fetchData 中添加到 messages
      // 只有在 conclusionResponse 有问题时才添加通用错误信息
      if (!conclusionResponse || !conclusionResponse.data) {
        const aiMessage = reactive({
          sender: "ai",
          text: "系统正在为您努力加载中，请稍后再试",
        });
        messages.value.push(aiMessage);
      }
      isRotating.value = false;
      messages.value = [...previousMessages, ...messages.value];

      // 如果有之前的股票数据且页面已加载，重新渲染图表
      if (
        isPageLoaded.value &&
        emotionStore.activeStock &&
        emotionStore.activeStock.apiData
      ) {
        nextTick(() => {
          renderCharts(emotionStore.activeStock.apiData);
          console.log(
            "搜索失败，恢复显示之前股票的图表:",
            emotionStore.activeStock.stockInfo.name
          );
        });
      }

      // 调用完成回调，重新启用输入框
      if (onComplete && typeof onComplete === "function") {
        onComplete();
        // 清除保存的回调函数
        currentOnCompleteCallback.value = null;
      }
      return;
    }
  } catch (error) {
    // 请求失败，清理第三步思考过程消息
    if (thinkingMessage3Ref) {
      const index = messages.value.indexOf(thinkingMessage3Ref);
      if (index > -1) {
        messages.value.splice(index, 1);
      }
    }

    // 请求失败时关闭加载状态
    // isLoading.value = false;

    // 如果有之前的股票数据，恢复显示状态；否则设置为false
    if (emotionStore.stockList.length > 0 && emotionStore.activeStock) {
      isPageLoaded.value = true;
      // 使用nextTick确保DOM更新后清空对话显示并启动高度监听器
      nextTick(() => {
        messages.value = [];
        // 搜索失败恢复场景，不启用自动滚动
        shouldEnableAutoScroll.value = false;
        // 不启动内部滚动监听器，避免与父组件冲突
        // 只通知父组件滚动到底部
        scrollToBottom();
      });
      console.log("请求工作流接口失败，但恢复显示之前的股票数据");
      // 立即渲染之前股票的图表，提升用户体验
      nextTick(() => {
        renderCharts(emotionStore.activeStock.apiData);
        console.log(
          "立即恢复显示之前股票的图表:",
          emotionStore.activeStock.stockInfo.name
        );
      });
    } else {
      isPageLoaded.value = false;
    }

    // 请求失败时停止图片旋转，恢复历史数据
    isRotating.value = false;
    messages.value = [...previousMessages, ...messages.value];

    // 如果有之前的股票数据且页面已加载，重新渲染图表
    if (
      isPageLoaded.value &&
      emotionStore.activeStock &&
      emotionStore.activeStock.apiData
    ) {
      nextTick(() => {
        renderCharts(emotionStore.activeStock.apiData);
        console.log(
          "请求失败，恢复显示之前股票的图表:",
          emotionStore.activeStock.stockInfo.name
        );
      });
    }

    // 调用完成回调，重新启用输入框
    if (onComplete && typeof onComplete === "function") {
      onComplete();
      // 清除保存的回调函数
      currentOnCompleteCallback.value = null;
    }
    return;
  } finally {
    // 停止图片旋转（只有在设置了旋转状态时才需要停止）
    if (isRotating.value) {
      isRotating.value = false;
    }
  }
}

// 请求数据接口
async function fetchData(code, market, stockName, queryText, stockId, presetUniqueId = null) {
  try {
    const stockDataParams = {
      stockId: stockId,
    };
    const stockDataResult = await axios.post(
      // "http://39.101.133.168:8828/link/api/aiEmotion/client/getAiEmotionData",
      `${APIurl}/api/workflow/getStockData`,
      stockDataParams,
      {
        headers: {
          "Content-Type": "application/json",
        },
      }
    );

    const stockDataResponse = stockDataResult.data; // 获取返回所有的数据

    if (stockDataResponse.code === 200 && stockDataResponse.data) {
      // 检查关键数据字段是否完整
      const validation = validateRequiredFields(stockDataResponse.data);

      // 如果有关键数据缺失，返回失败，不添加到StockTabs
      if (!validation.isValid) {
        console.log("API返回数据不完整，缺失字段:", validation.missingFields);
        // 关闭加载状态
        // isLoading.value = false;

        // 如果有之前的股票数据，恢复显示状态；否则设置为false
        if (emotionStore.stockList.length > 0 && emotionStore.activeStock) {
          isPageLoaded.value = true;
          // 使用nextTick确保DOM更新后清空对话显示并启动高度监听器
          nextTick(() => {
            messages.value = [];
            // 数据验证失败恢复场景，不启用自动滚动
            shouldEnableAutoScroll.value = false;
            // 不启动内部滚动监听器，避免与父组件冲突
            // 只通知父组件滚动到底部
            scrollToBottom();
          });
          console.log("数据验证失败，但恢复显示之前的股票数据");
          // 立即渲染之前股票的图表，提升用户体验
          nextTick(() => {
            renderCharts(emotionStore.activeStock.apiData);
            console.log(
              "立即恢复显示之前股票的图表:",
              emotionStore.activeStock.stockInfo.name
            );
          });
        } else {
          isPageLoaded.value = false;
        }

        const aiMessage = reactive({
          sender: "ai",
          text: `系统正在为您努力加载中，请稍后再试`,
        });
        messages.value.push(aiMessage);

        // 将AI消息添加到emotion store中
        emotionStore.addConversation({
          sender: "ai",
          text: "系统正在为您努力加载中，请稍后再试",
          timestamp: new Date().toISOString(),
        });
        return false; // 返回失败标识，不添加股票到标签
      }

      // 只有数据完整时才创建股票数据对象并添加到store
      const stockData = {
        queryText: queryText,
        stockInfo: {
          name: stockName,
          code: code,
          market: market,
        },
        apiData: stockDataResponse.data,
        conclusionData: conclusionData.value, // 包含结论数据
        timestamp: new Date().toISOString(),
        uniqueId: presetUniqueId || `${code}_${market}_${new Date().toISOString()}`, // 添加唯一标识
      };
      // 将股票数据添加到store中，显示在StockTabs中
      emotionStore.addStock(stockData);
      return true; // 返回成功标识
    } else {
      // 关闭加载状态
      // isLoading.value = false;

      // 如果有之前的股票数据，恢复显示状态；否则设置为false
      if (emotionStore.stockList.length > 0 && emotionStore.activeStock) {
        isPageLoaded.value = true;
        // 使用nextTick确保DOM更新后清空对话显示并启动高度监听器
        nextTick(() => {
          messages.value = [];
          // API请求失败恢复场景，不启用自动滚动
          shouldEnableAutoScroll.value = false;
          // 不启动内部滚动监听器，避免与父组件冲突
          // 只通知父组件滚动到底部
          scrollToBottom();
        });
        console.log("API请求失败，但恢复显示之前的股票数据");
        // 立即渲染之前股票的图表，提升用户体验
        nextTick(() => {
          renderCharts(emotionStore.activeStock.apiData);
          console.log(
            "立即恢复显示之前股票的图表:",
            emotionStore.activeStock.stockInfo.name
          );
        });
      } else {
        isPageLoaded.value = false;
      }

      const aiMessage = reactive({
        sender: "ai",
        text: "系统正在为您努力加载中，请稍后再试",
      });
      messages.value.push(aiMessage);

      // 将AI消息添加到emotion store中
      emotionStore.addConversation({
        sender: "ai",
        text: "系统正在为您努力加载中，请稍后再试",
        timestamp: new Date().toISOString(),
      });
      return false; // 返回失败标识
    }
  } catch (error) {
    // 关闭加载状态
    // isLoading.value = false;

    // 如果有之前的股票数据，恢复显示状态；否则设置为false
    if (emotionStore.stockList.length > 0 && emotionStore.activeStock) {
      isPageLoaded.value = true;
      // 使用nextTick确保DOM更新后清空对话显示并启动高度监听器
      nextTick(() => {
        messages.value = [];
        // 网络异常恢复场景，不启用自动滚动
        shouldEnableAutoScroll.value = false;
        // 不启动内部滚动监听器，避免与父组件冲突
        // 只通知父组件滚动到底部
        scrollToBottom();
      });
      console.log("网络异常，但恢复显示之前的股票数据");
      // 立即渲染之前股票的图表，提升用户体验
      nextTick(() => {
        renderCharts(emotionStore.activeStock.apiData);
        console.log(
          "立即恢复显示之前股票的图表:",
          emotionStore.activeStock.stockInfo.name
        );
      });
    } else {
      isPageLoaded.value = false;
    }

    const aiMessage = reactive({
      sender: "ai",
      text: "系统正在为您努力加载中，请稍后再试",
    });
    messages.value.push(aiMessage);

    // 将AI消息添加到emotion store中
    emotionStore.addConversation({
      sender: "ai",
      text: "系统正在为您努力加载中，请稍后再试",
      timestamp: new Date().toISOString(),
    });
    return false; // 返回失败标识
  }
}

// 检查关键数据字段是否完整的函数
function validateRequiredFields(data) {
  const requiredFields = ["GSWDJ", "KLine20", "QXJMQ", "QXTDLD", "WDRL"];
  const missingFields = [];

  for (const field of requiredFields) {
    if (
      !data[field] ||
      (Array.isArray(data[field]) && data[field].length === 0) ||
      (typeof data[field] === "object" && !hasValidData(data[field]))
    ) {
      missingFields.push(field);
    }
  }

  return {
    isValid: missingFields.length === 0,
    missingFields: missingFields,
  };
}

// 检查对象是否包含有效数据的辅助函数
function hasValidData(obj) {
  if (!obj || typeof obj !== "object") {
    return false;
  }

  // 定义可以为空的数组字段
  const allowedEmptyArrays = ["lowxh", "qixh", "topxh"];

  // 检查对象的所有属性值
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      const value = obj[key];

      // 如果是字符串字段
      if (typeof value === "string") {
        // 字符串字段必须有内容，为空则表示异常
        if (value.trim() !== "") {
          return true;
        }
      }
      // 如果是数组字段
      else if (Array.isArray(value)) {
        // 数组字段可以为空，但如果有内容则表示有效
        if (value.length > 0) {
          return true;
        }
      }
      // 如果是数字且不为0
      else if (typeof value === "number" && value !== 0) {
        return true;
      }
      // 如果是布尔值且为true
      else if (typeof value === "boolean" && value === true) {
        return true;
      }
      // 如果是对象且包含有效数据（递归检查）
      else if (typeof value === "object" && value !== null) {
        if (hasValidData(value)) {
          return true;
        }
      }
    }
  }

  return false;
}

// 依次渲染图表的方法 - 支持多个股票
async function renderChartsSequentially(clonedData, stockIndex = 0) {
  console.log(`开始渲染第${stockIndex}个股票的图表`);

  // 定义图表渲染顺序和配置
  const chartConfigs = [
    {
      name: "股市温度计",
      ref: marketTemperatureRef.value[stockIndex],
      visibility: chartVisibility.value.marketTemperature,
      method: "initChart",
      params: [clonedData.GSWDJ, clonedData.KLine20, clonedData.WDRL],
    },
    {
      name: "情绪解码器",
      ref: emotionDecodRef.value[stockIndex],
      visibility: chartVisibility.value.emotionDecod,
      method: "initQXNLZHEcharts",
      params: [clonedData.KLine20, clonedData.QXJMQ],
    },
    {
      name: "情绪探底雷达",
      ref: emotionalBottomRadarRef.value[stockIndex],
      visibility: chartVisibility.value.emotionalBottomRadar,
      method: "initEmotionalBottomRadar",
      params: [clonedData.KLine20, clonedData.QXTDLD],
    },
    {
      name: "情绪能量转化器",
      ref: emoEnergyConverterRef.value[stockIndex],
      visibility: chartVisibility.value.emoEnergyConverter,
      method: "initQXNLZHEcharts",
      params: [clonedData.KLine20, clonedData.QXNLZHQ],
    },
  ];

  // 依次渲染每个图表
  for (const config of chartConfigs) {
    if (config.ref && config.visibility) {
      console.log(`开始渲染第${stockIndex}个股票的${config.name}图表`);
      console.log(`${config.name}Ref方法:`, typeof config.ref[config.method]);

      if (typeof config.ref[config.method] === "function") {
          try {
            // 增加延迟时间，特别是对于第2个及后续股票
            const delay = stockIndex === 0 ? 100 : 300 + (stockIndex * 100);
            await new Promise((resolve) => setTimeout(resolve, delay));
            
            config.ref[config.method](...config.params);
            console.log(`第${stockIndex}个股票的${config.name}图表渲染成功`);
            
            // 每个图表渲染完成后等待一段时间再渲染下一个
            await new Promise((resolve) => setTimeout(resolve, 800));
          } catch (error) {
            console.error(
              `第${stockIndex}个股票的${config.name}图表渲染失败:`,
              error
            );
          }
        } else {
        console.error(
          `第${stockIndex}个股票的${config.name}Ref.${config.method} 方法不存在`
        );
      }
    } else {
      console.log(
        `第${stockIndex}个股票的${config.name}图表未渲染，ref存在:`,
        !!config.ref,
        "数据存在:",
        config.visibility
      );
    }
  }

  console.log(`第${stockIndex}个股票的所有图表依次渲染完成`);
}

// 渲染组件图表的方法
function renderCharts(data) {
  console.log("开始渲染图表，数据:", data);

  // 深拷贝数据避免污染原始数据
  const clonedData = JSON.parse(JSON.stringify(data));

  // 检查关键数据字段是否完整
  const validation = validateRequiredFields(clonedData);

  // 如果有任何关键数据缺失，不渲染页面并返回提示
  if (!validation.isValid) {
    console.log("关键数据缺失:", validation.missingFields);
    const aiMessage = reactive({
      sender: "ai",
      text: `数据不完整，缺少以下关键数据：${validation.missingFields.join(
        "、"
      )}。请稍后重试或联系客服。`,
    });
    messages.value.push(aiMessage);

    // 将AI消息添加到emotion store中
    emotionStore.addConversation({
      sender: "ai",
      text: `数据不完整，缺少以下关键数据：${validation.missingFields.join(
        "、"
      )}。请稍后重试或联系客服。`,
      timestamp: new Date().toISOString(),
    });

    // 隐藏页面内容
    isPageLoaded.value = false;
    // isLoading.value = false;

    return; // 直接返回，不进行后续渲染
  }

  // 先设置图表组件显示状态
  chartVisibility.value = {
    marketTemperature: !!(clonedData.GSWDJ && clonedData.GSWDJ.length > 0),
    emotionDecod: !!(clonedData.QXJMQ && clonedData.QXJMQ.length > 0),
    emotionalBottomRadar: !!(clonedData.QXTDLD && clonedData.QXTDLD.length > 0),
    emoEnergyConverter: !!(
      clonedData.QXNLZHQ &&
      (Array.isArray(clonedData.QXNLZHQ)
        ? clonedData.QXNLZHQ.length > 0
        : hasValidData(clonedData.QXNLZHQ))
    ),
  };

  console.log("图表显示状态:", chartVisibility.value);
  console.log("数据检查:", {
    GSWDJ: !!(clonedData.GSWDJ && clonedData.GSWDJ.length > 0),
    QXJMQ: !!(clonedData.QXJMQ && clonedData.QXJMQ.length > 0),
    QXTDLD: !!(clonedData.QXTDLD && clonedData.QXTDLD.length > 0),
    QXNLZHQ: !!(
      clonedData.QXNLZHQ &&
      (Array.isArray(clonedData.QXNLZHQ)
        ? clonedData.QXNLZHQ.length > 0
        : hasValidData(clonedData.QXNLZHQ))
    ),
  });
  console.log("QXNLZHQ数据详情:", clonedData.QXNLZHQ);

  nextTick(() => {
    // 增加延迟确保DOM完全更新和组件完全挂载
    setTimeout(() => {
      try {
        console.log("图表组件ref状态:", {
          marketTemperatureRef: !!marketTemperatureRef.value,
          emotionDecodRef: !!emotionDecodRef.value,
          emotionalBottomRadarRef: !!emotionalBottomRadarRef.value,
          emoEnergyConverterRef: !!emoEnergyConverterRef.value,
        });

        // 检查DOM元素是否存在
        console.log("DOM元素检查:", {
          marketTemperatureDOM: !!document.querySelector(
            ".market-temperature-section"
          ),
          emotionDecodDOM: !!document.querySelector(".emotion-decoder-section"),
          emotionalBottomRadarDOM: !!document.querySelector(
            ".bottom-radar-section"
          ),
          emoEnergyConverterDOM: !!document.querySelector(
            ".energy-converter-section"
          ),
        });

        // 检查具体的组件元素
        const emoEnergyElement = document.querySelector("emo-energy-converter");
        console.log("emoEnergyConverter元素:", emoEnergyElement);

        // 等待更长时间再次检查ref
        setTimeout(() => {
          console.log(
            "延迟检查emoEnergyConverterRef:",
            !!emoEnergyConverterRef.value
          );
          if (emoEnergyConverterRef.value) {
            console.log(
              "emoEnergyConverter方法:",
              typeof emoEnergyConverterRef.value.initQXNLZHEcharts
            );
          }
        }, 1000);

        // 开始依次渲染图表 - 为每个股票渲染
        emotionStore.stockList.forEach((stock, index) => {
          if (stock.apiData) {
            renderChartsSequentially(stock.apiData, index);
          }
        });

        console.log("图表渲染完成");
      } catch (error) {
        console.error("图表渲染错误:", error);
        const aiMessage = reactive({
          sender: "ai",
          text: "图表渲染失败，请重试",
        });
        messages.value.push(aiMessage);

        // 将AI消息添加到emotion store中
        emotionStore.addConversation({
          sender: "ai",
          text: "系统正在为您努力加载中，请稍后再试",
          timestamp: new Date().toISOString(),
        });
      }
    }, 500); // 增加延迟到500ms确保DOM和组件完全稳定
  });
}

// scrollToBottom函数已移除

// 处理用户滚动事件
const handleUserScroll = () => {
  // 标记用户正在滚动
  isUserScrolling.value = true;
  
  // 清除之前的定时器
  if (userScrollTimer.value) {
    clearTimeout(userScrollTimer.value);
  }
  
  // 设置定时器，2秒后恢复自动滚动
  userScrollTimer.value = setTimeout(() => {
    isUserScrolling.value = false;
    console.log("用户滚动检测：恢复自动滚动");
  }, 2000);
};

// 处理滚轮事件
const handleWheel = (event) => {
  handleUserScroll();
};

// 处理触摸滚动事件
const handleTouchMove = (event) => {
  handleUserScroll();
};

// 检查数据是否已加载完成
function isDataLoaded() {
  // 检查页面是否已加载
  if (!isPageLoaded.value) {
    console.log("页面数据尚未加载完成");
    return false;
  }

  // 检查当前股票数据是否存在
  if (!currentStock.value || !currentStock.value.apiData) {
    console.log("股票数据尚未加载完成");
    return false;
  }

  // 检查图表组件是否已渲染 - 检查所有股票的组件
  const stockCount = emotionStore.stockList.length;
  if (stockCount === 0) {
    console.log("没有股票数据");
    return false;
  }

  // 检查每个股票的图表组件是否都已加载
  for (let i = 0; i < stockCount; i++) {
    const requiredRefs = [
      marketTemperatureRef.value[i],
      emotionDecodRef.value[i],
      emotionalBottomRadarRef.value[i],
      emoEnergyConverterRef.value[i],
    ];

    const allRefsLoaded = requiredRefs.every((ref) => ref !== null);
    if (!allRefsLoaded) {
      console.log(`第${i}个股票的图表组件尚未完全加载`);
      return false;
    }
  }

  console.log("所有数据和组件已加载完成");
  return true;
}

// 自动滚动函数已移除

// 设置Intersection Observer监听场景应用部分
function setupIntersectionObserver() {
  // 检查 scenarioApplicationRef.value 是否存在且是有效的 DOM 元素
  if (
    !scenarioApplicationRef.value ||
    !(scenarioApplicationRef.value instanceof Element)
  ) {
    console.warn(
      "scenarioApplicationRef.value 不是有效的 DOM 元素，跳过 IntersectionObserver 设置"
    );
    return;
  }

  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          console.log("场景应用部分进入视口");

          // 获取当前股票唯一标识
          const stockUniqueId = currentStock.value ? getStockUniqueId(currentStock.value) : null;

          if (parsedConclusion.value && stockUniqueId) {
            // 检查该股票是否是第一次触发
            if (!stockTypewriterShown.value.has(stockUniqueId)) {
              // 如果是用户主动搜索，启动打字机效果和音频播放
              if (isUserInitiated.value && audioUrl.value) {
                console.log(
                  "用户主动搜索，该股票第一次进入场景应用，开始打字机效果和音频播放"
                );

                // 用户主动搜索时，每次都播放音频和打字机效果
                console.log("开始音频播放和打字机效果");
                stockAudioPlayed.value.set(stockUniqueId, true);
                playAudioQueue(parsedConclusion.value, true);

                stockTypewriterShown.value.set(stockUniqueId, true);
              } else {
                // 非用户主动搜索（如历史记录恢复），直接显示完整内容
                console.log(
                  "非用户主动搜索，该股票第一次进入场景应用，直接显示完整内容"
                );

                // 结论内容现在直接通过parsedConclusion计算属性显示

                // 记录该股票已显示过
                stockTypewriterShown.value.set(stockUniqueId, true);
                stockAudioPlayed.value.set(stockUniqueId, true);
              }
            } else {
              // 非第一次或已经触发过：直接显示完整内容，不播放音频和打字机效果
              console.log("非第一次进入场景应用或已触发过，直接显示完整内容");

              // 结论内容现在直接通过parsedConclusion计算属性显示
            }
          }
        }
      });
    },
    {
      threshold: 0.3, // 当30%的元素进入视口时触发
      rootMargin: "0px 0px -100px 0px", // 提前100px触发
    }
  );

  observer.observe(scenarioApplicationRef.value);
  intersectionObserver.value = observer;
}

// 手动触发自动滚动函数已移除

// 返回顶部功能
const scrollToTop = () => {
  const topAnchor = document.getElementById("top-anchor");
  if (topAnchor) {
    topAnchor.scrollIntoView({
      behavior: "smooth",
      block: "start",
      inline: "nearest",
    });
  } else {
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  // 备用方案：直接滚动到页面顶部
  setTimeout(() => {
    const currentScrollTop =
      window.pageYOffset || document.documentElement.scrollTop;
    if (currentScrollTop > 50) {
      document.documentElement.scrollTop = 0;
      document.body.scrollTop = 0;
    }
  }, 1000);
};

// 页面高度监听器
const heightObserver = ref(null);
const isAutoScrollEnabled = ref(false);

// 滚动到底部功能 - 通过emit通知父组件进行容器滚动
const scrollToBottom = () => {
  // 使用nextTick确保DOM已更新
  nextTick(() => {
    // 通过emit事件通知父组件进行滚动
    emit('scrollToBottom');
  });
};

// 防抖滚动函数
const debouncedScrollToBottom = (() => {
  let timeoutId = null;
  return () => {
    if (timeoutId) {
      clearTimeout(timeoutId);
    }
    timeoutId = setTimeout(() => {
      // 只有在自动滚动启用、页面已加载且用户未手动滚动时才执行自动滚动
      if (isAutoScrollEnabled.value && isPageLoaded.value && !isUserScrolling.value) {
        scrollToBottom();
      }
    }, 150);
  };
})();

// 启动页面高度监听器
const startHeightObserver = () => {
  // 先停止之前的监听器
  stopHeightObserver();

  // 只有在应该启用自动滚动时才启动监听器
  if (!shouldEnableAutoScroll.value) {
    console.log("跳过启动自动滚动监听器：非搜索新数据场景");
    return;
  }

  isAutoScrollEnabled.value = true;

  // 创建ResizeObserver监听页面内容变化
  heightObserver.value = new ResizeObserver((entries) => {
    if (isAutoScrollEnabled.value && isPageLoaded.value) {
      debouncedScrollToBottom();
    }
  });

  // 监听document.body的尺寸变化
  if (document.body) {
    heightObserver.value.observe(document.body);
  }

  // 创建MutationObserver监听DOM结构变化
  const mutationObserver = new MutationObserver((mutations) => {
    let shouldScroll = false;
    mutations.forEach((mutation) => {
      if (mutation.type === "childList" && mutation.addedNodes.length > 0) {
        // 检查新增的节点是否包含实际内容
        const hasContent = Array.from(mutation.addedNodes).some((node) => {
          if (node.nodeType === Node.ELEMENT_NODE) {
            return node.offsetHeight > 0 || node.scrollHeight > 0;
          }
          return (
            node.nodeType === Node.TEXT_NODE &&
            node.textContent.trim().length > 0
          );
        });
        if (hasContent) {
          shouldScroll = true;
        }
      }
    });

    if (shouldScroll && isAutoScrollEnabled.value && isPageLoaded.value) {
      debouncedScrollToBottom();
    }
  });

  // 监听主要内容区域的DOM变化
  const mainContainer = document.querySelector(".main") || document.body;
  if (mainContainer) {
    mutationObserver.observe(mainContainer, {
      childList: true,
      subtree: true,
      attributes: false,
      characterData: true,
    });
  }

  // 保存mutationObserver引用以便清理
  heightObserver.value.mutationObserver = mutationObserver;

  console.log("页面高度监听器已启动");
};

// 停止页面高度监听器
const stopHeightObserver = () => {
  isAutoScrollEnabled.value = false;

  if (heightObserver.value) {
    // 清理ResizeObserver
    heightObserver.value.disconnect();

    // 清理MutationObserver
    if (heightObserver.value.mutationObserver) {
      heightObserver.value.mutationObserver.disconnect();
      heightObserver.value.mutationObserver = null;
    }

    heightObserver.value = null;
  }

  console.log("页面高度监听器已停止");
};

// 监听页面滚动，控制返回顶部按钮显示
const handlePageScroll = () => {
  const scrollTop =
    window.pageYOffset ||
    document.documentElement.scrollTop ||
    document.body.scrollTop;
  showBackToTop.value = scrollTop > 200;
};

// 监听容器滚动（备用方案）
const handleContainerScroll = () => {
  const container = userInputDisplayRef.value;
  if (container) {
    const scrollTop = container.scrollTop;
    if (scrollTop > 200) {
      showBackToTop.value = true;
    }
  }
};

// 页面挂载完成后触发图片旋转和设置滚动监听
onMounted(async () => {
  // 设置全局点击处理函数
  window.handleTokenClick = () => {
    emit('showCount');
  };
  
  // 恢复对话记录
  loadConversationsFromStore();
  // 从stockList加载对话记录
  loadConversationsFromStockList();

  // 确保获取用户次数
  // try {
  //   await chatStore.getUserCount();
  //   console.log('情绪大模型页面：用户次数获取成功');
  // } catch (error) {
  //   console.error('情绪大模型页面：获取用户次数失败', error);
  // }

  // 添加全局resize监听器，确保所有图表和容器响应页面宽度变化
  const globalResizeHandler = debounce(() => {
    console.log("AiEmotion页面：窗口大小变化，触发容器和图表resize");

    // 强制重新计算容器布局
    const mainContainer = document.querySelector(".main");
    if (mainContainer) {
      // 触发重排，确保容器尺寸正确更新
      mainContainer.style.display = "none";
      mainContainer.offsetHeight; // 强制重排
      mainContainer.style.display = "";
    }

    // 触发所有图表组件的resize
    const resizeHandlers = [
      window.emoEnergyConverterResizeHandler,
      window.marketTempResizeHandler,
      window.emotionalBottomRadarResizeHandler,
      window.emotionDecodResizeHandler,
    ];

    resizeHandlers.forEach((handler) => {
      if (typeof handler === "function") {
        try {
          handler();
        } catch (error) {
          console.error("AiEmotion页面：图表resize失败", error);
        }
      }
    });

    // 延迟再次触发图表resize，确保容器尺寸稳定后图表能正确适配
    setTimeout(() => {
      resizeHandlers.forEach((handler) => {
        if (typeof handler === "function") {
          try {
            handler();
          } catch (error) {
            console.error("AiEmotion页面：延迟图表resize失败", error);
          }
        }
      });
    }, 100);
  }, 150); // 150ms防抖延迟

  // 移除之前的监听器（如果存在）
  if (window.aiEmotionGlobalResizeHandler) {
    window.removeEventListener("resize", window.aiEmotionGlobalResizeHandler);
  }

  // 添加新的监听器
  window.addEventListener("resize", globalResizeHandler);
  window.aiEmotionGlobalResizeHandler = globalResizeHandler;

  // 添加滚动事件监听器
  const container = userInputDisplayRef.value;
  if (container) {
    container.addEventListener("wheel", handleWheel, { passive: true });
    container.addEventListener("touchmove", handleTouchMove, { passive: true });
    container.addEventListener("scroll", handleUserScroll, { passive: true });
    // 添加容器滚动监听器用于返回顶部按钮
    container.addEventListener("scroll", handleContainerScroll, {
      passive: true,
    });
  }

  // 添加页面滚动监听器，控制返回顶部按钮显示
  window.addEventListener("scroll", handlePageScroll, { passive: true });

  // 添加document滚动监听器（备用方案）
  document.addEventListener("scroll", handlePageScroll, { passive: true });

  // 防抖函数定义
  function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
      const later = () => {
        clearTimeout(timeout);
        func(...args);
      };
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
    };
  }

  startImageRotation();

  // 检查是否有已保存的股票数据需要恢复
  if (emotionStore.stockList.length > 0 && emotionStore.activeStock) {
    console.log("检测到已保存的股票数据，开始恢复页面状态（不自动播放音频）");

    // 恢复页面加载状态
    isPageLoaded.value = true;
    // 使用nextTick确保DOM更新后清空对话显示
    nextTick(() => {
      messages.value = [];
      // 组件挂载时恢复数据场景，不启用自动滚动，完全依赖父组件管理
      shouldEnableAutoScroll.value = false;
      // 不启动内部滚动监听器，避免与父组件冲突
      // 组件挂载时恢复数据不滚动到底部，保持在顶部
    });

    // 等待DOM渲染后恢复图表和数据
    nextTick(() => {
      const currentStockData = emotionStore.activeStock;
      if (currentStockData && currentStockData.apiData) {
        console.log("恢复图表数据:", currentStockData.stockInfo.name);
        renderCharts(currentStockData.apiData);

        // 恢复结论数据并显示内容
        if (currentStockData.conclusionData) {
          conclusionData.value = currentStockData.conclusionData;

          // 结论内容现在直接通过parsedConclusion计算属性显示
          conclusionData.value = currentStockData.conclusionData;

          // 标记该股票的打字机效果和音频已经显示过，避免后续自动触发
          const stockUniqueId = getStockUniqueId(currentStockData);
          if (stockUniqueId) {
            stockTypewriterShown.value.set(stockUniqueId, true);
            stockAudioPlayed.value.set(stockUniqueId, true);
          }
        }
      }

      setupIntersectionObserver();
    });
  } else {
    // 没有保存的数据，正常设置监听器
    nextTick(() => {
      setupIntersectionObserver();
    });
  }
});

// 组件卸载时清理定时器、音频和observer
onUnmounted(() => {
  clearTypewriterTimers();

  // 如果有未完成的回调函数，调用它来重新启用输入框
  if (
    currentOnCompleteCallback.value &&
    typeof currentOnCompleteCallback.value === "function"
  ) {
    currentOnCompleteCallback.value();
    currentOnCompleteCallback.value = null;
  }

  stopAudio();

  // 重置触发状态
  hasTriggeredAudio.value = false;
  hasTriggeredTypewriter.value = false;

  // 清理页面高度监听器
  stopHeightObserver();

  // 清理用户滚动检测定时器
  if (userScrollTimer.value) {
    clearTimeout(userScrollTimer.value);
    userScrollTimer.value = null;
  }

  // 清理Intersection Observer
  if (intersectionObserver.value) {
    intersectionObserver.value.disconnect();
    intersectionObserver.value = null;
  }

  // 清理全局resize监听器
  if (window.aiEmotionGlobalResizeHandler) {
    window.removeEventListener("resize", window.aiEmotionGlobalResizeHandler);
    window.aiEmotionGlobalResizeHandler = null;
  }

  // 清理滚动事件监听器
  const container = userInputDisplayRef.value;
  if (container) {
    container.removeEventListener("wheel", handleWheel);
    container.removeEventListener("touchmove", handleTouchMove);
    container.removeEventListener("scroll", handleUserScroll);
    container.removeEventListener("scroll", handleContainerScroll);
  }

  // 清理页面滚动监听器
  window.removeEventListener("scroll", handlePageScroll);
  document.removeEventListener("scroll", handlePageScroll);

  // 滚动相关清理已简化
});

// 声明组件可以触发的事件
const emit = defineEmits(["updateMessage", "sendMessage", "ensureAIchat", "enableInput", "scrollToBottom", "showCount"]);

// 导出方法供外部使用（已在上方定义）
</script>

<style scoped>
  .disclaimer-text {
    font-size: 24px;
    color: #EEEEEE;
    font-weight: bold;
    text-align: center;
  }
/* 股票统计概览样式 */
.stock-statistics-overview {
  background: rgba(255, 255, 255, 0.95);
  border-radius: 15px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.statistics-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 2px solid #f0f0f0;
}

.statistics-header h3 {
  margin: 0;
  color: #333;
  font-size: 18px;
  font-weight: 600;
}

.stock-count {
  background: linear-gradient(45deg, #667eea, #764ba2);
  color: white;
  padding: 5px 12px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 500;
}

.statistics-content {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 15px;
  margin-bottom: 20px;
}

.stat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  background: rgba(102, 126, 234, 0.1);
  border-radius: 8px;
  border-left: 4px solid #667eea;
}

.stat-label {
  color: #666;
  font-size: 14px;
  font-weight: 500;
}

.stat-value {
  color: #333;
  font-size: 16px;
  font-weight: 600;
}

.stat-value.hot-temp {
  color: #ff4757;
}

.stat-value.cold-temp {
  color: #3742fa;
}

.temperature-distribution {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.distribution-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: rgba(255, 255, 255, 0.8);
  border-radius: 20px;
  border: 1px solid #e0e0e0;
}

.temp-level {
  font-size: 12px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 10px;
  color: white;
}

.temp-level.hot {
  background: #ff4757;
}

.temp-level.warm {
  background: #ff6b35;
}

.temp-level.normal {
  background: #26de81;
}

.temp-level.cool {
  background: #45aaf2;
}

.temp-level.cold {
  background: #3742fa;
}

.temp-count {
  color: #666;
  font-size: 12px;
  font-weight: 500;
}

.matrix-header {
  width: 100%;
  display: flex;
  align-items: center;
}

/* .disclaimer-item p {
  color: #ffffff !important;
  font-size: 24px;
  font-weight: bold;
} */

.temperature-content {
  padding-top: 8%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10rem;
}

.temperature-content .content1 {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.temperature-content .content1 img {
  scale: 0.5;
}

.temperature-display {
  display: flex;
  flex-direction: column;
  /* 竖向排列元素 */
  /* margin-left: 15%; */
  gap: 30px;
  /* margin-top: -12%; */
  /* width: 100%; */
  /* height: auto; */
}

.temperature-display::after {
  content: "";
  display: table;
  clear: both;
}

.temperature-content .temperature-hot {
  background-image: url("@/assets/img/AiEmotion/redBorder.png");
  background-repeat: no-repeat;
  background-size: 100% 100%;
  /* width: 50%; */
  width: 22vw;
  max-width: 400px;
  min-width: 200px;
  text-align: center;
  font-size: 24px;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-shrink: 0;
}

.temperature-content .temperature-cold {
  background-image: url("@/assets/img/AiEmotion/blueBorder.png");
  background-repeat: no-repeat;
  background-size: 100% 100%;
  /* width: 35%; */
  width: 22vw;
  max-width: 400px;
  min-width: 200px;
  text-align: center;
  font-size: 24px;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-shrink: 0;
}

.golden-wheel {
  width: 100%;
  display: flex;
  justify-content: center;
}

.golden-wheel-img {
  width: 30%;
  max-width: 500px;
  height: auto;
}

/* 定义旋转动画 */
@keyframes rotate {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

/* 应用动画到图片 */
.rotating-image {
  animation: rotate 5s linear;
  /* 5 秒完成一次旋转，线性速度*/
  will-change: transform;
  /* 优化动画性能 */
}

.bk-image {
  background-image: url("@/assets/img/AiEmotion/bk00000.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  width: 50vw;
  height: auto;
  margin: 0 auto;
  margin-top: 20px;
}

.bk-image .conclusion-container {
  padding: 45px;
  border-radius: 15px;
  margin: 20px;
}

.bk-image .conclusion-container .conclusion-item {
  border-radius: 12px;
  transition: all 0.3s ease;
  overflow: hidden;
}

.bk-image .conclusion-container .conclusion-item:last-child {
  margin-bottom: 0;
}

.bk-image .conclusion-container .conclusion-item .conclusion-title {
  color: #ffd700;
  font-size: 22px;
  font-weight: bold;
  margin: 0 0 15px 0;
  text-align: center;
  letter-spacing: 2px;
  margin-top: 22px;
}

.bk-image .conclusion-container .conclusion-item .conclusion-text {
  color: #ffffff;
  font-size: 20px;
  line-height: 1.8;
  margin: 0 0 12px 0;
  text-align: center;
  word-wrap: break-word;
  position: relative;
}

.bk-image .conclusion-container .conclusion-item .conclusion-text:last-child {
  margin-bottom: 0;
}

.bk-image .conclusion-placeholder {
  padding: 30px;
  text-align: center;
  border-radius: 12px;
}

.bk-image .conclusion-placeholder p {
  color: #999999;
  font-size: 16px;
  margin: 0;
  font-style: italic;
}

/* 最后文字的颜色 */
.text-container {
  position: relative;
  color: white;
  text-align: left;
  padding: 45px;
  border-radius: 15px;
}

/* .text-container p {
  margin: 0 auto;
  font-size: 40px;
  margin-left: 0%;
  border-radius: 12px;
  transition: all 0.3s ease;
  overflow: hidden;
  letter-spacing: 2px;
} */

.text-container .title {
  display: block;
  color: #ffd700;
  font-weight: bold;
  margin-top: 0px;
  margin-bottom: 20px;
  font-size: 22px;
  text-align: center;
}

.text-container .content {
  display: block;
  color: white;
  text-align: center;
  font-size: 22px;
}

.core-logic-section {
  background-image: url("@/assets/img/AiEmotion/bk00000.png");
  background-size: cover;
  background-repeat: no-repeat;
  width: 95%;
  height: auto;
  min-height: 70rem;
  margin: 0 auto;
}

.core-logic-header {
  margin: 0 auto;
  width: fit-content;
  margin-top: 2%;
  margin-bottom: 1%;
}

.core-highlights-header {
  margin: 0 auto;
  /* width: fit-content; */
  margin-top: 2%;
  margin-bottom: 1%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.emotion-decoder-content {
  /* width: 80vw; */
  margin: 0 auto;
}

.energy-converter-content {
  min-width: 100%;
  margin-top: 3%;
}

.bottom-radar-header {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.bottom-radar-header img {
  scale: 0.5;
}

.energy-converter-header {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.energy-converter-header img {
  scale: 0.5;
}

.bottom-radar-icon {
  width: fit-content;
  height: auto;
  margin: 0 auto;
  margin-top: 2%;
  margin-bottom: 1%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.energy-converter-icon {
  width: fit-content;
  height: auto;
  margin: 0 auto;
  margin-top: 2%;
  margin-bottom: 1%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.core-logic-content {
  margin: 0 auto;
  width: fit-content;
}

.market-temperature-icon {
  width: fit-content;
  height: auto;
  margin: 0 auto;
  margin-top: 2%;
  margin-bottom: 1%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.bottom-radar-title {
  margin: 0 auto;
  width: fit-content;
  margin-top: 2%;
  margin-bottom: 1%;
}

.emotion-decoder-title {
  margin: 0 auto;
  width: fit-content;
  margin-top: 2%;
  margin-bottom: 1%;
}

.temperature-title {
  margin: 0 auto;
  width: fit-content;
  margin-top: 2%;
  margin-bottom: 1%;
}

.matrix-title {
  margin: 0 auto;
  width: fit-content;
  margin-bottom: 1%;
}

.emotion-decoder-header {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.emotion-decoder-header img {
  scale: 0.5;
}

.emotion-decoder-icon {
  width: fit-content;
  height: auto;
  margin: 0 auto;
  margin-top: 2%;
  margin-bottom: 1%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.emotion-decoder-text {
  color: white;
  font-size: 20px;
  font-weight: bold;
  /* margin-left: 45%; */
}

.bottom-radar-text {
  color: white;
  font-size: 20px;
  font-weight: bold;
  /* margin-left: 44.6%; */
}

.energy-converter-text {
  color: white;
  font-size: 20px;
  font-weight: bold;
  /* margin-left: 44%; */
}

.scenario-application-section {
  text-align: center;
  margin-top: 2%;
  margin-bottom: 1%;
}

/* 为需要放大的图片添加样式 */
.scaled-img {
  background-image: url("@/assets/img/AiEmotion/tree00000.jpg");
  background-size: 100% 100%;
  background-position: center;
  background-repeat: no-repeat;
  width: 80%;
  height: 350px;
  margin: 0 auto;
  margin-top: 2%;
  margin-bottom: 3%;
}

.lz-img {
  text-align: center;
  padding-top: 30px;
}

.decision-tree-section {
  background-image: url("@/assets/img/AiEmotion/bk00000.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  width: 50vw;
  height: auto;
  min-height: 30rem;
  margin: 0 auto;
}

.energy-converter-section {
  background-image: url("@/assets/img/AiEmotion/bk00000.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  width: 50vw;
  height: auto;
  margin: 0 auto;
  box-sizing: border-box;
  transition: all 0.3s ease;
  min-height: 85vh;
}

.bottom-radar-section {
  background-image: url("@/assets/img/AiEmotion/bk00000.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  width: 50vw;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
  box-sizing: border-box;
  transition: all 0.3s ease;
}

.emotion-decoder-section {
  background-image: url("@/assets/img/AiEmotion/bk00000.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  width: 50vw;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
  box-sizing: border-box;
  transition: all 0.3s ease;
  padding-bottom: 1rem;
}

.market-temperature-section {
  background-image: url("@/assets/img/AiEmotion/bk00000.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  width: 50vw;
  max-width: 100%;
  height: auto;
  min-height: 70rem;
  margin: 0 auto;
  box-sizing: border-box;
  transition: all 0.3s ease;
}

.main-content-wrapper {
  background-size: 100% 100%;
  background-repeat: no-repeat;
  width: 77vw;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
  box-sizing: border-box;
  transition: all 0.3s ease;
}

.matrix-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 竖向排列元素 */
  /* gap: 1rem; */
  /* margin-left: 10%; */
}

.matrix-main-title {
  color: white;
  font-size: 20px;
  font-weight: bold;
  margin-left: 0%;
}

.market-temperature-value {
  font-size: 1.5rem;
  font-weight: bold;
  color: white;
  margin-left: auto;
}

.market-temperature-label {
  background-image: url("@/assets/img/AiEmotion/bk01.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  padding: 10px;
  color: #fff;
  font-size: 20px;
  font-weight: bold;
  text-align: center;
  margin-left: 0;
  width: 30%;
  min-width: 200px;
  max-width: 50%;
  height: auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  box-sizing: border-box;
}

.main {
  width: 83%;
  max-width: 1400px;
  min-width: 320px;
  min-height: 100px;
  height: auto;
  padding: 1rem;
  box-sizing: border-box;
  background-color: #2b378d;
  margin: 0 auto;
  transition: width 0.3s ease;
  margin-bottom: 10rem;
}

.ai-emotion-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  position: relative;
}

.user-input-display {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  width: 100%;
}

.message-container {
  display: flex;
  margin-bottom: 30px;
  width: 100%;
}

/* 用户消息容器样式 */
.user-message-container {
  align-items: center;
  margin-left: auto;
  gap: 10px;
  margin-right: 5px;
}

.user-content {
  display: flex;
  height: 100%;
  align-items: center;
  margin-right: 5px;
}

/* 确保历史记录模式下用户消息也能正确换行 */
.user-content .user-message {
  white-space: pre-wrap;
  word-wrap: break-word;
  word-break: break-word;
  overflow-wrap: break-word;
}

.user-message-speaker {
  width: 32px;
  height: 32px;
  object-fit: contain;
  margin-right: 5px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.user-sendTime {
  width: 100%;
  text-align: center;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.8rem;
}

.user-message-speaker:hover {
  transform: scale(1.1);
}

.user-message-speaker.speaker-active {
  animation: pulse 1.5s infinite;
}

@keyframes pulse {
  0% {
    transform: scale(1);
  }

  50% {
    transform: scale(1.1);
  }

  100% {
    transform: scale(1);
  }
}

.user-message {
  color: #6d22f8;
  background: white;
  font-weight: bold;
  padding: 15px 20px;
  border-radius: 15px;
  max-width: 80%;
  text-align: left;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  margin: 0;
  word-wrap: break-word;
  word-break: break-word;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  /* 将用户消息推到右边 */
}

/* AI消息容器样式 */
.ai-message-container {
  background-color: #f1f1f1;
  border-radius: 10px;
  align-items: flex-start;
  margin-right: auto;
  width: 100%;
  white-space: normal;
  overflow: visible;
  align-items: center;
  display: flex;
}

/* 思考过程动图样式 */
.thinking-gif {
  width: 40px;
  height: 40px;
  object-fit: contain;
  margin-top: 5px;
  margin-left: 10px;
  border-radius: 8px;
  animation: float 2s ease-in-out infinite;
}

@keyframes float {
  0%,
  100% {
    transform: translateY(0px);
  }

  50% {
    transform: translateY(-5px);
  }
}

/* 动态加载点样式 */
.loading-dots {
  display: inline-block;
}

.dot {
  opacity: 0.4;
  animation: loading 1.4s infinite;
}

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

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

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

.dot:nth-child(4) {
  animation-delay: 0.6s;
}

.dot:nth-child(5) {
  animation-delay: 0.8s;
}

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

@keyframes loading {
  0%,
  60%,
  100% {
    opacity: 0.4;
  }

  30% {
    opacity: 1;
  }
}

.ai-message {
  color: #000000;
  font-weight: bold;
  padding: 10px 10px;
  border-radius: 15px;
  text-align: left;
  margin-right: auto;
  width: 100%;
  overflow: visible;
  align-items: center;
  display: flex;
  margin: 20px 10px;
}

.input-container {
  display: flex;
  align-items: center;
  gap: 10px;
}

.fixed-bottom {
  position: fixed;
  bottom: 100px;
  left: 0;
  width: 100%;
  background-color: #f8f9fa;
  padding: 10px 20px;
  box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
}

.input-box {
  padding: 10px;
  font-size: 16px;
  border: 1px solid #ccc;
  border-radius: 5px;
  width: calc(100% - 120px);
}

.send-button {
  padding: 10px 20px;
  font-size: 16px;
  color: #fff;
  background-color: #007bff;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

.send-button:hover {
  background-color: #0056b3;
}

/* 响应式布局媒体查询 */
@media only screen and (max-width: 1200px) {
  .main {
    width: 95%;
    padding: 0.8rem;
  }

  .market-temperature-label {
    width: 40%;
    min-width: 170px;
    max-width: 60%;
    font-size: 1.3rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .market-temperature-value {
    font-size: 1.3rem;
  }

  /* 调整图表容器高度 */
  /* .class00 {
    min-height: 45rem;
  } */

  .market-temperature-section {
    min-height: 60rem;
  }

  .decision-tree-section {
    min-height: 42rem;
  }

  .scaled-img {
    height: 350px;
    min-height: 30rem;
  }
}

@media only screen and (max-width: 992px) {
  .main {
    width: 98%;
    padding: 0.6rem;
  }

  /* 调整图表容器高度 */
  /* .class00 {
    min-height: 40rem;
  } */

  .market-temperature-section {
    min-height: 55rem;
  }

  .decision-tree-section {
    min-height: 35rem;
  }

  .scaled-img {
    height: 300px;
    min-height: 25rem;
    background-size: contain;
  }
}

/* 手机端适配样式 */
@media only screen and (max-width: 768px) {
  .disclaimer-text {
    font-size: 18px;
    color: #EEEEEE;
    font-weight: bold;
    text-align: center;
  }


  .text-container .content {
    display: block;
    color: white;
    text-align: center;
    font-size: 20px;
  }

  .market-temperature-icon {
    width: auto;
    height: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    scale: 0.5;
  }

  .matrix-header {
    display: flex;
    align-items: center;
  }

  .main {
    width: 90%;
    padding: 0.5rem;
    margin-bottom: 5rem;
    background-color: #2b378d;
    border-radius: 0px 0px 10px 10px;
  }

  .energy-converter-text {
    color: white;
    font-size: 20px;
    font-weight: bold;
    margin-left: 28%;
  }

  .energy-converter-content {
    min-width: 100%;
    /* margin-top: 25%; */
  }

  .scaled-img {
    background-image: url("@/assets/img/AiEmotion/tree00000.jpg");
    background-size: 100% 100%;
    background-position: center;
    background-repeat: no-repeat;
    background-size: contain;
    text-align: center;
    width: 90%;
    margin-top: 4%;
    height: 200px;
    min-height: 200px;
  }

  .bottom-radar-text {
    color: white;
    font-size: 20px;
    font-weight: bold;
    margin-left: 30%;
  }

  .emotion-decoder-text {
    color: white;
    font-size: 20px;
    font-weight: bold;
    margin-left: 30%;
  }

  /* 图片样式 */
  .golden-wheel-img {
    width: 50%;
  }

  .matrix-title img {
    width: 100%;
  }

  .temperature-title img {
    width: 100%;
    margin: 10px 10px;
  }

  .emotion-decoder-title img {
    width: 100%;
    margin: 10px 10px;
  }

  .bottom-radar-title img {
    width: 100%;
    margin: 10px 10px;
  }

  .core-highlights-header img {
    scale: 0.5;
  }

  .core-logic-header img {
    width: 100%;
    margin: 10px 10px;
  }

  .scaled-img img {
    width: 30%;
    height: auto;
  }

  .scenario-application-section img {
    width: 100%;
    margin: 10px 10px;
  }

  .matrix-main-title {
    font-size: 20px;
    margin-left: 5%;
  }

  /* .span01 {
    width: 50%;
    min-width: 150px;
    max-width: 70%;
    font-size: 16px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 8px;
  } */

  .matrix-header .market-temperature-value {
    font-size: 14px;
    color: white;
    float: right;
  }

  .market-temperature-section {
    background-image: url("@/assets/img/AiEmotion/bk00000.png");
    background-size: 100% 100%;
    background-repeat: no-repeat;
    width: 100%;
    /* margin-left: -45px; */
    height: auto;
  }

  /* .main {
    min-height: 100px;
    height: auto;
    box-sizing: border-box;
    background-color: #02107d;
    margin-bottom: 10rem;
  } */

  .emotion-decoder-section {
    width: 80vw;
    height: auto;
    margin: 0 auto;
    /* min-height: 38rem; */
    /* min-height: 51rem; */
    /* margin-left: -39px; */
    /* min-height: 38rem; */
  }

  /* 调整其他图表容器高度 */
  /* .class00 {
    min-height: 35rem;
  } */

  .market-temperature-section {
    min-height: 45rem;
  }

  .matrix-header img {
    width: 68%;
    height: auto;
    /* margin-top: 5%; */
    margin-left: 0%;
  }

  .emotion-decoder-icon {
    width: 25%;
    height: auto;
    scale: 0.5;
  }

  .bottom-radar-icon,
  .energy-converter-icon {
    width: 25%;
    height: auto;
    scale: 0.5;
  }

  .lz-img {
    margin-bottom: 0;
    padding-top: 0;

    img {
      width: 30%;
      height: auto;
      margin-top: 5%;
    }
  }

  .decision-tree-section {
    background-size: 100% 100%;
    background-repeat: no-repeat;
    width: 80vw;
    height: auto;
    min-height: 20rem;
    margin: 0 auto;
  }

  .bk-image {
    .conclusion-container {
      padding: 15px;
      border-radius: 8px;
      margin: 8px;

      .conclusion-item {
        &:last-child {
          margin-bottom: 40px;
        }

        .conclusion-title {
          color: #ffd700;
          font-size: 16px;
          font-weight: bold;
          margin: 0 0 8px 0;
          text-align: center;
        }

        .conclusion-text {
          color: #ffffff;
          font-size: 14px;
          line-height: 1.5;
          margin: 0 0 6px 0;
          text-align: left;
          word-wrap: break-word;

          &:last-child {
            margin-bottom: 0;
          }
        }
      }
    }

    .conclusion-placeholder {
      padding: 15px;
      text-align: center;

      p {
        color: #999999;
        font-size: 12px;
        margin: 0;
      }
    }
  }

  .bk-image {
    background-size: 100% 100%;
    background-repeat: no-repeat;
    width: 80vw;
    height: auto;
    margin: 0 auto;

    .conclusion-container {
      padding-top: 20px;
      border-radius: 15px;
      margin: 20px;

      .conclusion-item {
        border-radius: 12px;
        transition: all 0.3s ease;
        overflow: hidden;
      }

      .conclusion-item:last-child {
        margin-bottom: 40;
      }

      .conclusion-item .conclusion-title {
        color: #ffd700;
        font-size: 22px;
        font-weight: bold;
        text-align: center;
        letter-spacing: 2px;
        margin-top: 22px;
      }

      .conclusion-item .conclusion-text {
        color: #ffffff;
        font-size: 20px;
        line-height: 1.8;
        margin: 0 0 12px 0;
        text-align: center;
        word-wrap: break-word;
        position: relative;
      }

      .conclusion-item .conclusion-text:last-child {
        margin-bottom: 0;
      }
    }

    .conclusion-placeholder {
      padding: 30px;
      text-align: center;
      border-radius: 12px;
      background: rgba(255, 255, 255, 0.05);
      border: 1px dashed rgba(153, 153, 153, 0.3);
    }

    .conclusion-placeholder p {
      color: #999999;
      font-size: 16px;
      margin: 0;
      font-style: italic;
    }

    .disclaimer-item {
      /* margin-top: 30px; */
      padding-bottom: 15%;
      text-align: center;
    }

    .disclaimer-item p {
      color: #ffffff !important;
      font-size: 18px;
      margin: 0;
      letter-spacing: 1px;
    }
  }

  .bottom-radar-section {
    background-size: 100% 100%;
    background-repeat: no-repeat;
    width: 80vw;
    height: auto;
    /* min-height: 48rem; */
  }

  .energy-converter-section {
    background-size: 100% 100%;
    background-repeat: no-repeat;
    width: 80vw;
    height: auto;
    margin: 0 auto;
    min-height: 55vh;
  }

  .temperature-display {
    display: flex;
    flex-direction: column;
    /* margin-left: 5rem; */
    gap: 0;
    /* margin-top: -6rem; */
    /* width: 100%; */
    height: auto;
  }

  .temperature-content .temperature-cold,
  .temperature-content .temperature-hot {
    min-width: 200px;
    font-size: 16px;
  }

  .temperature-content {
    padding-top: 8%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0rem;
  }

  .market-temperature-label {
    background-image: url("@/assets/img/AiEmotion/bk01.png");
    background-size: 100% 100%;
    background-repeat: no-repeat;
    display: inline-block;
    padding: 10px;
    color: #fff;
    font-size: 14px;
    text-align: center;
    width: 50%;
  }

  .temperature-display {
    flex-direction: column;
    gap: 1rem;
    align-items: center;
  }

  /* .span01 {
    width: 60%;
    font-size: 1.2rem;
    padding: 8px;
  } */

  .market-temperature-value {
    font-size: 1.2rem;
  }

  .matrix-main-title,
  .emotion-decoder-text,
  .bottom-radar-text,
  .energy-converter-text {
    font-size: 18px;
    margin-left: 0;
  }
}

/* 超小屏幕设备 */
@media only screen and (max-width: 480px) {
  .main {
    width: 90%;
    padding: 0.3rem;
    margin-bottom: 3rem;
  }

  .temperature-display {
    flex-direction: column;
    gap: 0.8rem;
    align-items: center;
    margin-right: 30px;
  }

  .temperature-content .temperature-cold,
  .temperature-content .temperature-hot {
    /* width: 90%; */
    width: 10vw;
    min-width: 100px;
    font-size: 14px;
  }

  /* .span01 {
    width: 50%;
    font-size: 1rem;
    padding: 6px;
  } */

  .market-temperature-value {
    font-size: 1rem;
  }

  .golden-wheel-img {
    width: 80%;
  }

  /* 调整图表容器高度适配超小屏幕 */
  /* .class00 {
    min-height: 25rem;
  } */

  .market-temperature-section {
    min-height: 35rem;
  }

  .decision-tree-section {
    min-height: 15rem;
  }

  .scaled-img {
    height: 150px;
    min-height: 150px;
  }
}

/* 加载提示样式 */
/* .loading-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 20vh;
  padding: 20px 10px;
} */

/* .loading-content {
  text-align: center;
  background: linear-gradient(135deg, rgba(0, 212, 255, 0.15) 0%, rgba(0, 100, 200, 0.15) 100%);
  border: 2px solid rgba(0, 212, 255, 0.4);
  border-radius: 20px;
  padding: 40px;
  box-shadow: 0 8px 25px rgba(0, 212, 255, 0.3);
} */

/* .loading-spinner {
  width: 60px;
  height: 60px;
  border: 4px solid rgba(0, 212, 255, 0.3);
  border-top: 4px solid #00d4ff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 20px;
} */

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

/* .loading-text {
  color: #00d4ff;
  font-size: 18px;
  font-weight: bold;
  text-shadow: 0 2px 8px rgba(0, 212, 255, 0.5);
  letter-spacing: 1px;
} */

/* 对话区域样式 */
.conversation-area {
  width: 100%;
  padding: 0 20px;
}

.message-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.message-item {
  width: 100%;
  display: flex;
}

.user-message-item {
  justify-content: flex-end;
}

.ai-message-item {
  justify-content: flex-start;
}

.user-message-wrapper {
  display: flex;
  justify-content: flex-end;
  max-width: 70%;
}

.ai-message-wrapper {
  display: flex;
  justify-content: flex-start;
}

/* 顶部锚点样式 */
.top-anchor {
  position: relative;
  top: 0;
  left: 0;
  width: 100%;
  height: 1px;
  display: block;
  visibility: visible;
  opacity: 0;
  pointer-events: none;
}

/* 返回顶部按钮样式 */
.back-to-top {
  position: sticky !important;
  bottom: 20px !important;
  left: calc(100% - 70px) !important;
  width: 50px !important;
  height: 50px !important;
  background: linear-gradient(135deg, #00d4ff 0%, #0066cc 100%) !important;
  border-radius: 50% !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  cursor: pointer !important;
  transition: all 0.3s ease !important;
  z-index: 100 !important;
  color: white !important;
  opacity: 1 !important;
  visibility: visible !important;
  margin-top: 20px !important;
  margin-bottom: 20px !important;
}

.back-to-top:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(0, 212, 255, 0.5);
  background: linear-gradient(135deg, #00e6ff 0%, #0077dd 100%);
}

.back-to-top:active {
  transform: translateY(-1px);
}

/* 页面主容器样式 */
.page-container {
  position: relative;
  width: 100%;
}

.master:last-child {
  border-bottom: none;
  margin-bottom: 0;
}

/* class01容器样式 */
.main {
  position: relative;
}

/* 移动端适配 */
@media only screen and (max-width: 768px) {
  .back-to-top {
    left: calc(100% - 65px) !important;
    width: 45px !important;
    height: 45px !important;
  }
}

@media only screen and (max-width: 480px) {
  .back-to-top {
    left: calc(100% - 60px) !important;
    width: 40px !important;
    height: 40px !important;
  }

  .back-to-top svg {
    width: 20px;
    height: 20px;
  }
}
</style>