import React, { useState, useRef, useEffect } from 'react';
import { Button, Card, Space, Typography, Alert, Divider, Progress } from 'antd';
import { AudioOutlined, PlayCircleOutlined, StopOutlined, UploadOutlined, DeleteOutlined } from '@ant-design/icons';
import { startChatStream, uploadFile } from '@/server/api';
import './index.scss';

const { Title, Text } = Typography;

interface AudioTestPageProps {}

// 测试用的Bot ID - 基于官方示例
const TEST_BOT_ID = '7509379008556089379';

const AudioTestPage: React.FC<AudioTestPageProps> = () => {
  const [isRecording, setIsRecording] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [logs, setLogs] = useState<string[]>([]);
  const [token, setToken] = useState<string>('');
  const [conversationId, setConversationId] = useState<string>('');
  const [audioBlob, setAudioBlob] = useState<Blob | null>(null);
  const [audioUrl, setAudioUrl] = useState<string>('');
  const [responseAudioUrl, setResponseAudioUrl] = useState<string>('');
  
  const mediaRecorderRef = useRef<MediaRecorder | null>(null);
  const audioChunksRef = useRef<Blob[]>([]);
  const audioRef = useRef<HTMLAudioElement | null>(null);

  // 添加日志
  const addLog = (message: string) => {
    const timestamp = new Date().toLocaleTimeString();
    setLogs(prev => [...prev, `[${timestamp}] ${message}`]);
  };

  // 获取Token - 基于官方示例
  const getToken = async () => {
    try {
      addLog('正在获取Token...');
      const response = await fetch('http://localhost:8000/agent/v1/cozechat/get-token?modelEnum=CONSULTANT_PRACTICE');
      const data = await response.json();
      
      if (data.code === 10000 && data.data) {
        setToken(data.data);
        addLog(`✅ Token获取成功: ${data.data.substring(0, 20)}...`);
        return data.data;
      } else {
        throw new Error(`获取Token失败: ${data.message || '未知错误'}`);
      }
    } catch (error) {
      const errorMsg = `❌ 获取Token失败: ${error}`;
      setError(errorMsg);
      addLog(errorMsg);
      throw error;
    }
  };

  // 创建对话 - 基于官方示例
  const createConversation = async () => {
    try {
      addLog('正在创建对话...');
      const currentToken = token || await getToken();
      
      const response = await fetch('http://localhost:8000/agent/v1/cozechat/create-conversation', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${currentToken}`
        },
        body: JSON.stringify({
          bot_id: TEST_BOT_ID,
          user_id: 'web-audio-test-user'
        })
      });
      
      const data = await response.json();
      if (data.code === 10000 && data.data?.id) {
        setConversationId(data.data.id);
        addLog(`✅ 对话创建成功: ${data.data.id}`);
        return data.data.id;
      } else {
        throw new Error(`创建对话失败: ${data.message || '未知错误'}`);
      }
    } catch (error) {
      const errorMsg = `❌ 创建对话失败: ${error}`;
      setError(errorMsg);
      addLog(errorMsg);
      throw error;
    }
  };

  // 初始化音频录制 - 基于官方示例的Web版本
  const initAudioRecording = async () => {
    try {
      addLog('🎤 正在初始化音频录制...');
      
      // 检查浏览器支持
      if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
        throw new Error('浏览器不支持音频录制');
      }

      // 请求麦克风权限
      const stream = await navigator.mediaDevices.getUserMedia({ 
        audio: {
          sampleRate: 16000,
          channelCount: 1,
          echoCancellation: true,
          noiseSuppression: true
        } 
      });

      addLog('✅ 麦克风权限获取成功');
      addLog('✅ 音频录制初始化完成');
      
      // 创建MediaRecorder
      mediaRecorderRef.current = new MediaRecorder(stream, {
        mimeType: 'audio/webm;codecs=opus'
      });

      // 监听数据可用事件
      mediaRecorderRef.current.ondataavailable = (event) => {
        if (event.data.size > 0) {
          audioChunksRef.current.push(event.data);
        }
      };

      // 监听录制停止事件
      mediaRecorderRef.current.onstop = () => {
        const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/webm' });
        setAudioBlob(audioBlob);
        const url = URL.createObjectURL(audioBlob);
        setAudioUrl(url);
        addLog(`✅ 音频录制完成，大小: ${(audioBlob.size / 1024).toFixed(2)}KB`);
        audioChunksRef.current = [];
      };

      return true;
    } catch (error) {
      const errorMsg = `❌ 初始化音频录制失败: ${error}`;
      setError(errorMsg);
      addLog(errorMsg);
      return false;
    }
  };

  // 开始录音 - 基于官方示例
  const startRecording = async () => {
    try {
      if (!mediaRecorderRef.current) {
        const success = await initAudioRecording();
        if (!success) return;
      }

      setIsRecording(true);
      setError(null);
      addLog('🎙️ 开始录音...');

      if (mediaRecorderRef.current && mediaRecorderRef.current.state === 'inactive') {
        mediaRecorderRef.current.start();
        addLog('📹 录音器已启动');
      }
    } catch (error) {
      const errorMsg = `开始录音失败: ${error}`;
      setError(errorMsg);
      addLog(`❌ ${errorMsg}`);
      setIsRecording(false);
    }
  };

  // 停止录音
  const stopRecording = () => {
    try {
      if (mediaRecorderRef.current && mediaRecorderRef.current.state === 'recording') {
        mediaRecorderRef.current.stop();
        setIsRecording(false);
        addLog('🛑 录音已停止');
      }
    } catch (error) {
      addLog(`停止录音失败: ${error}`);
    }
  };

  // 上传音频文件并发送聊天 - 基于官方示例
  const uploadAudioAndChat = async () => {
    if (!audioBlob) {
      addLog('❌ 请先录制音频');
      return;
    }

    try {
      setIsProcessing(true);
      setError(null);
      
      // 确保有Token和ConversationId
      const currentToken = token || await getToken();
      const currentConversationId = conversationId || await createConversation();

      addLog('📤 正在上传音频文件...');
      
      // 创建FormData上传音频
      const formData = new FormData();
      formData.append('file', audioBlob, 'audio.webm');
      
      const uploadResponse = await fetch('http://localhost:8000/agent/v1/cozechat/upload-file', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${currentToken}`
        },
        body: formData
      });

      const uploadData = await uploadResponse.json();
      if (uploadData.code !== 10000 || !uploadData.data?.id) {
        throw new Error(`上传音频失败: ${uploadData.message}`);
      }

      const fileId = uploadData.data.id;
      addLog(`✅ 音频上传成功，文件ID: ${fileId}`);

      // 发送聊天消息 - 基于官方示例
      addLog('💬 正在发送音频消息...');
      const chatResponse = await fetch('http://localhost:8000/agent/v1/cozechat/chat-stream', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${currentToken}`
        },
        body: JSON.stringify({
          bot_id: TEST_BOT_ID,
          user_id: 'web-audio-test-user',
          conversation_id: currentConversationId,
          additional_messages: [
            {
              role: 'user',
              type: 'question',
              content: '',
              content_type: 'object_string',
              object_string: {
                type: 'audio',
                file_id: fileId
              }
            }
          ]
        })
      });

      if (!chatResponse.ok) {
        throw new Error(`聊天请求失败: ${chatResponse.statusText}`);
      }

      addLog('✅ 音频消息发送成功');
      addLog('🎧 正在等待AI回复...');

      // 处理流式响应
      const reader = chatResponse.body?.getReader();
      if (!reader) {
        throw new Error('无法读取响应流');
      }

      let audioData = '';
      let textResponse = '';

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        const chunk = new TextDecoder().decode(value);
        const lines = chunk.split('\n');

        for (const line of lines) {
          if (line.startsWith('data: ')) {
            try {
              const data = JSON.parse(line.slice(6));
              
              if (data.event === 'conversation.message.delta') {
                textResponse += data.message.content;
                console.log('文本回复:', data.message.content);
              } else if (data.event === 'conversation.audio.delta') {
                audioData += data.message.content;
                addLog('📻 接收音频数据块...');
              }
            } catch (e) {
              // 忽略解析错误
            }
          }
        }
      }

      if (textResponse) {
        addLog(`💬 AI回复: ${textResponse}`);
      }

      if (audioData) {
        // 转换Base64音频数据为播放格式
        const audioBuffer = Uint8Array.from(atob(audioData), c => c.charCodeAt(0));
        const audioBlob = new Blob([audioBuffer], { type: 'audio/pcm' });
        const audioUrl = URL.createObjectURL(audioBlob);
        setResponseAudioUrl(audioUrl);
        addLog('🎵 AI音频回复已准备就绪');
      }

    } catch (error) {
      const errorMsg = `语音聊天失败: ${error}`;
      setError(errorMsg);
      addLog(`❌ ${errorMsg}`);
    } finally {
      setIsProcessing(false);
    }
  };

  // 播放AI回复音频
  const playResponseAudio = () => {
    if (responseAudioUrl && audioRef.current) {
      audioRef.current.src = responseAudioUrl;
      audioRef.current.play();
      addLog('🔊 正在播放AI回复音频');
    }
  };

  // 清空录音
  const clearRecording = () => {
    setAudioBlob(null);
    setAudioUrl('');
    setResponseAudioUrl('');
    addLog('🗑️ 已清空录音');
  };

  // 清空日志
  const clearLogs = () => {
    setLogs([]);
  };

  // 播放录制的音频
  const playRecordedAudio = () => {
    if (audioUrl && audioRef.current) {
      audioRef.current.src = audioUrl;
      audioRef.current.play();
      addLog('🎵 正在播放录制的音频');
    }
  };

  // 初始化
  useEffect(() => {
    addLog('🚀 官方语音测试页面已加载 (基于 Coze Python SDK 示例)');
    getToken().catch(() => {}); // 预先获取token，忽略错误
    
    return () => {
      // 清理资源
      if (audioUrl) URL.revokeObjectURL(audioUrl);
      if (responseAudioUrl) URL.revokeObjectURL(responseAudioUrl);
    };
  }, []);

  return (
    <div className="audio-test-page">
      <audio ref={audioRef} style={{ display: 'none' }} />
      
      <div className="audio-test-container">
        <Card className="main-card">
          <Title level={2}>🎙️ Coze 官方语音测试 (基于Python SDK示例)</Title>
          <Text type="secondary">Bot ID: {TEST_BOT_ID}</Text>
          <Text type="secondary" style={{ display: 'block', marginTop: 4 }}>
            基于 /参考代码/coze-py-main/examples/chat_oneonone_audio.py
          </Text>
          
          <Divider />

          {error && (
            <Alert
              message="错误信息"
              description={error}
              type="error"
              showIcon
              closable
              onClose={() => setError(null)}
              style={{ marginBottom: 16 }}
            />
          )}

          <div className="audio-record-section">
            <Title level={4}>🎤 音频录制</Title>
            <Space wrap>
              <Button
                type="primary"
                icon={<AudioOutlined />}
                loading={isRecording}
                onClick={isRecording ? stopRecording : startRecording}
                danger={isRecording}
              >
                {isRecording ? '停止录音' : '开始录音'}
              </Button>
              
              {audioBlob && (
                <>
                  <Button
                    icon={<PlayCircleOutlined />}
                    onClick={playRecordedAudio}
                  >
                    播放录音
                  </Button>
                  
                  <Button
                    icon={<DeleteOutlined />}
                    onClick={clearRecording}
                  >
                    清空录音
                  </Button>
                </>
              )}
            </Space>
            
            {audioBlob && (
              <div style={{ marginTop: 12 }}>
                <Text type="success">
                  ✅ 录音完成，大小: {(audioBlob.size / 1024).toFixed(2)}KB
                </Text>
              </div>
            )}
          </div>

          <Divider />

          <div className="chat-section">
            <Title level={4}>💬 语音聊天 (官方API)</Title>
            <Space wrap>
              <Button
                type="primary"
                icon={<UploadOutlined />}
                loading={isProcessing}
                disabled={!audioBlob || isProcessing}
                onClick={uploadAudioAndChat}
              >
                {isProcessing ? '处理中...' : '发送音频消息'}
              </Button>
              
              {responseAudioUrl && (
                <Button
                  icon={<PlayCircleOutlined />}
                  onClick={playResponseAudio}
                >
                  播放AI回复
                </Button>
              )}
            </Space>
            
            {isProcessing && (
              <div style={{ marginTop: 12 }}>
                <Progress percent={50} status="active" showInfo={false} />
                <Text type="secondary">正在处理语音消息...</Text>
              </div>
            )}
          </div>

          <Divider />

          <div className="token-section">
            <Title level={4}>🔑 认证信息</Title>
            <Space direction="vertical" style={{ width: '100%' }}>
              <div>
                <Text strong>Token: </Text>
                <Text code>{token ? `${token.substring(0, 30)}...` : '未获取'}</Text>
              </div>
              <div>
                <Text strong>对话ID: </Text>
                <Text code>{conversationId || '未创建'}</Text>
              </div>
              <Button size="small" onClick={getToken}>
                重新获取Token
              </Button>
            </Space>
          </div>
        </Card>

        <Card className="log-card" title="实时日志">
          <div className="log-controls">
            <Button size="small" onClick={clearLogs}>清空日志</Button>
          </div>
          <div className="log-container">
            {logs.length === 0 ? (
              <Text type="secondary">暂无日志</Text>
            ) : (
              logs.map((log, index) => (
                <div key={index} className="log-item">
                  <Text code>{log}</Text>
                </div>
              ))
            )}
          </div>
        </Card>
      </div>
    </div>
  );
};

export default AudioTestPage;
