import React, { useState, useEffect, useRef, useCallback } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import { AudioOutline, AudioFill } from "antd-mobile-icons";
import './AiChatStyles.less';

const ChatInterface = () => {
  // ==================== 状态管理 ====================
  const [sessionId, setSessionId] = useState('');
  const [sUserId] = useState('user-001');
  const [sUserType] = useState('sysadmin');
  const [messages, setMessages] = useState([]);
  const [inputValue, setInputValue] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [currentModel, setCurrentModel] = useState('general');
  const [chatHistory, setChatHistory] = useState([]);
  const [welcomeContent, setWelcomeContent] = useState('');

  // 语音输入状态
  const [isRecording, setIsRecording] = useState(false);
  const [isWsConnected, setIsWsConnected] = useState(false);
  const [isVoiceMode, setIsVoiceMode] = useState(false);
  const [recordingDuration, setRecordingDuration] = useState(0);

  const messagesEndRef = useRef(null);
  const inputRef = useRef(null);
  const wsRef = useRef(null);
  const audioContextRef = useRef(null);
  const scriptProcessorRef = useRef(null);
  const inputNodeRef = useRef(null);
  const recordingTimerRef = useRef(null);
  const isRecordingRef = useRef(false);

  // ==================== 配置 ====================
  const CONFIG = {
    backendUrl: 'http://localhost:8099/xlyAi',
    wsUrl: 'ws://121.43.128.225:10096', // 语音识别WebSocket地址
    sampleRate: 16000,
    endpoints: {
      chat: '/api/v1/chat/query',
      process: '/api/v1/chat/query',
    },
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    },
    maxHistory: 20,
  };

  // ==================== 工具函数 ====================
  const getCurrentTime = () => {
    const now = new Date();
    return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;
  };

  const generateRandomString = (length) => {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < length; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  };

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  // ==================== WebSocket 语音识别 ====================

  // 连接语音识别WebSocket
  const connectWebSocket = useCallback(() => {
    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
      return;
    }

    const ws = new WebSocket(CONFIG.wsUrl);
    ws.binaryType = "arraybuffer";

    ws.onopen = () => {
      console.log("语音识别WebSocket连接成功");
      setIsWsConnected(true);
    };

    ws.onmessage = (event) => {
      try {
        const res = JSON.parse(event.data);
        if (res.code === 0 && (res.msg === "success" || res.msg === "flush_success")) {
          if (res.text && res.text.trim()) {
            setInputValue(prev => {
              const separator = prev && !prev.endsWith(' ') ? ' ' : '';
              const newValue = prev ? `${prev}${separator}${res.text}` : res.text;
              console.log('语音识别结果:', res.text, '更新后:', newValue);
              return newValue;
            });
          }
        }
      } catch (e) {
        console.error("WebSocket消息解析失败:", e);
      }
    };

    ws.onclose = () => {
      console.log("语音识别WebSocket连接断开");
      setIsWsConnected(false);
      if (isRecordingRef.current) {
        stopRecording();
      }
    };

    ws.onerror = (err) => {
      console.error("WebSocket错误:", err);
      setIsWsConnected(false);
    };

    wsRef.current = ws;
  }, []);

  // 断开WebSocket
  const disconnectWebSocket = useCallback(() => {
    if (wsRef.current) {
      wsRef.current.close();
      wsRef.current = null;
    }
    setIsWsConnected(false);
  }, []);

  // 发送指令
  const sendCommand = useCallback((action) => {
    if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
      return;
    }
    const cmd = JSON.stringify({ action });
    wsRef.current.send(cmd);
  }, []);

  // Float32 转 Int16 PCM
  const float32ToInt16 = (float32Array) => {
    const int16Array = new Int16Array(float32Array.length);
    for (let i = 0; i < float32Array.length; i++) {
      let s = Math.max(-1, Math.min(1, float32Array[i]));
      int16Array[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
    }
    return new Uint8Array(int16Array.buffer);
  };

  // 音频重采样
  const resampleAudio = (data, originalRate, targetRate) => {
    if (originalRate === targetRate) return data;
    const ratio = targetRate / originalRate;
    const newLength = Math.round(data.length * ratio);
    const result = new Float32Array(newLength);
    for (let i = 0; i < newLength; i++) {
      result[i] = data[Math.round(i / ratio)] || 0;
    }
    return result;
  };

  // 开始录音
  const startRecording = async () => {
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
      alert("浏览器不支持麦克风采集");
      return;
    }

    try {
      // 先连接WebSocket
      if (!isWsConnected) {
        connectWebSocket();
        await new Promise(resolve => setTimeout(resolve, 1000));
      }

      // 检查 WebSocket 是否已连接
      if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
        alert("语音识别服务未连接，请重试");
        return;
      }

      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)();
      inputNodeRef.current = audioContextRef.current.createMediaStreamSource(stream);
      scriptProcessorRef.current = audioContextRef.current.createScriptProcessor(2048, 1, 1);

      // 使用 ref 来检查录音状态，避免闭包问题
      scriptProcessorRef.current.onaudioprocess = (event) => {
        if (!isRecordingRef.current) return;
        const inputData = event.inputBuffer.getChannelData(0);
        const resampledData = resampleAudio(inputData, audioContextRef.current.sampleRate, CONFIG.sampleRate);
        const pcmData = float32ToInt16(resampledData);
        if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
          wsRef.current.send(pcmData);
        }
      };

      inputNodeRef.current.connect(scriptProcessorRef.current);
      scriptProcessorRef.current.connect(audioContextRef.current.destination);

      // 关键：先设置 ref，再设置 state
      isRecordingRef.current = true;
      setIsRecording(true);
      setIsVoiceMode(true);
      setRecordingDuration(0);

      // 开始计时
      recordingTimerRef.current = setInterval(() => {
        setRecordingDuration(prev => prev + 1);
      }, 1000);

      console.log("录音已开始");

    } catch (e) {
      console.error("录音启动失败:", e);
      alert("录音启动失败：" + e.message);
      isRecordingRef.current = false;
      setIsRecording(false);
    }
  };

  // 停止录音
  const stopRecording = useCallback(() => {
    console.log("停止录音");
    isRecordingRef.current = false;
    setIsRecording(false);
    setIsVoiceMode(false);

    if (recordingTimerRef.current) {
      clearInterval(recordingTimerRef.current);
      recordingTimerRef.current = null;
    }

    if (inputNodeRef.current) {
      inputNodeRef.current.disconnect();
      inputNodeRef.current = null;
    }
    if (scriptProcessorRef.current) {
      scriptProcessorRef.current.disconnect();
      scriptProcessorRef.current = null;
    }
    if (audioContextRef.current) {
      audioContextRef.current.close();
      audioContextRef.current = null;
    }

    // 发送刷新指令获取最终结果
    sendCommand("flush");
  }, [sendCommand]);

  // 切换录音状态（点击按钮）
  const toggleRecording = useCallback(() => {
    if (isRecordingRef.current) {
      // 正在录音，停止
      stopRecording();
    } else {
      // 未录音，开始
      startRecording();
    }
  }, [stopRecording]);

  // 取消录音并清空
  const cancelRecording = useCallback(() => {
    if (isRecordingRef.current) {
      stopRecording();
    }
    setInputValue('');
    setIsVoiceMode(false);
  }, [stopRecording]);

  // 格式化录音时长
  const formatDuration = (seconds) => {
    const mins = Math.floor(seconds / 60).toString().padStart(2, '0');
    const secs = (seconds % 60).toString().padStart(2, '0');
    return `${mins}:${secs}`;
  };

  // ==================== 初始化 ====================
  useEffect(() => {
    setMessages([
      {
        id: 'welcome',
        type: 'ai',
        content: '',
        time: getCurrentTime(),
        isWelcome: true
      }
    ]);

    const initSession = async () => {
      try {
        const initUrl = `${CONFIG.backendUrl}/api/v1/chat/init?sUserId=${sUserId}&sUserType=${sUserType}`;
        const response = await fetch(initUrl, {
          method: 'POST',
          headers: CONFIG.headers,
          body: JSON.stringify({})
        });
        const data = await response.json();
        if (data.data) {
          setWelcomeContent(data.data);
          setMessages(prev => prev.map(msg =>
            msg.id === 'welcome' ? { ...msg, content: data.data } : msg
          ));
        }
      } catch (error) {
        console.error('初始化失败:', error);
      }
    };

    initSession();
    inputRef.current?.focus();

    const handleKeyDown = (e) => {
      if (e.ctrlKey && e.key === 'Enter') {
        handleSendMessage();
      }
      if (e.key === 'Escape') {
        setInputValue('');
        if (isRecordingRef.current) {
          stopRecording();
          setIsVoiceMode(false);
        }
      }
    };

    document.addEventListener('keydown', handleKeyDown);

    return () => {
      document.removeEventListener('keydown', handleKeyDown);
      disconnectWebSocket();
      if (recordingTimerRef.current) {
        clearInterval(recordingTimerRef.current);
      }
    };
  }, []);

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

  // ==================== 消息处理 ====================
  const addMessage = (content, type, isError = false) => {
    const newMessage = {
      id: `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      type,
      content,
      time: getCurrentTime(),
      isError
    };
    setMessages(prev => [...prev, newMessage]);
    return newMessage.id;
  };

  const handleSendMessage = async () => {
    const message = inputValue.trim();
    if (!message || isLoading) return;

    // 如果正在录音，先停止
    if (isRecordingRef.current) {
      stopRecording();
      setIsVoiceMode(false);
    }

    let currentSessionId = sessionId;
    if (!currentSessionId) {
      currentSessionId = generateRandomString(20);
      setSessionId(currentSessionId);
    }

    setInputValue('');
    setIsLoading(true);

    addMessage(message, 'user');

    const newHistoryItem = { role: 'user', content: message, timestamp: Date.now() };
    setChatHistory(prev => {
      const updated = [...prev, newHistoryItem];
      return updated.length > CONFIG.maxHistory ? updated.slice(-CONFIG.maxHistory) : updated;
    });

    try {
      const endpoint = currentModel === 'process' ? CONFIG.endpoints.process : CONFIG.endpoints.chat;
      const requestData = {
        message,
        modelType: currentModel,
        sUserId,
        sUserType,
        sessionId: currentSessionId
      };

      const response = await fetch(`${CONFIG.backendUrl}${endpoint}`, {
        method: 'POST',
        headers: CONFIG.headers,
        body: JSON.stringify(requestData)
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();

      if (data.data) {
        addMessage(data.data, 'ai');
        setChatHistory(prev => {
          const updated = [...prev, { role: 'assistant', content: data.data, timestamp: Date.now() }];
          return updated.length > CONFIG.maxHistory ? updated.slice(-CONFIG.maxHistory) : updated;
        });
      }
    } catch (error) {
      console.error('请求失败:', error);
      const errorMessage = `
抱歉，请求出现错误：${error.message}

**可能的原因：**
1. Spring Boot 后端服务未启动
2. API 接口路径不正确
3. 网络连接问题

**检查步骤：**
1. 确保后端服务在端口 8099 运行
2. 检查浏览器控制台查看详细错误
3. 刷新页面重试
      `;
      addMessage(errorMessage, 'ai', true);
    } finally {
      setIsLoading(false);
      inputRef.current?.focus();
    }
  };

  const handleClearChat = () => {
    if (window.confirm('确定要清空当前对话吗？')) {
      setMessages([
        {
          id: 'cleared',
          type: 'ai',
          content: '对话已清空，请开始新的对话。',
          time: getCurrentTime(),
        }
      ]);
      setChatHistory([]);
      setSessionId('');
      setInputValue('');
      if (isRecordingRef.current) {
        stopRecording();
        setIsVoiceMode(false);
      }
    }
  };

  const handleCopyMessage = (content) => {
    navigator.clipboard.writeText(content).then(() => {
      alert('已复制到剪贴板');
    });
  };

  const handleRegenerateMessage = (messageId, content) => {
    setChatHistory(prev => prev.filter(item =>
      !(item.role === 'assistant' && item.content === content)
    ));

    setMessages(prev => prev.filter(msg => msg.id !== messageId));

    setInputValue(content);
    setTimeout(() => handleSendMessage(), 100);
  };

  const handleModelChange = (e) => {
    setCurrentModel(e.target.value);
  };

  // ==================== 渲染 ====================
  return (
    <div className="ai-chat-container">
      {/* 头部 */}
      <div className="chat-header">
        <div className="header-left">
          <h1>小羚羊Ai-agent智能体</h1>
          <p>AI 印刷助手</p>
        </div>
        <div className="header-right">
          <select
            className="model-selector"
            value={currentModel}
            onChange={handleModelChange}
          >
            <option value="process">小羚羊印刷行业大模型</option>
            <option value="general">qwen2.5:14b</option>
          </select>
          <button
            className="model-selectors"
            onClick={handleClearChat}
          >
            清空对话
          </button>
        </div>
      </div>

      {/* 主体 */}
      <div className="chat-body">
        <div className="chat-main">
          {/* 消息区域 */}
          <div className="messages-container">
            {messages.map((msg) => (
              <div
                key={msg.id}
                className={`message ${msg.type}-message`}
              >
                <div className={`message-bubble ${msg.type}-bubble`}>
                  <div className="message-content">
                    {msg.type === 'ai' ? (
                      <ReactMarkdown
                        remarkPlugins={[remarkGfm]}
                        components={{
                          code: ({ node, inline, className, children, ...props }) => (
                            inline ? (
                              <code className="inline-code" {...props}>
                                {children}
                              </code>
                            ) : (
                              <pre className="code-block">
                                <code {...props}>{children}</code>
                              </pre>
                            )
                          )
                        }}
                      >
                        {msg.content || welcomeContent}
                      </ReactMarkdown>
                    ) : (
                      msg.content
                    )}
                  </div>
                  <div className="message-meta">
                    <span className="message-time">{msg.time}</span>
                    {msg.type === 'ai' && !msg.isWelcome && (
                      <div className="message-actions">
                        <button
                          className="action-btn"
                          onClick={() => handleCopyMessage(msg.content)}
                        >
                          复制
                        </button>
                        <button
                          className="action-btn"
                          onClick={() => handleRegenerateMessage(msg.id, msg.content)}
                        >
                          重新生成
                        </button>
                      </div>
                    )}
                  </div>
                </div>
              </div>
            ))}

            {/* 打字机效果 */}
            {isLoading && (
              <div className="message ai-message">
                <div className="typing-indicator">
                  <div className="typing-dot"></div>
                  <div className="typing-dot" style={{ animationDelay: '0.2s' }}></div>
                  <div className="typing-dot" style={{ animationDelay: '0.4s' }}></div>
                  <span className="typing-text">正在思考...</span>
                </div>
              </div>
            )}

            <div ref={messagesEndRef} className="bottom-spacer" />
          </div>

          {/* 输入区域 */}
          <div className="input-section">
            {/* 语音模式提示 - 仅在录音时显示 */}
            {isRecording && (
              <div className="voice-mode-indicator">
                <div className="voice-wave">
                  <span></span>
                  <span></span>
                  <span></span>
                  <span></span>
                  <span></span>
                </div>
                <span className="voice-text">
                  正在录音 {formatDuration(recordingDuration)}
                </span>
                <button
                  className="voice-cancel-btn"
                  onClick={cancelRecording}
                >
                  取消
                </button>
              </div>
            )}

            <div className="input-wrapper">
              <input
                ref={inputRef}
                type="text"
                className="message-input"
                placeholder={isRecording ? "正在听您说话..." : "输入您的问题..."}
                value={inputValue}
                onChange={(e) => {
                  if (!isRecording) {
                    setInputValue(e.target.value);
                  }
                }}
                onKeyPress={(e) => {
                  if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault();
                    handleSendMessage();
                  }
                }}
                disabled={isLoading}
                readOnly={isRecording}
              />

              {/* 语音按钮 - 点击切换录音状态 */}
              <button
                className={`voice-button ${isRecording ? 'recording' : ''}`}
                onClick={toggleRecording}
                disabled={isLoading}
              >
                {isRecording ? (
                  <>
                    {/* <AudioFill className="voice-icon" /> */}
                    <span className="voice-text">结束录音</span>
                  </>
                ) : (
                  <>
                    {/* <AudioOutline className="voice-icon" /> */}
                    <span className="voice-text">点击录音</span>
                  </>
                )}
              </button>

              <button
                className={`send-button ${isLoading ? 'disabled' : ''}`}
                onClick={handleSendMessage}
                disabled={isLoading || isRecording}
              >
                发送
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default ChatInterface;