/**
 * Chat Area - Protocol Agent 聊天区域
 * 
 * 方案A: 使用 Protocol Agent 独立 API
 * - POST /api/v1/aia/protocol-agent/message 发送消息
 * - 后端返回结构化 AgentResponse（含 syncButton, actionCards）
 */

import React, { useState, useRef, useEffect, useCallback } from 'react';
import { Send, Sparkles, User, Loader2, ExternalLink } from 'lucide-react';
import { ThinkingBlock, useAIStream } from '@/shared/components/Chat';
import { getAccessToken } from '../../../../framework/auth/api';
import type { ProtocolContext } from '../types';
import { SyncButton } from './SyncButton';
import { MarkdownContent } from './MarkdownContent';

// ============================================
// 类型定义（与后端 AgentResponse 对应）
// ============================================

interface SyncButtonData {
  stageCode: string;
  extractedData: Record<string, unknown>;
  label: string;
  disabled?: boolean;
}

interface ActionCard {
  id: string;
  type: string;
  title: string;
  description?: string;
  actionUrl?: string;
  actionParams?: Record<string, unknown>;
}

interface Message {
  id: string;
  role: 'user' | 'assistant' | 'system';
  content: string;
  thinkingContent?: string;
  stage?: string;
  stageName?: string;
  syncButton?: SyncButtonData;
  actionCards?: ActionCard[];
  timestamp: Date;
}

interface ChatAreaProps {
  conversationId?: string;
  context: ProtocolContext | null;
  onContextUpdate: () => void;
  /** 更新对话标题（首次发送消息时调用） */
  onTitleUpdate?: (title: string) => void;
}

// ============================================
// 阶段常量
// ============================================

const STAGE_NAMES: Record<string, string> = {
  scientific_question: '科学问题梳理',
  pico: 'PICO要素',
  study_design: '研究设计',
  sample_size: '样本量计算',
  endpoints: '观察指标',
};

/**
 * 从 AI 响应中解析 extracted_data XML 标签
 */
function parseExtractedData(content: string): {
  cleanContent: string;
  extractedData: Record<string, unknown> | null;
} {
  const regex = /<extracted_data>([\s\S]*?)<\/extracted_data>/;
  const match = content.match(regex);
  
  if (!match) {
    return { cleanContent: content, extractedData: null };
  }

  try {
    const jsonStr = match[1].trim();
    const extractedData = JSON.parse(jsonStr);
    const cleanContent = content.replace(regex, '').trim();
    return { cleanContent, extractedData };
  } catch (e) {
    console.warn('[ChatArea] Failed to parse extracted_data:', e);
    return { cleanContent: content, extractedData: null };
  }
}

// ============================================
// 主组件
// ============================================

export const ChatArea: React.FC<ChatAreaProps> = ({ 
  conversationId, 
  context,
  onContextUpdate,
  onTitleUpdate,
}) => {
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [isLoadingHistory, setIsLoadingHistory] = useState(false);
  const chatContainerRef = useRef<HTMLDivElement>(null);
  const prevConversationIdRef = useRef<string | undefined>(undefined);
  const isFirstMount = useRef(true);

  // 使用通用 useAIStream hook 实现流式输出（打字机效果）
  const {
    content: streamContent,
    thinking: streamThinking,
    status: streamStatus,
    isStreaming,
    isThinking,
    error: streamError,
    sendMessage: sendStreamMessage,
    reset: resetStream,
  } = useAIStream({
    apiEndpoint: `/api/v1/aia/protocol-agent/message`,
    headers: {
      Authorization: `Bearer ${getAccessToken()}`,
    },
  });

  // 自动滚动到底部
  const scrollToBottom = useCallback(() => {
    if (chatContainerRef.current) {
      chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
    }
  }, []);

  useEffect(() => {
    scrollToBottom();
  }, [messages, streamContent, scrollToBottom]);

  // 生成欢迎消息（紧凑版本）
  const createWelcomeMessage = useCallback((currentStage?: string): Message => {
    const stage = currentStage || 'scientific_question';
    const stageName = STAGE_NAMES[stage] || '科学问题梳理';
    
    return {
      id: 'welcome',
      role: 'assistant',
      content: `您好！我是研究方案制定助手，将帮助您系统地完成临床研究方案的核心要素设计。我们将一起完成以下5个关键步骤：
1️⃣ **科学问题梳理** - 明确研究要解决的核心问题
2️⃣ **PICO要素** - 确定研究人群、干预、对照和结局
3️⃣ **研究设计** - 选择合适的研究类型和方法
4️⃣ **样本量计算** - 估算所需的样本量
5️⃣ **观察指标** - 定义基线、暴露、结局指标和混杂因素

完成这5个要素后，您可以**一键生成完整的研究方案**并下载为Word文档。

📍 **当前阶段**: ${stageName}
让我们开始吧！请先告诉我，您想研究什么问题？或者描述一下您的研究背景和想法。`,
      stage,
      stageName,
      timestamp: new Date(),
    };
  }, []);

  // 加载历史消息（当 conversationId 变化时）
  useEffect(() => {
    // 首次挂载或 conversationId 变化时执行
    const shouldUpdate = isFirstMount.current || conversationId !== prevConversationIdRef.current;
    
    if (!shouldUpdate) {
      return;
    }
    
    isFirstMount.current = false;
    prevConversationIdRef.current = conversationId;
    
    // 如果没有 conversationId，显示欢迎消息（等待自动创建会话）
    if (!conversationId) {
      setMessages([createWelcomeMessage(context?.currentStage)]);
      return;
    }

    const loadHistoryMessages = async () => {
      setIsLoadingHistory(true);
      try {
        const token = getAccessToken();
        const response = await fetch(`/api/v1/aia/protocol-agent/messages/${conversationId}`, {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        });

        if (response.ok) {
          const result = await response.json();
          const historyMessages = result.data?.messages || [];
          
          if (historyMessages.length > 0) {
            // 有历史消息：加载历史 + 欢迎消息在最前
            const loadedMessages: Message[] = historyMessages.map((m: any) => ({
              id: m.id,
              role: m.role,
              content: m.content,
              thinkingContent: m.thinkingContent,
              timestamp: new Date(m.createdAt),
            }));
            
            // 在历史消息前添加欢迎消息
            setMessages([createWelcomeMessage(context?.currentStage), ...loadedMessages]);
          } else {
            // 没有历史消息：只显示欢迎消息
            setMessages([createWelcomeMessage(context?.currentStage)]);
          }
        } else {
          // API 失败：显示欢迎消息
          setMessages([createWelcomeMessage(context?.currentStage)]);
        }
      } catch (error) {
        console.error('[ChatArea] 加载历史消息失败:', error);
        // 出错也显示欢迎消息
        setMessages([createWelcomeMessage(context?.currentStage)]);
      } finally {
        setIsLoadingHistory(false);
      }
    };

    loadHistoryMessages();
  }, [conversationId, context?.currentStage, createWelcomeMessage]);

  // 处理流式响应完成
  useEffect(() => {
    if (streamStatus === 'complete' && streamContent) {
      // 解析 AI 响应中的 extracted_data（用于同步按钮）
      const { cleanContent, extractedData } = parseExtractedData(streamContent);
      
      // 构建同步按钮数据
      let syncButton: SyncButtonData | undefined;
      if (extractedData) {
        const stageCode = context?.currentStage || 'scientific_question';
        syncButton = {
          stageCode,
          extractedData,
          label: `✅ 同步「${STAGE_NAMES[stageCode]}」到方案`,
          disabled: false,
        };
      }

      // 添加 AI 消息
      const aiMessage: Message = {
        id: Date.now().toString(),
        role: 'assistant',
        content: cleanContent,
        thinkingContent: streamThinking || undefined,
        stage: context?.currentStage,
        stageName: context?.stageName,
        syncButton,
        timestamp: new Date(),
      };

      setMessages(prev => [...prev, aiMessage]);
      resetStream();
      
      // 刷新上下文状态
      onContextUpdate();
    }
  }, [streamStatus, streamContent, streamThinking, context, resetStream, onContextUpdate]);

  // 处理流式错误
  useEffect(() => {
    if (streamStatus === 'error' && streamError) {
      setMessages(prev => [...prev, {
        id: Date.now().toString(),
        role: 'system',
        content: `❌ 发送失败：${streamError}`,
        timestamp: new Date(),
      }]);
      resetStream();
    }
  }, [streamStatus, streamError, resetStream]);

  /**
   * 发送消息（流式）
   */
  const handleSend = useCallback(async () => {
    if (!input.trim() || !conversationId || isStreaming) return;

    const userContent = input.trim();
    
    // 检查是否是首次用户消息（只有欢迎消息时）
    const isFirstUserMessage = messages.filter(m => m.role === 'user').length === 0;
    
    // 添加用户消息
    const userMessage: Message = {
      id: Date.now().toString(),
      role: 'user',
      content: userContent,
      timestamp: new Date(),
    };
    setMessages(prev => [...prev, userMessage]);
    setInput('');

    // 首次消息时更新对话标题（锦上添花，不影响核心功能）
    if (isFirstUserMessage && onTitleUpdate) {
      try {
        const newTitle = userContent.length > 20 
          ? userContent.slice(0, 20) + '...' 
          : userContent;
        onTitleUpdate(newTitle);
      } catch (e) {
        console.warn('[ChatArea] 更新标题失败，不影响对话:', e);
      }
    }

    // 发送消息
    await sendStreamMessage(userContent, {
      conversationId,
    });
  }, [input, conversationId, isStreaming, sendStreamMessage, messages, onTitleUpdate]);

  /**
   * 处理同步到方案
   */
  const handleSync = useCallback(async (stageCode: string, data: Record<string, unknown>) => {
    if (!conversationId) return;

    try {
      const token = getAccessToken();
      const response = await fetch('/api/v1/aia/protocol-agent/sync', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`,
        },
        body: JSON.stringify({
          conversationId,
          stageCode,
          data,
        }),
      });

      const result = await response.json();

      if (response.ok && result.success) {
        // 添加成功提示
        setMessages(prev => [...prev, {
          id: Date.now().toString(),
          role: 'system',
          content: `✅ ${result.data?.message || `已同步「${STAGE_NAMES[stageCode] || stageCode}」到方案`}`,
          timestamp: new Date(),
        }]);
        
        // 刷新上下文状态
        onContextUpdate();
      } else {
        throw new Error(result.error || '同步失败');
      }
    } catch (err) {
      console.error('[ChatArea] handleSync error:', err);
      setMessages(prev => [...prev, {
        id: Date.now().toString(),
        role: 'system',
        content: `❌ 同步失败：${err instanceof Error ? err.message : '请重试'}`,
        timestamp: new Date(),
      }]);
    }
  }, [conversationId, onContextUpdate]);

  /**
   * 处理动作卡片点击
   */
  const handleActionCard = useCallback((card: ActionCard) => {
    console.log('[ChatArea] Action card clicked:', card);
    
    if (card.actionUrl) {
      // 对于 API 调用类型的动作卡片
      if (card.actionUrl.startsWith('/api/')) {
        // TODO: 实现 API 调用（如一键生成）
        setMessages(prev => [...prev, {
          id: Date.now().toString(),
          role: 'system',
          content: `⏳ 正在执行：${card.title}...`,
          timestamp: new Date(),
        }]);
      } else {
        // 跳转到工具页面
        window.open(card.actionUrl, '_blank');
      }
    }
  }, []);

  // 按 Enter 发送
  const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  }, [handleSend]);

  return (
    <section className="chat-area">
      {/* 聊天历史 */}
      <div className="chat-container" ref={chatContainerRef}>
        {/* 加载历史消息时显示加载状态 */}
        {isLoadingHistory && (
          <div className="loading-history">
            <div className="loading-spinner" />
            <span>加载历史消息...</span>
          </div>
        )}
        
        {messages.map(msg => (
          <div key={msg.id}>
            {msg.role === 'user' && (
              <div className="message-row user-row">
                <div className="avatar user-avatar">
                  <User size={16} />
                </div>
                <div className="message-content">
                  <div className="message-meta">您 • {formatTime(msg.timestamp)}</div>
                  <div className="chat-bubble user-bubble">
                    {msg.content}
                  </div>
                </div>
              </div>
            )}

            {msg.role === 'assistant' && (
              <div className="message-row assistant-row">
                <div className="avatar assistant-avatar">
                  <Sparkles size={16} />
                </div>
                <div className="message-content">
                  <div className="message-meta">
                    Protocol Agent
                    {msg.stageName && <span className="stage-tag">{msg.stageName}</span>}
                    <span className="timestamp">• {formatTime(msg.timestamp)}</span>
                  </div>
                  
                  {/* 深度思考内容 */}
                  {msg.thinkingContent && (
                    <ThinkingBlock content={msg.thinkingContent} />
                  )}
                  
                  <div className="chat-bubble assistant-bubble">
                    <MarkdownContent content={msg.content} />
                  </div>
                  
                  {/* 同步按钮 */}
                  {msg.syncButton && !msg.syncButton.disabled && (
                    <SyncButton 
                      syncData={msg.syncButton}
                      onSync={handleSync}
                    />
                  )}
                  
                  {/* 动作卡片 */}
                  {msg.actionCards && msg.actionCards.length > 0 && (
                    <div className="action-cards">
                      {msg.actionCards.map(card => (
                        <div 
                          key={card.id} 
                          className="action-card"
                          onClick={() => handleActionCard(card)}
                        >
                          <div className="action-card-title">{card.title}</div>
                          {card.description && (
                            <div className="action-card-desc">{card.description}</div>
                          )}
                          <ExternalLink size={14} className="action-card-icon" />
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              </div>
            )}

            {msg.role === 'system' && (
              <div className="message-row system-row">
                <div className="system-message">
                  {msg.content}
                </div>
              </div>
            )}
          </div>
        ))}

        {/* 流式输出中的消息（打字机效果） */}
        {(isStreaming || isThinking) && (
          <div className="message-row assistant-row">
            <div className="avatar assistant-avatar">
              <Sparkles size={16} />
            </div>
            <div className="message-content">
              <div className="message-meta">
                Protocol Agent
                {context?.stageName && <span className="stage-tag">{context.stageName}</span>}
                <span className="timestamp">• 正在回复...</span>
              </div>
              
              {/* 深度思考内容（流式） */}
              {isThinking && streamThinking && (
                <ThinkingBlock content={streamThinking} isThinking />
              )}
              
              {/* 流式内容 */}
              {streamContent ? (
                <div className="chat-bubble assistant-bubble">
                  <MarkdownContent content={streamContent} />
                  <span className="streaming-cursor">▊</span>
                </div>
              ) : (
                <div className="chat-bubble assistant-bubble loading">
                  <Loader2 size={16} className="spinner" />
                  <span>AI 正在思考...</span>
                </div>
              )}
            </div>
          </div>
        )}
      </div>

      {/* 输入区 */}
      <div className="input-area">
        <div className="input-wrapper">
          <input
            type="text"
            className="input-field"
            placeholder="输入您的问题或想法..."
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={handleKeyDown}
            disabled={isStreaming || !conversationId}
          />
          <button 
            className="send-btn"
            onClick={handleSend}
            disabled={isStreaming || !input.trim() || !conversationId}
          >
            {isStreaming ? <Loader2 size={16} className="spinner" /> : <Send size={16} />}
          </button>
        </div>
      </div>
    </section>
  );
};

/**
 * 格式化时间
 */
function formatTime(date: Date): string {
  return date.toLocaleTimeString('zh-CN', { 
    hour: '2-digit', 
    minute: '2-digit' 
  });
}
