import React, { useState, useEffect, useRef } from 'react';
import { ChatMessage, MessageSender, MessagePurpose } from './types';
import { generateResponse } from './services/openaiService';
import ChatInput from './components/ChatInput';
import MessageBubble from './components/MessageBubble';
import Notepad from './components/Notepad';
import ModelConfigManager from './components/ModelConfigManager';
import {
  AiModel,
  AiRole,
  ApiChannel,
  ModelConfigManager as ConfigManager,
  DEFAULT_MANUAL_FIXED_TURNS,
  MIN_MANUAL_FIXED_TURNS,
  MAX_MANUAL_FIXED_TURNS,
  MAX_AI_DRIVEN_DISCUSSION_TURNS_PER_MODEL,
  INITIAL_NOTEPAD_CONTENT,
  NOTEPAD_INSTRUCTION_PROMPT_PART,
  NOTEPAD_UPDATE_TAG_START,
  NOTEPAD_UPDATE_TAG_END,
  DISCUSSION_COMPLETE_TAG,
  AI_DRIVEN_DISCUSSION_INSTRUCTION_PROMPT_PART,
  DiscussionMode
} from './constants';
import { 
  BotMessageSquare, 
  AlertTriangle, 
  RefreshCcw, 
  SlidersHorizontal, 
  Users, 
  MessagesSquare, 
  Bot, 
  ChevronDown,
  Settings,
  Play,
  Pause,
  Square,
  Download
} from 'lucide-react';

interface ParsedAIResponse {
  spokenText: string;
  newNotepadContent: string | null;
  discussionShouldEnd?: boolean;
}

interface ActiveRole extends AiRole {
  model: AiModel;
  channel: ApiChannel;
  isProcessing?: boolean;
}

interface DiscussionState {
  currentRoleIndex: number;
  currentTurn: number;
  discussionLog: string[];
  isFirstMessage: boolean;
  previousAISignaledStop: boolean;
  discussionEndCount: number;
  userQuery: string;
  imageApiPart?: any;
  commonPromptInstructions: string;
  roleOrder: ActiveRole[];
  maxTurnsForLoop: number;
}

const parseAIResponse = (responseText: string): ParsedAIResponse => {
  let currentText = responseText.trim();
  let spokenText = "";
  let newNotepadContent: string | null = null;
  let discussionShouldEnd = false;
  
  let notepadActionText = "";
  let discussionActionText = "";

  const notepadStartIndex = currentText.lastIndexOf(NOTEPAD_UPDATE_TAG_START);
  const notepadEndIndex = currentText.lastIndexOf(NOTEPAD_UPDATE_TAG_END);

  if (notepadStartIndex !== -1 && notepadEndIndex !== -1 && notepadEndIndex > notepadStartIndex && currentText.endsWith(NOTEPAD_UPDATE_TAG_END)) {
    newNotepadContent = currentText.substring(notepadStartIndex + NOTEPAD_UPDATE_TAG_START.length, notepadEndIndex).trim();
    spokenText = currentText.substring(0, notepadStartIndex).trim(); 
    
    if (newNotepadContent) {
        notepadActionText = "更新了记事本";
    } else {
        notepadActionText = "尝试更新记事本但内容为空";
    }
  } else {
    spokenText = currentText;
  }

  if (spokenText.includes(DISCUSSION_COMPLETE_TAG)) {
    discussionShouldEnd = true;
    spokenText = spokenText.replace(new RegExp(DISCUSSION_COMPLETE_TAG.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), "").trim();
    discussionActionText = "建议结束讨论";
  }

  if (!spokenText.trim()) {
    if (notepadActionText && discussionActionText) {
      spokenText = `(AI ${notepadActionText}并${discussionActionText})`;
    } else if (notepadActionText) {
      spokenText = `(AI ${notepadActionText})`;
    } else if (discussionActionText) {
      spokenText = `(AI ${discussionActionText})`;
    } else {
      spokenText = "(AI 未提供额外文本回复)"; 
    }
  }
  
  return { spokenText: spokenText.trim(), newNotepadContent, discussionShouldEnd };
};

const fileToBase64 = (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => {
      const result = reader.result as string;
      resolve(result.split(',')[1]);
    };
    reader.onerror = (error) => reject(error);
  });
};

const createDynamicMessageSender = (roleName: string): MessageSender => {
  return roleName as MessageSender;
};

const App: React.FC = () => {
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [currentTotalProcessingTimeMs, setCurrentTotalProcessingTimeMs] = useState<number>(0);

  const [notepadContent, setNotepadContent] = useState<string>(INITIAL_NOTEPAD_CONTENT);
  const [lastNotepadUpdateBy, setLastNotepadUpdateBy] = useState<MessageSender | null>(null);

  const [discussionMode, setDiscussionMode] = useState<DiscussionMode>(DiscussionMode.FixedTurns);
  const [manualFixedTurns, setManualFixedTurns] = useState<number>(DEFAULT_MANUAL_FIXED_TURNS);
  const [isReducedCapacityEnabled, setIsReducedCapacityEnabled] = useState<boolean>(false);

  const [activeRoles, setActiveRoles] = useState<ActiveRole[]>([]);
  const [channels, setChannels] = useState<ApiChannel[]>([]);
  const [models, setModels] = useState<AiModel[]>([]);
  const [isConfigManagerOpen, setIsConfigManagerOpen] = useState<boolean>(false);
  const [isRoleSelectorOpen, setIsRoleSelectorOpen] = useState<boolean>(false);

  const [isDiscussionActive, setIsDiscussionActive] = useState<boolean>(false);
  const [streamingMessages, setStreamingMessages] = useState<Map<string, { text: string; isComplete: boolean }>>(new Map());
  const [currentDiscussion, setCurrentDiscussion] = useState<DiscussionState | null>(null);

  const chatContainerRef = useRef<HTMLDivElement>(null);
  const currentQueryStartTimeRef = useRef<number | null>(null);
  const cancelRequestRef = useRef<boolean>(false);

  // 实时流式消息管理
  const createStreamingMessage = (sender: MessageSender, purpose: MessagePurpose): string => {
    const messageId = Date.now().toString() + Math.random().toString(36).substr(2, 9);
    const message: ChatMessage = {
      id: messageId,
      text: '',
      sender,
      purpose,
      timestamp: new Date()
    };
    
    setMessages(prev => [...prev, message]);
    setStreamingMessages(prev => new Map(prev.set(messageId, { text: '', isComplete: false })));
    return messageId;
  };

  const updateStreamingMessage = (messageId: string, fullText: string, isComplete: boolean, durationMs?: number) => {
    setMessages(prev => prev.map(msg => 
      msg.id === messageId ? { 
        ...msg, 
        text: fullText,
        durationMs: isComplete ? durationMs : msg.durationMs
      } : msg
    ));
  };

  const loadConfiguration = () => {
    const allChannels = ConfigManager.getChannels();
    const allModels = ConfigManager.getModels();
    const allRoles = ConfigManager.getActiveRoles();
    
    setChannels(allChannels);
    setModels(allModels);
    
    const rolesWithModelsAndChannels: ActiveRole[] = allRoles.map(role => {
      const model = allModels.find(m => m.id === role.modelId);
      if (!model) {
        console.warn(`Role ${role.name} references non-existent model ${role.modelId}`);
        return null;
      }
      
      const channel = allChannels.find(ch => ch.id === model.channelId);
      if (!channel) {
        console.warn(`Model ${model.name} references non-existent channel ${model.channelId}`);
        return null;
      }
      
      return { ...role, model, channel };
    }).filter(Boolean) as ActiveRole[];
    
    setActiveRoles(rolesWithModelsAndChannels);
  };

  useEffect(() => {
    loadConfiguration();
  }, []);

  const addMessage = (
    text: string,
    sender: MessageSender,
    purpose: MessagePurpose,
    durationMs?: number,
    image?: ChatMessage['image']
  ) => {
    const messageId = Date.now().toString() + Math.random().toString(36).substr(2, 9);
    const message: ChatMessage = {
      id: messageId,
      text,
      sender,
      purpose,
      timestamp: new Date(),
      durationMs,
      image
    };

    setMessages(prev => [...prev, message]);
    return messageId;
  };

  const interruptDiscussion = () => {
    if (isLoading && isDiscussionActive) {
      cancelRequestRef.current = true;
      setIsLoading(false);
      setIsDiscussionActive(false);
      setCurrentDiscussion(null);
      
      if (currentTotalProcessingTimeMs > 0) {
        addMessage(
          `讨论已被用户中断 (已进行 ${(currentTotalProcessingTimeMs / 1000).toFixed(2)}秒)`,
          MessageSender.System,
          MessagePurpose.SystemNotification
        );
      }
      
      setCurrentTotalProcessingTimeMs(0);
      if (currentQueryStartTimeRef.current) {
        currentQueryStartTimeRef.current = null;
      }
    }
  };

  const exportDiscussionRecord = () => {
    if (messages.length === 0) {
      addMessage('当前没有可导出的消息记录', MessageSender.System, MessagePurpose.SystemNotification);
      return;
    }

    // 生成简洁的文本格式导出
    let exportText = `=== Multi-Mind Chat 对话记录 ===\n`;
    exportText += `导出时间: ${new Date().toLocaleString()}\n`;
    exportText += `消息总数: ${messages.length}\n\n`;

    messages.forEach(msg => {
      if (msg.purpose !== MessagePurpose.SystemNotification) {
        const timeStr = msg.timestamp.toLocaleTimeString();
        const durationStr = msg.durationMs ? ` (${(msg.durationMs / 1000).toFixed(2)}s)` : '';
        exportText += `[${timeStr}] ${msg.sender}${durationStr}: ${msg.text}\n\n`;
        
        if (msg.image) {
          exportText += `    [附件: ${msg.image.name} - ${msg.image.type}]\n\n`;
        }
      }
    });

    if (notepadContent !== INITIAL_NOTEPAD_CONTENT) {
      exportText += `=== 最终记事本内容 ===\n`;
      exportText += `${notepadContent}\n\n`;
    }

    const blob = new Blob([exportText], { type: 'text/plain;charset=utf-8' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `对话记录-${new Date().toISOString().split('T')[0]}-${Date.now()}.txt`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);

    addMessage('对话记录已导出', MessageSender.System, MessagePurpose.SystemNotification);
  };

  const getWelcomeMessageText = () => {
    const modeDescription = discussionMode === DiscussionMode.FixedTurns 
      ? `固定轮次对话 (${manualFixedTurns}轮)` 
      : "AI驱动对话";
    
    const roleNames = activeRoles.map(role => role.name).join(' 和 ');
    const roleCount = activeRoles.length;
    const channelCount = channels.length;
    
    if (channelCount === 0) {
      return `欢迎使用Multi-Mind Chat 智囊团！请先配置API渠道。点击设置按钮开始配置。`;
    } else if (roleCount === 0) {
      return `欢迎使用Multi-Mind Chat 智囊团！已配置 ${channelCount} 个API渠道，请继续配置AI角色和模型。点击设置按钮开始配置。`;
    } else if (roleCount === 1) {
      return `欢迎使用Multi-Mind Chat 智囊团！当前模式: ${modeDescription}。当前只有一个活跃角色: ${roleNames}。建议添加更多角色以获得更好的协作体验。`;
    } else {
      return `欢迎使用Multi-Mind Chat 智囊团！当前模式: ${modeDescription}。活跃的AI角色: ${roleNames}。这些角色将协作讨论您的问题并使用共享记事本。`;
    }
  };
  
  const initializeChat = () => {
    setMessages([]);
    setNotepadContent(INITIAL_NOTEPAD_CONTENT);
    setLastNotepadUpdateBy(null);
    setIsDiscussionActive(false);
    setStreamingMessages(new Map());
    setCurrentDiscussion(null);

    addMessage(
      getWelcomeMessageText(),
      MessageSender.System,
      MessagePurpose.SystemNotification
    );
  };

  useEffect(() => {
    initializeChat();
  }, [activeRoles, discussionMode, manualFixedTurns, channels]);

  useEffect(() => {
    if (chatContainerRef.current) {
      chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
    }
  }, [messages]);

  useEffect(() => {
    let intervalId: number | undefined;
    if (isLoading && currentQueryStartTimeRef.current) {
      intervalId = window.setInterval(() => {
        if (currentQueryStartTimeRef.current) {
          setCurrentTotalProcessingTimeMs(performance.now() - currentQueryStartTimeRef.current);
        }
      }, 100);
    } else {
      if (intervalId) clearInterval(intervalId);
    }
    return () => {
      if (intervalId) clearInterval(intervalId);
    };
  }, [isLoading]);

  const handleClearChat = () => {
    if (isLoading) {
      cancelRequestRef.current = true;
    }
    setIsLoading(false);
    setIsDiscussionActive(false);
    setCurrentDiscussion(null);
    
    setCurrentTotalProcessingTimeMs(0);
    if (currentQueryStartTimeRef.current) {
        currentQueryStartTimeRef.current = null;
    }

    setMessages([]);
    setNotepadContent(INITIAL_NOTEPAD_CONTENT);
    setLastNotepadUpdateBy(null);
    setStreamingMessages(new Map());

    addMessage(
      getWelcomeMessageText(),
      MessageSender.System,
      MessagePurpose.SystemNotification
    );
  };
  
  const handleManualFixedTurnsChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    let value = parseInt(e.target.value, 10);
    if (isNaN(value)) {
      value = DEFAULT_MANUAL_FIXED_TURNS; 
    }
    value = Math.max(MIN_MANUAL_FIXED_TURNS, Math.min(MAX_MANUAL_FIXED_TURNS, value));
    setManualFixedTurns(value);
  };

  const toggleRoleActiveState = (roleId: string) => {
    const role = activeRoles.find(r => r.id === roleId);
    if (role) {
      ConfigManager.updateRole(roleId, { isActive: !role.isActive });
      loadConfiguration();
    }
  };

  const processNextRole = (state: DiscussionState) => {
    if (cancelRequestRef.current) {
      setIsDiscussionActive(false);
      setCurrentDiscussion(null);
      return;
    }

    // 检查是否完成所有讨论
    if (state.currentTurn === 0 && state.currentRoleIndex >= state.roleOrder.length) {
      // 第一轮结束，开始多轮讨论
      if (!state.previousAISignaledStop && state.maxTurnsForLoop > 0) {
        const newState = { ...state, currentTurn: 1, currentRoleIndex: 0, discussionEndCount: 0 };
        setCurrentDiscussion(newState);
        processNextRole(newState);
        return;
      } else {
        processFinalAnswer(state);
        return;
      }
    } else if (state.currentTurn > 0 && 
      (state.currentTurn >= state.maxTurnsForLoop || 
      state.previousAISignaledStop || 
      state.currentRoleIndex >= state.roleOrder.length)) {
      processFinalAnswer(state);
      return;
    }

    const currentRole = state.roleOrder[state.currentRoleIndex];
    const shouldUseReducedCapacity = isReducedCapacityEnabled && currentRole.model.supportsReducedCapacity;

    // 显示系统通知
    addMessage(
      `${currentRole.name} 正在${state.currentTurn === 0 ? '分析问题并提供观点' : '回应其他角色的观点'} (使用 ${currentRole.model.name} - ${currentRole.channel.name})...`, 
      MessageSender.System, 
      MessagePurpose.SystemNotification
    );

    // 立即创建消息气泡
    const purpose = state.currentRoleIndex % 2 === 0 ? MessagePurpose.CognitoToMuse : MessagePurpose.MuseToCognito;
    const messageId = Date.now().toString() + Math.random().toString(36).substr(2, 9);
    
    // 立即添加空消息到界面，用户会看到正在输入的效果
    const initialMessage: ChatMessage = {
      id: messageId,
      text: '', // 开始时为空，等待流式输入
      sender: createDynamicMessageSender(currentRole.name),
      purpose,
      timestamp: new Date()
    };
    
    setMessages(prev => [...prev, initialMessage]);

    // 构建提示词
    let prompt: string;
    if (state.isFirstMessage) {
      prompt = `用户的查询 (中文) 是: "${state.userQuery}". ${state.imageApiPart ? "用户还提供了一张图片。请在您的分析和回复中同时考虑此图片和文本查询。" : ""} 请针对此查询提供您的初步想法或分析。这是一个多AI协作的环境，其他AI角色稍后会对您的观点进行回应和讨论。用中文回答。\n${state.commonPromptInstructions}`;
    } else if (state.currentTurn === 0) {
      const otherRoles = state.roleOrder.filter(r => r.id !== currentRole.id).map(r => r.name).join(' 和 ');
      prompt = `用户的查询 (中文) 是: "${state.userQuery}". ${state.imageApiPart ? "用户还提供了一张图片。请在您的分析和回复中同时考虑此图片和文本查询。" : ""} 当前讨论 (均为中文):\n${state.discussionLog.join("\n")}\n您正在与 ${otherRoles} 协作讨论这个问题。请提供您的观点和分析。用中文回答。\n${state.commonPromptInstructions}`;
    } else {
      const otherRoles = state.roleOrder.filter(r => r.id !== currentRole.id).map(r => r.name).join(' 和 ');
      prompt = `用户的查询 (中文) 是: "${state.userQuery}". ${state.imageApiPart ? "用户还提供了一张图片。请在您的分析和回复中同时考虑此图片和文本查询。" : ""} 当前讨论 (均为中文):\n${state.discussionLog.join("\n")}\n您正在与 ${otherRoles} 协作讨论。请对前面的讨论进行回应，提供您的进一步见解或不同观点。保持简洁并使用中文。\n${NOTEPAD_INSTRUCTION_PROMPT_PART.replace('{notepadContent}', notepadContent)}`;
      
      if (discussionMode === DiscussionMode.AiDriven && state.previousAISignaledStop) {
        prompt += `\n注意：之前有AI角色建议结束讨论。如果您同意，请在回复中包含 ${DISCUSSION_COMPLETE_TAG}。否则，请继续讨论。`;
      } else if (discussionMode === DiscussionMode.AiDriven) {
        prompt += AI_DRIVEN_DISCUSSION_INSTRUCTION_PROMPT_PART;
      }
    }

    // 用于后台累积完整响应文本的变量
    let accumulatedText = '';

    // 开始流式API调用
    generateResponse(
      prompt,
      currentRole.model.apiName,
      currentRole.systemPrompt,
      shouldUseReducedCapacity,
      state.imageApiPart,
      currentRole.channel.baseUrl,
      currentRole.channel.apiKey,
      // 关键的流式回调函数
      (newChunk: string, fullText: string, isComplete: boolean) => {
        // newChunk: 本次新接收到的文本块
        // fullText: API累积的完整文本（用于后续处理）
        // isComplete: 是否完成
        
        // 更新后台累积的完整文本
        accumulatedText = fullText;
        
        // 实时更新界面显示 - 关键是这里直接使用 fullText 进行显示
        setMessages(prev => prev.map(msg => 
          msg.id === messageId ? { 
            ...msg, 
            text: fullText, // 直接显示累积的完整文本，实现打字机效果
            durationMs: isComplete ? (performance.now() - (currentQueryStartTimeRef.current || 0)) : undefined
          } : msg
        ));
      },
      currentRole.model.maxTokens  // 传递模型配置的 maxTokens
    ).then(response => {
      if (cancelRequestRef.current) {
        setIsDiscussionActive(false);
        setCurrentDiscussion(null);
        return;
      }

      if (response.error) {
        if (response.error.includes("API key not valid") || response.error.includes("401")) {
          setMessages(prev => prev.map(msg => 
            msg.id === messageId ? { 
              ...msg, 
              text: `API密钥无效 (渠道: ${currentRole.channel.name})，请在配置界面中检查密钥设置。`,
              durationMs: response.durationMs
            } : msg
          ));
          setIsLoading(false);
          setIsDiscussionActive(false);
          setCurrentDiscussion(null);
          return;
        }
        throw new Error(`${currentRole.name}: ${response.text}`);
      }

      // 确保最终消息内容正确
      setMessages(prev => prev.map(msg => 
        msg.id === messageId ? { 
          ...msg, 
          text: response.text,
          durationMs: response.durationMs
        } : msg
      ));

      // 解析响应
      const parsedResponse = parseAIResponse(response.text);
      if (parsedResponse.newNotepadContent !== null) {
        setNotepadContent(parsedResponse.newNotepadContent);
        setLastNotepadUpdateBy(createDynamicMessageSender(currentRole.name));
      }

      // 更新讨论日志 - 使用解析后的文本
      const newDiscussionLog = [...state.discussionLog, `${currentRole.name}: ${parsedResponse.spokenText}`];
      
      // 更新状态
      let newState = {
        ...state,
        discussionLog: newDiscussionLog,
        isFirstMessage: false,
        currentRoleIndex: state.currentRoleIndex + 1
      };

      // 处理AI驱动模式的结束信号
      if (discussionMode === DiscussionMode.AiDriven && parsedResponse.discussionShouldEnd) {
        if (state.currentTurn > 0) {
          newState.discussionEndCount++;
          if (state.previousAISignaledStop || newState.discussionEndCount >= Math.ceil(state.roleOrder.length / 2)) {
            addMessage(`多数AI角色已同意结束讨论。`, MessageSender.System, MessagePurpose.SystemNotification);
            newState.previousAISignaledStop = true;
          } else {
            addMessage(`${currentRole.name} 已建议结束讨论。`, MessageSender.System, MessagePurpose.SystemNotification);
          }
        } else {
          newState.previousAISignaledStop = true;
          addMessage(`${currentRole.name} 已建议结束讨论。`, MessageSender.System, MessagePurpose.SystemNotification);
        }
      }

      setCurrentDiscussion(newState);
      
      // 直接处理下一个角色，不使用setTimeout延迟
      processNextRole(newState);
    }).catch(error => {
      console.error("处理AI响应时出错:", error);
      addMessage(`错误: ${error instanceof Error ? error.message : "处理响应时发生未知错误"}`, MessageSender.System, MessagePurpose.SystemNotification);
      setIsLoading(false);
      setIsDiscussionActive(false);
      setCurrentDiscussion(null);
    });
  };

  const processFinalAnswer = (state: DiscussionState) => {
    const finalAnswerRole = state.roleOrder[0];
    const shouldUseReducedCapacity = isReducedCapacityEnabled && finalAnswerRole.model.supportsReducedCapacity;

    addMessage(
      `${finalAnswerRole.name} 正在综合所有讨论内容，准备最终答案 (使用 ${finalAnswerRole.model.name} - ${finalAnswerRole.channel.name})...`,
      MessageSender.System,
      MessagePurpose.SystemNotification
    );

    // 立即创建最终答案消息气泡
    const finalMessageId = Date.now().toString() + Math.random().toString(36).substr(2, 9);
    const finalMessage: ChatMessage = {
      id: finalMessageId,
      text: '', // 开始时为空
      sender: createDynamicMessageSender(finalAnswerRole.name),
      purpose: MessagePurpose.FinalResponse,
      timestamp: new Date()
    };
    
    setMessages(prev => [...prev, finalMessage]);

    const finalPrompt = `用户最初的查询 (中文) 是: "${state.userQuery}". ${state.imageApiPart ? "用户还提供了一张图片。请在您的分析和回复中同时考虑此图片和文本查询。" : ""} 您和其他AI角色进行了以下讨论 (均为中文):\n${state.discussionLog.join("\n")}\n基于整个协作讨论过程和共享记事本的最终状态，请综合所有关键观点，为用户提供一个全面、有用的最终答案。直接回复用户，确保答案结构良好，易于理解，并使用中文。如果相关，您可以在答案中引用记事本内容。如果需要，您也可以最后一次更新记事本。\n${NOTEPAD_INSTRUCTION_PROMPT_PART.replace('{notepadContent}', notepadContent)}`;

    generateResponse(
      finalPrompt,
      finalAnswerRole.model.apiName,
      finalAnswerRole.systemPrompt,
      shouldUseReducedCapacity,
      state.imageApiPart,
      finalAnswerRole.channel.baseUrl,
      finalAnswerRole.channel.apiKey,
      // 最终答案的流式回调
      (newChunk: string, fullText: string, isComplete: boolean) => {
        setMessages(prev => prev.map(msg => 
          msg.id === finalMessageId ? { 
            ...msg, 
            text: fullText, // 实时显示累积文本
            durationMs: isComplete ? (performance.now() - (currentQueryStartTimeRef.current || 0)) : undefined
          } : msg
        ));
      },
      finalAnswerRole.model.maxTokens  // 传递模型配置的 maxTokens
    ).then(finalResponse => {
      if (cancelRequestRef.current) {
        setIsDiscussionActive(false);
        setCurrentDiscussion(null);
        return;
      }

      if (finalResponse.error) {
        if (finalResponse.error.includes("API key not valid") || finalResponse.error.includes("401")) {
          setMessages(prev => prev.map(msg => 
            msg.id === finalMessageId ? { 
              ...msg, 
              text: `API密钥无效 (渠道: ${finalAnswerRole.channel.name})，请在配置界面中检查密钥设置。`,
              durationMs: finalResponse.durationMs
            } : msg
          ));
          setIsLoading(false);
          setIsDiscussionActive(false);
          setCurrentDiscussion(null);
          return;
        }
        throw new Error(`${finalAnswerRole.name}: ${finalResponse.text}`);
      }

      setMessages(prev => prev.map(msg => 
        msg.id === finalMessageId ? { 
          ...msg, 
          text: finalResponse.text,
          durationMs: finalResponse.durationMs
        } : msg
      ));

      const finalParsedResponse = parseAIResponse(finalResponse.text);
      if (finalParsedResponse.newNotepadContent !== null) {
        setNotepadContent(finalParsedResponse.newNotepadContent);
        setLastNotepadUpdateBy(createDynamicMessageSender(finalAnswerRole.name));
      }

      // 讨论完成
      setIsLoading(false);
      setIsDiscussionActive(false);
      setCurrentDiscussion(null);
      currentQueryStartTimeRef.current = null;
    }).catch(error => {
      console.error("生成最终答案时出错:", error);
      addMessage(`错误: ${error instanceof Error ? error.message : "生成最终答案时发生未知错误"}`, MessageSender.System, MessagePurpose.SystemNotification);
      setIsLoading(false);
      setIsDiscussionActive(false);
      setCurrentDiscussion(null);
    });
  };

  const handleSendMessage = async (userInput: string, imageFile?: File | null) => {
    if (isLoading) return;
    if (!userInput.trim() && !imageFile) return;
    
    if (channels.length === 0) {
      addMessage("请先配置API渠道。点击设置按钮添加渠道。", MessageSender.System, MessagePurpose.SystemNotification);
      return;
    }
    
    if (activeRoles.length === 0) {
      addMessage("请先配置AI角色。点击设置按钮添加角色。", MessageSender.System, MessagePurpose.SystemNotification);
      return;
    }

    const rolesWithoutApiKey = activeRoles.filter(role => !role.channel.apiKey?.trim());
    if (rolesWithoutApiKey.length > 0) {
      const roleNames = rolesWithoutApiKey.map(role => `${role.name}(${role.channel.name})`).join('、');
      addMessage(`以下角色的API渠道缺少API密钥: ${roleNames}。请在配置界面中设置相应的API密钥。`, MessageSender.System, MessagePurpose.SystemNotification);
      return;
    }

    if (imageFile) {
      const supportsImages = activeRoles.some(role => role.model.supportsImages);
      if (!supportsImages) {
        addMessage("当前活跃的角色都不支持图片处理。请添加支持图片的模型和角色，或移除图片。", MessageSender.System, MessagePurpose.SystemNotification);
        return;
      }
    }

    setIsDiscussionActive(true);
    cancelRequestRef.current = false;
    setIsLoading(true);
    currentQueryStartTimeRef.current = performance.now();
    setCurrentTotalProcessingTimeMs(0);

    let userImageForDisplay: ChatMessage['image'] | undefined = undefined;
    if (imageFile) {
      const dataUrl = URL.createObjectURL(imageFile);
      userImageForDisplay = { dataUrl, name: imageFile.name, type: imageFile.type };
    }

    addMessage(userInput, MessageSender.User, MessagePurpose.UserInput, undefined, userImageForDisplay);
    
    let imageApiPart: { inlineData: { mimeType: string; data: string } } | undefined = undefined;
    if (imageFile) {
      try {
        const base64Data = await fileToBase64(imageFile);
        imageApiPart = {
          inlineData: {
            mimeType: imageFile.type,
            data: base64Data,
          },
        };
      } catch (error) {
        console.error("Error converting file to base64:", error);
        addMessage("图片处理失败，请重试。", MessageSender.System, MessagePurpose.SystemNotification);
        setIsLoading(false);
        setIsDiscussionActive(false);
        return;
      }
    }

    const discussionModeInstruction = discussionMode === DiscussionMode.AiDriven ? AI_DRIVEN_DISCUSSION_INSTRUCTION_PROMPT_PART : "";
    const commonPromptInstructions = NOTEPAD_INSTRUCTION_PROMPT_PART.replace('{notepadContent}', notepadContent) + discussionModeInstruction;

    const roleOrder = [...activeRoles];
    const maxTurnsForLoop = discussionMode === DiscussionMode.AiDriven ? MAX_AI_DRIVEN_DISCUSSION_TURNS_PER_MODEL : manualFixedTurns;

    // 初始化讨论状态
    const discussionState: DiscussionState = {
      currentRoleIndex: 0,
      currentTurn: 0,
      discussionLog: [],
      isFirstMessage: true,
      previousAISignaledStop: false,
      discussionEndCount: 0,
      userQuery: userInput,
      imageApiPart,
      commonPromptInstructions,
      roleOrder,
      maxTurnsForLoop
    };

    setCurrentDiscussion(discussionState);
    
    // 开始第一个AI的回复（不等待）
    processNextRole(discussionState);
    
    // 清理图片URL
    if (userImageForDisplay?.dataUrl.startsWith('blob:')) {
      // 延迟清理，确保消息已渲染
      setTimeout(() => {
        URL.revokeObjectURL(userImageForDisplay.dataUrl);
      }, 5000);
    }
  };
  
  const Separator = () => <div className="h-6 w-px bg-gray-600" aria-hidden="true"></div>;

  const hasValidChannels = channels.some(ch => ch.apiKey?.trim());
  const isSystemReady = hasValidChannels && activeRoles.length > 0;

  return (
    <div className="flex flex-col h-screen max-w-7xl mx-auto bg-gray-900 shadow-2xl rounded-lg overflow-hidden">
      <header className="p-4 bg-gray-900 border-b border-gray-700 flex items-center justify-between shrink-0 space-x-2 md:space-x-4 flex-wrap">
        <div className="flex items-center shrink-0">
          <BotMessageSquare size={28} className="mr-2 md:mr-3 text-sky-400" />
          <h1 className="text-xl md:text-2xl font-semibold text-sky-400">Multi-Mind Chat 智囊团</h1>
        </div>
        
        <div className="flex items-center space-x-2 md:space-x-3 flex-wrap justify-end gap-y-2">
          {/* 讨论控制按钮 */}
          {isDiscussionActive && (
            <div className="flex items-center space-x-2">
              <button
                onClick={interruptDiscussion}
                className="px-3 py-1 bg-red-600 hover:bg-red-700 text-white rounded text-sm flex items-center space-x-1"
                title="中断当前讨论"
              >
                <Square size={16} />
                <span>中断讨论</span>
              </button>
              <Separator />
            </div>
          )}
          
          {/* 导出按钮 - 有消息时始终可用 */}
          {messages.length > 1 && (
            <div className="flex items-center space-x-2">
              <button
                onClick={exportDiscussionRecord}
                className="px-3 py-1 bg-green-600 hover:bg-green-700 text-white rounded text-sm flex items-center space-x-1"
                title="导出对话记录"
                disabled={isLoading}
              >
                <Download size={16} />
                <span>导出记录</span>
              </button>
              <Separator />
            </div>
          )}

          {/* 角色管理器 */}
          <div className="relative flex items-center">
            <label className="text-sm text-gray-300 mr-1.5 flex items-center shrink-0">
              <Users size={18} className="mr-1 text-sky-400"/>
              角色:
            </label>
            <button
              onClick={() => setIsRoleSelectorOpen(!isRoleSelectorOpen)}
              className="bg-gray-700 border border-gray-600 text-white text-sm rounded-md p-1.5 focus:ring-2 focus:ring-sky-500 focus:border-sky-500 outline-none flex items-center space-x-2 min-w-[120px]"
              aria-label="管理AI角色"
            >
              <span className="truncate">{activeRoles.length}个活跃</span>
              <ChevronDown size={16} className={`transition-transform ${isRoleSelectorOpen ? 'rotate-180' : ''}`} />
            </button>
            
            {isRoleSelectorOpen && (
              <div className="absolute top-full left-0 mt-1 w-80 bg-gray-800 border border-gray-600 rounded-md shadow-lg z-50 max-h-96 overflow-y-auto">
                <div className="p-3 border-b border-gray-700">
                  <div className="flex justify-between items-center">
                    <h3 className="text-white font-medium">活跃角色</h3>
                    <button
                      onClick={() => {
                        setIsConfigManagerOpen(true);
                        setIsRoleSelectorOpen(false);
                      }}
                      className="text-xs bg-sky-600 hover:bg-sky-700 text-white px-2 py-1 rounded flex items-center space-x-1"
                    >
                      <Settings size={12} />
                      <span>配置</span>
                    </button>
                  </div>
                </div>
                
                {activeRoles.length === 0 ? (
                  <div className="p-4 text-center text-gray-400">
                    <p className="mb-2">暂无活跃角色</p>
                    <button
                      onClick={() => {
                        setIsConfigManagerOpen(true);
                        setIsRoleSelectorOpen(false);
                      }}
                      className="text-sm bg-sky-600 hover:bg-sky-700 text-white px-3 py-1 rounded"
                    >
                      添加角色
                    </button>
                  </div>
                ) : (
                  <div className="max-h-64 overflow-y-auto">
                    {activeRoles.map((role) => (
                      <div key={role.id} className="p-3 border-b border-gray-700 last:border-b-0">
                        <div className="flex justify-between items-start">
                          <div className="flex-1">
                            <div className="flex items-center space-x-2">
                              <h4 className="text-white font-medium">{role.name}</h4>
                              <button
                                onClick={() => toggleRoleActiveState(role.id)}
                                className={`p-1 rounded transition-colors ${
                                  role.isActive ? 'text-green-400 hover:text-green-300' : 'text-gray-500 hover:text-gray-400'
                                }`}
                                title={role.isActive ? '暂停角色' : '激活角色'}
                              >
                                {role.isActive ? <Play size={14} /> : <Pause size={14} />}
                              </button>
                            </div>
                            <p className="text-gray-400 text-xs">{role.model.name}</p>
                            <p className="text-gray-500 text-xs">渠道: {role.channel.name}</p>
                            <div className="flex space-x-1 mt-1">
                              {role.model.supportsImages && (
                                <span className="text-xs bg-green-600 text-white px-1 rounded">图像</span>
                              )}
                              {role.model.supportsReducedCapacity && (
                                <span className="text-xs bg-blue-600 text-white px-1 rounded">优化</span>
                              )}
                              {!role.channel.apiKey?.trim() && (
                                <span className="text-xs bg-red-600 text-white px-1 rounded">缺少密钥</span>
                              )}
                            </div>
                          </div>
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            )}
            
            {isRoleSelectorOpen && (
              <div 
                className="fixed inset-0 z-40" 
                onClick={() => setIsRoleSelectorOpen(false)}
              />
            )}
          </div>
          
          <Separator />

          <div className="flex items-center space-x-1.5">
            <label
              htmlFor="discussionModeToggle"
              className="flex items-center text-sm text-gray-300 cursor-pointer hover:text-sky-400"
              title={discussionMode === DiscussionMode.FixedTurns ? "切换到AI驱动模式" : "切换到固定轮次模式"}
            >
              {discussionMode === DiscussionMode.FixedTurns 
                ? <MessagesSquare size={18} className="mr-1 text-sky-400" /> 
                : <Bot size={18} className="mr-1 text-sky-400" />}
              <span className="mr-1 select-none shrink-0">模式:</span>
              <div className="relative">
                <input
                  type="checkbox"
                  id="discussionModeToggle"
                  className="sr-only peer"
                  checked={discussionMode === DiscussionMode.AiDriven}
                  onChange={() => setDiscussionMode(prev => prev === DiscussionMode.FixedTurns ? DiscussionMode.AiDriven : DiscussionMode.FixedTurns)}
                  aria-label="切换对话模式"
                  disabled={isLoading}
                />
                <div className={`block w-10 h-6 rounded-full transition-colors ${discussionMode === DiscussionMode.AiDriven ? 'bg-sky-500' : 'bg-gray-600'}`}></div>
                <div className={`absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform ${discussionMode === DiscussionMode.AiDriven ? 'translate-x-4' : ''}`}></div>
              </div>
              <span className="ml-1.5 select-none shrink-0 min-w-[4rem] text-left">
                {discussionMode === DiscussionMode.FixedTurns ? '固定' : 'AI驱动'}
              </span>
            </label>
            {discussionMode === DiscussionMode.FixedTurns && (
              <div className="flex items-center text-sm text-gray-300">
                <input
                  type="number"
                  id="manualFixedTurnsInput"
                  value={manualFixedTurns}
                  onChange={handleManualFixedTurnsChange}
                  min={MIN_MANUAL_FIXED_TURNS}
                  max={MAX_MANUAL_FIXED_TURNS}
                  className="w-14 bg-gray-700 border border-gray-600 text-white text-sm rounded-md p-1 text-center focus:ring-1 focus:ring-sky-500 focus:border-sky-500 outline-none"
                  aria-label="设置固定轮次数量"
                  disabled={isLoading}
                />
                <span className="ml-1 select-none">轮</span>
              </div>
            )}
          </div>

          <Separator />

          <label
            htmlFor="capacityToggle"
            className="flex items-center text-sm text-gray-300 cursor-pointer hover:text-sky-400"
            title={isReducedCapacityEnabled ? "切换为优质模式 (完整性能)" : "切换为快速模式 (降低性能)"}
          >
            <SlidersHorizontal size={18} className={`mr-1.5 ${!isReducedCapacityEnabled ? 'text-sky-400' : 'text-gray-500'}`} />
            <span className="mr-2 select-none shrink-0">性能:</span>
            <div className="relative">
              <input
                type="checkbox"
                id="capacityToggle"
                className="sr-only peer"
                checked={!isReducedCapacityEnabled}
                onChange={() => setIsReducedCapacityEnabled(!isReducedCapacityEnabled)}
                aria-label="切换AI性能模式"
                disabled={isLoading}
              />
              <div className={`block w-10 h-6 rounded-full transition-colors ${!isReducedCapacityEnabled ? 'bg-sky-500 peer-checked:bg-sky-500' : 'bg-gray-600'}`}></div>
              <div className={`absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform ${!isReducedCapacityEnabled ? 'peer-checked:translate-x-4' : ''}`}></div>
            </div>
            <span className="ml-2 w-20 text-left select-none shrink-0">
              {!isReducedCapacityEnabled ? '优质' : '快速'}
            </span>
          </label>

          <Separator />

          <button
            onClick={() => setIsConfigManagerOpen(true)}
            className="p-2 text-gray-400 hover:text-sky-400 transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-sky-500 focus:ring-offset-2 focus:ring-offset-gray-900 rounded-md shrink-0"
            aria-label="配置管理"
            title="配置管理"
          >
            <Settings size={22} />
          </button>

          <button
            onClick={handleClearChat}
            className="p-2 text-gray-400 hover:text-sky-400 transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-sky-500 focus:ring-offset-2 focus:ring-offset-gray-900 rounded-md shrink-0"
            aria-label="清空会话"
            title="清空会话"
            disabled={isLoading}
          >
            <RefreshCcw size={22} />
          </button>
        </div>
      </header>

      <div className="flex flex-row flex-grow overflow-hidden">
        <div className="flex flex-col w-2/3 md:w-3/5 lg:w-2/3 h-full">
          <div ref={chatContainerRef} className="flex-grow p-4 space-y-4 overflow-y-auto bg-gray-800 scroll-smooth">
            {messages.map((msg) => {
              const streamingState = streamingMessages.get(msg.id);
              const displayMessage = streamingState && !streamingState.isComplete 
                ? { ...msg, text: streamingState.text }
                : msg;
              
              return <MessageBubble key={msg.id} message={displayMessage} />;
            })}
          </div>
          <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} isApiKeyMissing={!isSystemReady} />
        </div>

        <div className="w-1/3 md:w-2/5 lg:w-1/3 h-full bg-slate-800">
          <Notepad
            content={notepadContent}
            lastUpdatedBy={lastNotepadUpdateBy}
            isLoading={isLoading}
          />
        </div>
      </div>

      {/* 配置管理器 */}
      <ModelConfigManager
        isOpen={isConfigManagerOpen}
        onClose={() => setIsConfigManagerOpen(false)}
        onConfigChange={loadConfiguration}
      />

      {/* 处理时间显示 */}
      {(isLoading || (currentTotalProcessingTimeMs > 0 && !isLoading) || (isLoading && currentTotalProcessingTimeMs === 0)) && (
        <div className="fixed bottom-4 right-4 md:bottom-6 md:right-6 bg-gray-900 bg-opacity-80 text-white p-2 rounded-md shadow-lg text-xs z-50">
          总耗时: {(currentTotalProcessingTimeMs / 1000).toFixed(2)}s
          {isDiscussionActive && (
            <div className="text-green-400 mt-1">讨论进行中...</div>
          )}
        </div>
      )}

      {/* 系统状态提示 */}
      {!isSystemReady && (
        <div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 p-3 bg-orange-700 text-white rounded-lg shadow-lg flex items-center text-sm z-50">
          <AlertTriangle size={20} className="mr-2" /> 
          {!hasValidChannels ? '请配置API渠道和密钥' : '请配置AI角色'}
          。点击设置按钮进行配置。
        </div>
      )}
    </div>
  );
};

export default App;