
import React, { useState, useRef, useEffect } from 'react';
import { AIChatMessage, User } from '../../types';
import { Bot, Mic, Square, Volume2, Send, Sparkles, Loader2, Image as ImageIcon, Trash2, X, StopCircle, Globe, Brain, Search, Copy, ChevronDown, ChevronRight, Camera } from 'lucide-react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import { blobToBase64, base64ToUint8Array, decodePCM, cleanTextForTTS, compressImage } from '../../utils/mediaHelpers';
import { Toast, ToastState } from '../Toast';

interface ChatPanelProps {
    currentUser: User | null;
}

export const ChatPanel: React.FC<ChatPanelProps> = ({ currentUser }) => {
    const [messages, setMessages] = useState<AIChatMessage[]>(() => {
        try {
            const saved = localStorage.getItem('ai_chat_history');
            return saved ? JSON.parse(saved) : [{ 
                id: 'welcome', 
                role: 'model', 
                text: '你好！我是你的 AI 智能助教。', 
                timestamp: Date.now() 
            }];
        } catch (e) {
            return [{ id: 'welcome', role: 'model', text: '你好！', timestamp: Date.now() }];
        }
    });
    
    // Input States
    const [textInput, setTextInput] = useState('');
    const [isRecording, setIsRecording] = useState(false);
    const [isMobile, setIsMobile] = useState(false);
    
    // Config States
    const [enableThinking, setEnableThinking] = useState(false);
    const [enableSearch, setEnableSearch] = useState(false);
    
    // Attachments
    const [selectedImages, setSelectedImages] = useState<File[]>([]);
    const [audioAttachment, setAudioAttachment] = useState<string | null>(null); // Base64

    const [isChatProcessing, setIsChatProcessing] = useState(false);
    const [playingMessageId, setPlayingMessageId] = useState<string | null>(null);
    const [toast, setToast] = useState<ToastState>({ show: false, message: '', type: 'success' });
    const [isThinkingExpanded, setIsThinkingExpanded] = useState<Record<string, boolean>>({});
    
    const mediaRecorderRef = useRef<MediaRecorder | null>(null);
    const audioChunksRef = useRef<Blob[]>([]);
    const audioContextRef = useRef<AudioContext | null>(null);
    const currentSourceRef = useRef<AudioBufferSourceNode | null>(null);
    const messagesEndRef = useRef<HTMLDivElement>(null);
    const scrollContainerRef = useRef<HTMLDivElement>(null); 
    const fileInputRef = useRef<HTMLInputElement>(null);
    const cameraInputRef = useRef<HTMLInputElement>(null);
    
    const abortControllerRef = useRef<AbortController | null>(null);

    // Initialize AudioContext & Check Mobile
    useEffect(() => {
        // @ts-ignore
        const AudioCtor = window.AudioContext || window.webkitAudioContext;
        audioContextRef.current = new AudioCtor();
        
        const checkMobile = () => {
            const userAgent = navigator.userAgent || navigator.vendor || (window as any).opera;
            const mobile = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent.toLowerCase());
            setIsMobile(mobile);
        };
        checkMobile();

        return () => {
            stopPlayback();
            window.speechSynthesis.cancel();
        };
    }, []);

    // Persist messages
    useEffect(() => {
        try {
            const MAX_COUNT = 50;
            const welcome = messages.find(m => m.id === 'welcome');
            const others = messages.filter(m => m.id !== 'welcome');
            const recent = others.slice(-MAX_COUNT);
            const messagesToSave = (welcome ? [welcome] : []).concat(recent);
            localStorage.setItem('ai_chat_history', JSON.stringify(messagesToSave));
        } catch (e) {}
    }, [messages]);

    // SMART SCROLL LOGIC
    useEffect(() => {
        if (!scrollContainerRef.current || !messagesEndRef.current) return;
        const container = scrollContainerRef.current;
        const { scrollTop, scrollHeight, clientHeight } = container;
        const isNearBottom = scrollHeight - scrollTop - clientHeight < 150;
        const lastMsg = messages[messages.length - 1];
        const isUserMsg = lastMsg?.role === 'user';

        if (isNearBottom || (isUserMsg && !isChatProcessing)) {
            messagesEndRef.current.scrollIntoView({ behavior: 'smooth', block: 'end' });
        }
    }, [messages, isChatProcessing, isThinkingExpanded]);

    const stopPlayback = () => {
        if (currentSourceRef.current) {
            try { currentSourceRef.current.stop(); } catch (e) {}
            currentSourceRef.current = null;
        }
        window.speechSynthesis.cancel();
        setPlayingMessageId(null);
    };

    const handleStopGeneration = () => {
        if (abortControllerRef.current) {
            abortControllerRef.current.abort();
            abortControllerRef.current = null;
            setIsChatProcessing(false);
            setToast({ show: true, message: '已停止生成', type: 'error' });
        }
    };

    const playAudio = async (msg: AIChatMessage) => {
        stopPlayback();
        if (msg.audio) {
            try {
                if (!audioContextRef.current) {
                    // @ts-ignore
                    const AudioCtor = window.AudioContext || window.webkitAudioContext;
                    audioContextRef.current = new AudioCtor();
                }
                if (audioContextRef.current?.state === 'suspended') {
                    await audioContextRef.current.resume();
                }
                const bytes = base64ToUint8Array(msg.audio);
                const audioBuffer = decodePCM(bytes, audioContextRef.current!);
                const source = audioContextRef.current!.createBufferSource();
                source.buffer = audioBuffer;
                source.connect(audioContextRef.current!.destination);
                source.onended = () => setPlayingMessageId(null);
                source.start(0);
                currentSourceRef.current = source;
                setPlayingMessageId(msg.id);
                return;
            } catch (e) {
                console.warn("PCM Playback failed, falling back to Browser TTS", e);
            }
        }
        
        if (!msg.text) return;
        const cleanText = cleanTextForTTS(msg.text);
        const utterance = new SpeechSynthesisUtterance(cleanText);
        utterance.lang = 'zh-CN';
        utterance.onstart = () => setPlayingMessageId(msg.id);
        utterance.onend = () => setPlayingMessageId(null);
        utterance.onerror = () => setPlayingMessageId(null);
        window.speechSynthesis.speak(utterance);
    };

    const startRecording = async () => {
        if (audioAttachment) return;
        try {
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            const mediaRecorder = new MediaRecorder(stream);
            mediaRecorderRef.current = mediaRecorder;
            audioChunksRef.current = [];

            mediaRecorder.ondataavailable = (event) => {
                if (event.data.size > 0) audioChunksRef.current.push(event.data);
            };

            mediaRecorder.start();
            setIsRecording(true);
        } catch (e) {
            setToast({ show: true, message: '无法访问麦克风', type: 'error' });
        }
    };

    const stopRecording = () => {
        if (mediaRecorderRef.current && isRecording) {
            mediaRecorderRef.current.stop();
            setIsRecording(false);
            
            mediaRecorderRef.current.onstop = async () => {
                const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/webm' });
                const base64 = await blobToBase64(audioBlob);
                setAudioAttachment(base64);
                mediaRecorderRef.current?.stream.getTracks().forEach(track => track.stop());
            };
        }
    };

    const handleImageSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
        if (e.target.files) {
            setSelectedImages(prev => [...prev, ...Array.from(e.target.files!)]);
        }
    };

    const handleCopy = (text: string) => {
        navigator.clipboard.writeText(text);
        setToast({ show: true, message: '已复制', type: 'success' });
    };

    const handleSubmit = async () => {
        if ((!textInput.trim() && !audioAttachment && selectedImages.length === 0) || isChatProcessing) return;
        
        stopPlayback();
        const currentText = textInput;
        const currentAudio = audioAttachment;
        const currentImages = [...selectedImages]; 

        setTextInput('');
        setAudioAttachment(null);
        setSelectedImages([]);

        if (audioContextRef.current?.state === 'suspended') {
            try { await audioContextRef.current.resume(); } catch(e){}
        }
        
        setIsChatProcessing(true);
        abortControllerRef.current = new AbortController();

        const newAiMsgId = crypto.randomUUID(); 
        const newUserMsgId = crypto.randomUUID();

        try {
            const base64Images = await Promise.all(currentImages.map(f => compressImage(f)));

            const newUserMsg: AIChatMessage = { 
                id: newUserMsgId, 
                role: 'user', 
                text: currentAudio ? '(语音消息)' : (currentText || (currentImages.length ? '' : '')), 
                isAudioMessage: !!currentAudio, 
                images: base64Images, 
                timestamp: Date.now() 
            };
            
            const newAiMsg: AIChatMessage = { id: newAiMsgId, role: 'model', text: '', thought: '', timestamp: Date.now(), isSearching: enableSearch };

            setMessages(prev => [...prev, newUserMsg, newAiMsg]);
            
            setTimeout(() => {
                messagesEndRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' });
            }, 100);

            if (enableThinking) setIsThinkingExpanded(prev => ({ ...prev, [newAiMsgId]: true }));

            const response = await fetch('/api/ai/chat', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'x-user-username': currentUser?.username || '',
                    'x-user-role': currentUser?.role || '',
                    'x-school-id': currentUser?.schoolId || ''
                },
                body: JSON.stringify({ 
                    text: currentText, 
                    audio: currentAudio, 
                    images: base64Images, 
                    history: messages.filter(m => m.id !== 'welcome').map(m => ({ role: m.role, text: m.text })),
                    enableThinking,
                    enableSearch
                }),
                signal: abortControllerRef.current.signal
            });

            if (!response.ok) throw new Error(response.statusText);
            if (!response.body) throw new Error('No response body');

            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let aiTextAccumulated = '';
            let aiThoughtAccumulated = '';
            let buffer = '';

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;
                
                buffer += decoder.decode(value, { stream: true });
                const parts = buffer.split('\n\n');
                buffer = parts.pop() || ''; 
                
                for (const line of parts) {
                    if (line.startsWith('data: ')) {
                        const jsonStr = line.replace('data: ', '').trim();
                        try {
                            const data = JSON.parse(jsonStr);
                            
                            if (data.type === 'text') {
                                if (aiTextAccumulated === '' && aiThoughtAccumulated !== '') {
                                    setIsThinkingExpanded(prev => ({ ...prev, [newAiMsgId]: false }));
                                }
                                aiTextAccumulated += data.content;
                                setMessages(prev => prev.map(m => m.id === newAiMsgId ? { ...m, text: aiTextAccumulated, isSearching: false } : m));
                            } 
                            else if (data.type === 'thinking') {
                                aiThoughtAccumulated += data.content;
                                setMessages(prev => prev.map(m => m.id === newAiMsgId ? { ...m, thought: aiThoughtAccumulated } : m));
                            }
                            else if (data.type === 'search') {
                                setMessages(prev => prev.map(m => m.id === newAiMsgId ? { ...m, isSearching: true } : m));
                            }
                            else if (data.type === 'status' && data.status === 'tts') {
                                setMessages(prev => prev.map(m => m.id === newAiMsgId ? { ...m, isGeneratingAudio: true } : m));
                            }
                            else if (data.type === 'audio') {
                                setMessages(prev => prev.map(m => m.id === newAiMsgId ? { ...m, audio: data.audio, isGeneratingAudio: false } : m));
                                const tempMsg = { ...newAiMsg, text: aiTextAccumulated, audio: data.audio };
                                playAudio(tempMsg);
                            }
                            else if (data.type === 'status' && data.ttsSkipped) {
                                setMessages(prev => prev.map(m => m.id === newAiMsgId ? { ...m, isGeneratingAudio: false } : m));
                                if (aiTextAccumulated) {
                                    const tempMsg = { ...newAiMsg, text: aiTextAccumulated };
                                    playAudio(tempMsg);
                                }
                            }
                            else if (data.type === 'error') {
                                setMessages(prev => prev.map(m => m.id === newAiMsgId ? { ...m, text: `⚠️ 错误: ${data.message}`, isGeneratingAudio: false, isSearching: false } : m));
                            }
                        } catch (e) {}
                    }
                }
            }

        } catch (error: any) {
            if (error.name !== 'AbortError') {
                setMessages(prev => prev.map(m => m.id === newAiMsgId ? { ...m, text: '抱歉，连接断开或发生错误。', isSearching: false } : m));
            }
        } finally { 
            setMessages(prev => prev.map(m => m.id === newAiMsgId ? { ...m, isSearching: false, isGeneratingAudio: false } : m));
            setIsChatProcessing(false);
            abortControllerRef.current = null;
        }
    };

    const clearHistory = () => {
        setMessages([{ id: 'welcome', role: 'model', text: '你好！我是你的 AI 智能助教。', timestamp: Date.now() }]);
    };

    return (
        <div className="flex-1 flex flex-col max-w-4xl mx-auto w-full min-h-0 relative overflow-hidden h-full">
            {toast.show && <Toast message={toast.message} type={toast.type} onClose={()=>setToast({...toast, show: false})}/>}
            
            <div className="absolute top-2 right-4 z-10 flex gap-2">
                <button onClick={clearHistory} className="text-xs text-gray-400 hover:text-red-500 flex items-center gap-1 bg-white/80 p-1.5 rounded-lg border border-transparent hover:border-red-100 transition-all shadow-sm backdrop-blur">
                    <Trash2 size={14}/> 清除
                </button>
            </div>
            
            <div ref={scrollContainerRef} className="flex-1 overflow-y-auto p-4 space-y-4 pb-4 custom-scrollbar">
                {messages.map(msg => (
                    <div key={msg.id} className={`flex gap-3 ${msg.role === 'user' ? 'flex-row-reverse' : ''}`}>
                        <div className={`w-10 h-10 rounded-full flex items-center justify-center shrink-0 ${msg.role === 'model' ? 'bg-blue-100 text-blue-600' : 'bg-gray-200 text-gray-600'}`}>
                            {msg.role === 'model' ? <Sparkles size={20}/> : <Bot size={20}/>}
                        </div>
                        <div className={`max-w-[85%] flex flex-col items-start ${msg.role === 'user' ? 'items-end' : ''}`}>
                            {msg.role === 'model' && msg.thought && (
                                <div className="w-full bg-purple-50 rounded-xl border border-purple-100 overflow-hidden mb-2 max-w-full">
                                    <button 
                                        onClick={() => setIsThinkingExpanded(prev => ({ ...prev, [msg.id]: !prev[msg.id] }))}
                                        className="w-full px-4 py-2 flex items-center gap-2 text-xs font-bold text-purple-700 bg-purple-100/50 hover:bg-purple-100 transition-colors"
                                    >
                                        <Brain size={14}/> 
                                        <span>深度思考过程</span>
                                        <div className="ml-auto text-xs opacity-50">{isThinkingExpanded[msg.id] ? '收起' : '展开'}</div>
                                    </button>
                                    {isThinkingExpanded[msg.id] && (
                                        <div className="p-4 text-xs text-purple-800 whitespace-pre-wrap leading-relaxed border-t border-purple-100 font-mono bg-white/50">
                                            {msg.thought}
                                        </div>
                                    )}
                                </div>
                            )}
                            
                            {msg.role === 'model' && msg.isSearching && (
                                <div className="flex items-center gap-2 bg-blue-50 text-blue-600 px-3 py-2 rounded-xl mb-2 text-xs border border-blue-100 animate-pulse w-fit">
                                    <Globe size={14} className="animate-spin"/>
                                    <span>正在联网搜索相关信息...</span>
                                </div>
                            )}
                            <div className={`p-3 rounded-2xl text-sm overflow-hidden shadow-sm ${msg.role === 'user' ? 'bg-blue-600 text-white rounded-tr-none' : 'bg-white border border-gray-200 text-gray-800 rounded-tl-none'}`}>
                                {msg.images && msg.images.length > 0 && (
                                    <div className="flex gap-2 mb-2 flex-wrap">
                                        {msg.images.map((img, i) => (
                                            <img key={i} src={`data:image/jpeg;base64,${img}`} className="max-w-[150px] max-h-[150px] rounded-lg object-cover border border-white/20" alt="sent" />
                                        ))}
                                    </div>
                                )}
                                <div className="markdown-body"><ReactMarkdown remarkPlugins={[remarkGfm]}>{msg.text || ''}</ReactMarkdown></div>
                                
                                {msg.role === 'model' && !msg.text && !msg.isSearching && isChatProcessing && (
                                    <div className="flex items-center gap-2 text-gray-400 py-1">
                                        <Loader2 className="animate-spin" size={14}/><span className="text-xs">思考中...</span>
                                    </div>
                                )}
                                
                                {msg.isGeneratingAudio && (
                                    <div className="flex items-center gap-2 text-blue-600 py-1 mt-1 bg-blue-50 px-2 rounded-lg w-fit animate-pulse">
                                        <Loader2 className="animate-spin" size={12}/>
                                        <span className="text-[10px] font-bold">正在合成语音...</span>
                                    </div>
                                )}
                                
                                {(msg.role === 'model' && (msg.text || msg.audio) && !isChatProcessing && !msg.isGeneratingAudio) && (
                                    <div className="flex gap-2 mt-2">
                                        <button 
                                            onClick={() => playingMessageId === msg.id ? stopPlayback() : playAudio(msg)} 
                                            className={`flex items-center gap-2 text-xs px-3 py-1.5 rounded-full border transition-colors w-fit ${
                                                playingMessageId === msg.id 
                                                ? 'bg-blue-100 text-blue-600 border-blue-200 animate-pulse' 
                                                : 'bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200'
                                            }`}
                                        >
                                            {playingMessageId === msg.id ? <Square size={14} fill="currentColor"/> : <Volume2 size={14}/>}
                                            {playingMessageId === msg.id ? '朗读中...' : '朗读'}
                                        </button>
                                        <button 
                                            onClick={() => handleCopy(msg.text || '')} 
                                            className="flex items-center gap-2 text-xs px-3 py-1.5 rounded-full border bg-gray-50 text-gray-600 hover:bg-gray-100 border-gray-200 transition-colors w-fit"
                                            title="复制"
                                        >
                                            <Copy size={14}/>
                                        </button>
                                    </div>
                                )}
                            </div>
                        </div>
                    </div>
                ))}
                <div ref={messagesEndRef} />
            </div>
            
            <div className="p-4 bg-white border-t border-gray-200 shrink-0 z-20">
                <div className="max-w-4xl mx-auto flex flex-col gap-2">
                    <div className="flex justify-between items-center px-1">
                        <div className="flex gap-3">
                            <button 
                                onClick={() => setEnableThinking(!enableThinking)}
                                className={`flex items-center gap-1 text-xs px-2 py-1 rounded-md border transition-all ${enableThinking ? 'bg-purple-50 text-purple-600 border-purple-200' : 'bg-gray-50 text-gray-500 border-transparent hover:bg-gray-100'}`}
                            >
                                <Brain size={14} className={enableThinking ? "fill-current" : ""}/> 深度思考
                            </button>
                            <button 
                                onClick={() => setEnableSearch(!enableSearch)}
                                className={`flex items-center gap-1 text-xs px-2 py-1 rounded-md border transition-all ${enableSearch ? 'bg-blue-50 text-blue-600 border-blue-200' : 'bg-gray-50 text-gray-500 border-transparent hover:bg-gray-100'}`}
                            >
                                <Globe size={14}/> 联网搜索
                            </button>
                        </div>
                    </div>
                    {(selectedImages.length > 0 || audioAttachment) && (
                        <div className="flex gap-2 overflow-x-auto pb-2">
                            {selectedImages.map((file, idx) => (
                                <div key={idx} className="relative w-16 h-16 shrink-0 group rounded-lg overflow-hidden border border-gray-200">
                                    <img src={URL.createObjectURL(file)} className="w-full h-full object-cover" />
                                    <button onClick={() => setSelectedImages(prev => prev.filter((_, i) => i !== idx))} className="absolute top-0.5 right-0.5 bg-black/50 text-white rounded-full p-0.5 hover:bg-red-500"><X size={12}/></button>
                                </div>
                            ))}
                            {audioAttachment && (
                                <div className="relative h-16 px-3 bg-blue-50 border border-blue-200 rounded-lg flex items-center justify-center shrink-0 min-w-[80px]">
                                    <div className="text-blue-600 flex flex-col items-center">
                                        <Volume2 size={20}/>
                                        <span className="text-[10px] font-bold">语音已录制</span>
                                    </div>
                                    <button onClick={() => setAudioAttachment(null)} className="absolute top-0.5 right-0.5 bg-gray-300 text-white rounded-full p-0.5 hover:bg-red-500"><X size={12}/></button>
                                </div>
                            )}
                        </div>
                    )}
                    <div className="flex items-end gap-2 bg-gray-100 p-2 rounded-2xl border border-gray-200">
                        <div className="flex items-center">
                            <button onClick={() => fileInputRef.current?.click()} className="p-2 text-gray-500 hover:bg-white hover:text-blue-600 rounded-full transition-colors shrink-0" title="相册/文件">
                                <ImageIcon size={22}/>
                            </button>
                            {isMobile && (
                                <button onClick={() => cameraInputRef.current?.click()} className="p-2 text-gray-500 hover:bg-white hover:text-blue-600 rounded-full transition-colors shrink-0" title="拍照">
                                    <Camera size={22}/>
                                </button>
                            )}
                        </div>
                        
                        <input 
                            type="file" 
                            multiple 
                            accept="image/*" 
                            ref={fileInputRef} 
                            className="hidden" 
                            onChange={handleImageSelect}
                            onClick={(e) => (e.currentTarget.value = '')} 
                        />
                        
                        {isMobile && (
                            <input 
                                type="file" 
                                accept="image/*" 
                                capture="environment"
                                ref={cameraInputRef} 
                                className="hidden" 
                                onChange={handleImageSelect}
                                onClick={(e) => (e.currentTarget.value = '')} 
                            />
                        )}

                        <div className="flex-1 min-h-[40px] flex items-center">
                            {audioAttachment ? (
                                <div className="w-full text-center text-sm text-gray-400 italic bg-transparent">
                                    语音消息已就绪 (文字输入已禁用)
                                </div>
                            ) : (
                                <textarea 
                                    className="w-full bg-transparent border-none outline-none text-sm resize-none max-h-24 py-2" 
                                    placeholder="输入文字..." 
                                    rows={1}
                                    value={textInput} 
                                    onChange={e => setTextInput(e.target.value)}
                                    onKeyDown={e => {
                                        if (e.key === 'Enter' && !e.shiftKey) {
                                            e.preventDefault();
                                            handleSubmit();
                                        }
                                    }}
                                />
                            )}
                        </div>
                        {isChatProcessing ? (
                            <button onClick={handleStopGeneration} className="p-2 bg-red-500 text-white rounded-full hover:bg-red-600 transition-all shrink-0 shadow-sm animate-pulse" title="停止生成">
                                <Square size={20} fill="currentColor"/>
                            </button>
                        ) : ((textInput.trim() || audioAttachment || selectedImages.length > 0) ? (
                            <button 
                                onClick={handleSubmit} 
                                // FIX: Add onMouseDown/onTouchEnd to prevent focus loss issues on mobile
                                onMouseDown={(e) => e.preventDefault()}
                                onTouchEnd={(e) => { e.preventDefault(); handleSubmit(); }}
                                type="button"
                                className="p-2 bg-blue-600 text-white rounded-full hover:bg-blue-700 transition-all shrink-0 shadow-sm disabled:opacity-50"
                            >
                                <Send size={20}/>
                            </button>
                        ) : (
                            <button 
                                onMouseDown={startRecording} 
                                onMouseUp={stopRecording} 
                                onTouchStart={startRecording} 
                                onTouchEnd={stopRecording}
                                onContextMenu={(e) => { e.preventDefault(); e.stopPropagation(); }} 
                                className={`p-2 rounded-full transition-all shrink-0 select-none ${isRecording ? 'bg-red-500 text-white scale-110 shadow-lg ring-4 ring-red-200' : 'bg-gray-200 text-gray-600 hover:bg-gray-300'}`}
                            >
                                {isRecording ? <StopCircle size={22}/> : <Mic size={22}/>}
                            </button>
                        ))}
                    </div>
                    {isRecording && <div className="text-center text-xs text-red-500 font-bold animate-pulse">正在录音... 松开发送到输入框</div>}
                </div>
            </div>
        </div>
    );
};
