import React, { useRef, useEffect, useState } from 'react';
import { MessageSquare, Send, ClipboardList, Activity, Mic, Volume2, Camera, X, ArrowLeft, Sparkles, ScanEye, Zap, Server, Plus, Trash2, Edit2, MessageCircle, Save, Loader2, ArrowDown } from 'lucide-react';
import { ChatMessage, AppMode, ChatSession } from '../types';
import { generateQuickReplies, generateSpeech } from '../services/geminiService';

interface ChatProps {
sessions: ChatSession[];
currentSessionId: string;
onSwitchSession: (id: string) => void;
onCreateSession: () => void;
onRenameSession: (id: string, newName: string) => void;
onDeleteSession: (id: string) => void;
onSendMessage: (input: string, image?: string) => void;
isProcessing: boolean;
statusMessage?: string; // New prop for transparency
mode: AppMode;
setMode: (mode: AppMode) => void;
onSummarize: () => void;
isSummarizing: boolean;
chatSummary?: string;
}

const Chat: React.FC<ChatProps> = ({
sessions,
currentSessionId,
onSwitchSession,
onCreateSession,
onRenameSession,
onDeleteSession,
onSendMessage,
isProcessing,
statusMessage,
mode,
setMode,
onSummarize,
isSummarizing,
chatSummary
}) => {
const scrollRef = useRef<HTMLDivElement>(null);
const containerRef = useRef<HTMLDivElement>(null);
const fileInputRef = useRef<HTMLInputElement>(null);
const editInputRef = useRef<HTMLInputElement>(null);
const [currentInput, setCurrentInput] = useState('');
const [isListening, setIsListening] = useState(false);

// TTS State
const [speakingId, setSpeakingId] = useState<string | null>(null);
const [isGeneratingAudio, setIsGeneratingAudio] = useState<string | null>(null);
const audioContextRef = useRef<AudioContext | null>(null);
const sourceNodeRef = useRef<AudioBufferSourceNode | null>(null);

const [viewMode, setViewMode] = useState<'chat' | 'summary'>('chat');
const [selectedImage, setSelectedImage] = useState<string | null>(null);
const [quickReplies, setQuickReplies] = useState<string[]>([]);
const [showVisionTip, setShowVisionTip] = useState(true);
const [showScrollDown, setShowScrollDown] = useState(false);
const [showSidebar, setShowSidebar] = useState(false);
const [editingSessionId, setEditingSessionId] = useState<string | null>(null);
const [editName, setEditName] = useState('');

const currentSession = sessions.find(s => s.id === currentSessionId) || sessions[0];
const chatHistory = currentSession?.messages || [];

// RESOURCE MANAGEMENT: Stop Audio on Page Hide
useEffect(() => {
const handleVisibilityChange = () => {
if (document.hidden) {
stopAudio();
}
};
document.addEventListener('visibilitychange', handleVisibilityChange);
return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
}, []);

// SCROLL LOGIC
const scrollToBottom = (smooth = true) => {
if (scrollRef.current) {
scrollRef.current.scrollIntoView({ behavior: smooth ? 'smooth' : 'auto' });
}
};

const handleScroll = () => {
if (!containerRef.current) return;
const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
const isNotAtBottom = scrollHeight - scrollTop - clientHeight > 300;
setShowScrollDown(isNotAtBottom);
};

useEffect(() => {
scrollToBottom();
}, [chatHistory, isProcessing, quickReplies]);

useEffect(() => {
if (chatHistory.length > 0 && !isProcessing) {
generateQuickReplies(chatHistory).then(setQuickReplies);
} else if (isProcessing) {
setQuickReplies([]);
}
}, [chatHistory, isProcessing]);

useEffect(() => {
if (editingSessionId && editInputRef.current) {
editInputRef.current.focus();
}
}, [editingSessionId]);

const handleSummarizeClick = async () => {
await onSummarize();
setViewMode('summary');
};

const handleImageSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onloadend = () => {
setSelectedImage(reader.result as string);
};
reader.readAsDataURL(file);
setShowVisionTip(false);
}
};

const handleSend = () => {
if (!currentInput.trim() && !selectedImage) return;
onSendMessage(currentInput, selectedImage || undefined);
setCurrentInput('');
setSelectedImage(null);
setQuickReplies([]);
};

// --- TTS ENGINE ---
const stopAudio = () => {
if (sourceNodeRef.current) {
sourceNodeRef.current.stop();
sourceNodeRef.current = null;
}
if ('speechSynthesis' in window) {
window.speechSynthesis.cancel();
}
setSpeakingId(null);
};

const browserTTS = (text: string, id: string) => {
if ('speechSynthesis' in window) {
const speak = () => {
const utterance = new SpeechSynthesisUtterance(text);
const voices = window.speechSynthesis.getVoices();

const maleVoice = voices.find(v => 
           v.name.includes('Google US English Male') || 
           v.name.includes('Microsoft David') || 
           v.name.includes('Daniel') ||
           (v.name.includes('Male') && v.lang.includes('en'))
       );
       const anyEnglish = voices.find(v => v.lang.includes('en-US'));

       if (maleVoice) utterance.voice = maleVoice;
       else if (anyEnglish) utterance.voice = anyEnglish;
       
       utterance.rate = 1.05; 
       utterance.pitch = 0.95;

       utterance.onend = () => setSpeakingId(null);
       utterance.onerror = () => setSpeakingId(null);
       setSpeakingId(id);
       window.speechSynthesis.speak(utterance);
   };

   if (window.speechSynthesis.getVoices().length === 0) {
       window.speechSynthesis.onvoiceschanged = speak;
   } else {
       speak();
   }
} else {
   alert("TTS not supported.");
}
};

const speakText = async (text: string, id: string) => {
if (speakingId === id) {
stopAudio();
return;
}
stopAudio();
setIsGeneratingAudio(id);

try {
    const timeoutPromise = new Promise((_, reject) => 
        setTimeout(() => reject(new Error("Timeout")), 8000)
    );

    const base64Audio = await Promise.race([
        generateSpeech(text),
        timeoutPromise
    ]);
    
    if (base64Audio && typeof base64Audio === 'string') {
        const binaryString = window.atob(base64Audio);
        const len = binaryString.length;
        const bytes = new Uint8Array(len);
        for (let i = 0; i < len; i++) {
            bytes[i] = binaryString.charCodeAt(i);
        }

        if (!audioContextRef.current) {
            audioContextRef.current = new (window.AudioContext || (window as any).webkitAudioContext)({ sampleRate: 24000 });
        }
        
        const audioBuffer = await audioContextRef.current.decodeAudioData(bytes.buffer);
        const source = audioContextRef.current.createBufferSource();
        source.buffer = audioBuffer;
        source.connect(audioContextRef.current.destination);
        
        source.onended = () => setSpeakingId(null);
        source.start(0);
        
        sourceNodeRef.current = source;
        setSpeakingId(id);
    } else {
        throw new Error("No audio returned");
    }
} catch (e) {
    console.warn("TTS Fallback used.");
    browserTTS(text, id);
} finally {
    setIsGeneratingAudio(null);
}
};

const toggleListening = () => {
if (!('webkitSpeechRecognition' in window)) {
alert("Voice input is not supported in this browser.");
return;
}
if (isListening) {
setIsListening(false);
return;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const recognition = new (window as any).webkitSpeechRecognition();
recognition.continuous = false;
recognition.interimResults = false;
recognition.lang = 'en-US';

recognition.onstart = () => setIsListening(true);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
recognition.onresult = (event: any) => {
const transcript = event.results[0][0].transcript;
setCurrentInput(transcript);
setIsListening(false);
};
recognition.onerror = () => setIsListening(false);
recognition.onend = () => setIsListening(false);
recognition.start();
};

const startEditing = (session: ChatSession) => {
setEditingSessionId(session.id);
setEditName(session.name);
};

const saveSessionName = () => {
if (editingSessionId && editName.trim()) {
onRenameSession(editingSessionId, editName.trim());
}
setEditingSessionId(null);
};

if (viewMode === 'summary') {
return (
<div className="animate-in fade-in slide-in-from-bottom-4 duration-500 h-full flex flex-col pt-16 md:pt-0">
<div className="glass-panel rounded-2xl flex-1 p-8 flex flex-col relative overflow-hidden">
<div className="absolute top-0 right-0 w-96 h-96 bg-neon-green/5 rounded-full blur-3xl -z-10 pointer-events-none"></div>
<div className="flex justify-between items-center mb-6 border-b border-white/10 pb-4">
<button onClick={() => setViewMode('chat')} className="flex items-center gap-2 text-gray-400 hover:text-white transition-colors text-sm font-mono font-bold uppercase"><ArrowLeft size={16} /> Back to Chat</button>
<h2 className="text-xl font-bold text-white flex items-center gap-2"><ClipboardList className="text-neon-yellow" /> Session Brief</h2>
</div>
<div className="flex-1 overflow-y-auto">
{isSummarizing ? (
<div className="flex flex-col items-center justify-center h-64 text-gray-500 gap-4"><Activity className="animate-spin text-neon-green" size={32} /><p className="font-mono text-xs animate-pulse">ANALYZING CONVERSATION...</p></div>
) : (
<div className="bg-white/5 p-6 rounded-xl border border-white/10 leading-relaxed text-gray-200 text-base whitespace-pre-wrap">{chatSummary || "No summary available."}</div>
)}
</div>
</div>
</div>
);
}

// --- RESPONSIVE LAYOUT ---
return (
<div className="flex gap-4 h-[calc(100vh-140px)] md:h-[calc(100vh-6rem)] animate-in fade-in slide-in-from-bottom-4 duration-500 relative">
  {/* SESSIONS SIDEBAR */}
  <div className={`w-64 glass-panel rounded-2xl flex flex-col transition-all duration-300 ${showSidebar ? 'absolute z-50 h-full left-0 bg-black/95 border-r border-white/20' : 'hidden md:flex'}`}>
     <div className="p-4 border-b border-white/5 flex justify-between items-center">
        <button onClick={onCreateSession} className="flex-1 flex items-center justify-center gap-2 bg-neon-blue/10 text-neon-blue hover:bg-neon-blue/20 py-2 rounded-xl font-bold text-xs transition-colors border border-neon-blue/30">
           <Plus size={14} /> New Chat
        </button>
        {showSidebar && <button onClick={() => setShowSidebar(false)} className="md:hidden p-2 text-gray-500 hover:text-white ml-2"><X size={16}/></button>}
     </div>
     <div className="flex-1 overflow-y-auto p-2 space-y-1">
        {sessions.map(s => (
           <div key={s.id} className={`group flex items-center gap-2 p-2 rounded-lg cursor-pointer transition-all ${s.id === currentSessionId ? 'bg-white/10 text-white' : 'text-gray-400 hover:bg-white/5 hover:text-gray-200'}`} onClick={() => { onSwitchSession(s.id); setShowSidebar(false); }}>
              <MessageCircle size={14} className={s.id === currentSessionId ? 'text-neon-green' : 'opacity-50'} />
              {editingSessionId === s.id ? (
                 <div className="flex-1 flex items-center gap-1" onClick={e => e.stopPropagation()}>
                    <input 
                      ref={editInputRef}
                      className="w-full bg-black/50 border border-neon-blue/50 rounded px-1 text-xs outline-none text-white"
                      value={editName}
                      onChange={e => setEditName(e.target.value)}
                      onKeyDown={e => e.key === 'Enter' && saveSessionName()}
                    />
                    <button onClick={saveSessionName} className="text-neon-green hover:text-white p-1"><Save size={12}/></button>
                 </div>
              ) : (
                 <span className="flex-1 text-xs truncate font-medium">{s.name}</span>
              )}
              
              {s.id === currentSessionId && !editingSessionId && (
                 <div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
                    <button onClick={(e) => { e.stopPropagation(); startEditing(s); }} className="p-1 hover:text-white"><Edit2 size={10} /></button>
                    <button onClick={(e) => { e.stopPropagation(); onDeleteSession(s.id); }} className="p-1 hover:text-red-400"><Trash2 size={10} /></button>
                 </div>
              )}
           </div>
        ))}
     </div>
  </div>
  {/* CHAT AREA */}
  <div className="flex-1 glass-panel rounded-2xl flex flex-col relative overflow-hidden min-h-0">
    
    {/* FIXED HEADER FOR MOBILE */}
    <div className="absolute top-0 left-0 right-0 bg-black/80 backdrop-blur-md border-b border-white/10 p-3 z-40 flex justify-between items-center md:static md:bg-white/5 md:border-white/5 md:p-4">
      <div className="flex items-center gap-3">
         <button onClick={() => setShowSidebar(!showSidebar)} className="md:hidden p-2 bg-white/10 rounded-lg text-gray-300 hover:bg-white/20"><MessageSquare size={18}/></button>
         <div className="flex gap-2">
            <button onClick={() => setMode(AppMode.GENERAL)} className={`px-2 py-1.5 md:px-3 rounded-lg text-[10px] md:text-xs font-mono font-bold uppercase tracking-wider transition-all ${mode === AppMode.GENERAL ? 'bg-neon-blue text-black' : 'text-gray-400 hover:text-white bg-white/5'}`}>Medical Guide</button>
            <button onClick={() => setMode(AppMode.THERAPY)} className={`px-2 py-1.5 md:px-3 rounded-lg text-[10px] md:text-xs font-mono font-bold uppercase tracking-wider transition-all ${mode === AppMode.THERAPY ? 'bg-purple-500 text-white' : 'text-gray-400 hover:text-white bg-white/5'}`}>Therapist</button>
         </div>
      </div>
      <button onClick={handleSummarizeClick} disabled={chatHistory.length === 0} className="flex items-center gap-2 px-3 py-1.5 md:px-4 md:py-2 rounded-lg text-xs font-mono font-bold transition-all border border-white/10 text-gray-300 hover:text-white hover:border-white/30 bg-white/5 disabled:opacity-50">
        <ClipboardList size={16} /> <span className="hidden md:inline">BRIEF</span>
      </button>
    </div>
    {/* MESSAGES */}
    <div 
        className="flex-1 overflow-y-auto p-4 md:p-6 space-y-6 relative scroll-smooth pt-16 md:pt-4" 
        ref={containerRef}
        onScroll={handleScroll}
    >
      {chatHistory.length === 0 && (
        <div className="flex flex-col items-center justify-center h-full text-gray-600">
           <div className="p-4 rounded-full bg-white/5 mb-4 relative">
              <div className="absolute -top-1 -right-1 w-3 h-3 bg-neon-green rounded-full animate-pulse"></div>
              <MessageSquare size={32} className="opacity-50" />
           </div>
           <p className="font-medium text-lg">Start a session with SomAI.</p>
           <p className="text-xs mt-2 opacity-50 flex items-center gap-2"><span className="flex items-center gap-1"><ScanEye size={12}/> Vision Enabled</span> • <span>Secure</span> • <span>Private</span></p>
        </div>
      )}
      
      {chatHistory.map((msg) => (
        <div key={msg.id} className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}>
          <div className={`max-w-[85%] md:max-w-[75%] rounded-2xl px-5 py-3 shadow-lg relative group ${
            msg.role === 'user' 
              ? 'bg-neon-green/10 text-white border border-neon-green/20 rounded-tr-none' 
              : 'bg-black/40 text-gray-200 border border-white/10 rounded-tl-none'
          }`}>
            {msg.image && (
              <div className="mb-3 rounded-lg overflow-hidden border border-white/10">
                <img src={msg.image} alt="Upload" className="max-w-full h-auto max-h-64 object-cover" />
              </div>
            )}
            <p className="text-sm leading-relaxed whitespace-pre-wrap">{msg.text}</p>
            {msg.role === 'model' && msg.modelUsed && (
               <div className="mt-2 flex items-center gap-1.5 opacity-50 text-[10px] font-mono">
                  {msg.modelUsed.includes('Gemini') ? <><Zap size={10} className="text-neon-yellow"/> {msg.modelUsed}</> : <><Server size={10} className="text-neon-red"/> {msg.modelUsed}</>}
               </div>
            )}
            
            {msg.role === 'model' && !isProcessing && (
              <button 
                onClick={() => speakText(msg.text, msg.id)}
                className={`absolute -right-10 top-2 p-2 rounded-full hover:bg-white/10 transition-all ${speakingId === msg.id ? 'text-neon-blue opacity-100' : 'text-gray-500 opacity-0 group-hover:opacity-100'}`}
                disabled={isGeneratingAudio === msg.id}
              >
                 {isGeneratingAudio === msg.id ? <Loader2 size={16} className="animate-spin text-neon-blue" /> : <Volume2 size={16} className={speakingId === msg.id ? "animate-pulse" : ""} />}
              </button>
            )}
          </div>
        </div>
      ))}
      
      {/* LOADING INDICATOR */}
      {isProcessing && (
         <div className="flex justify-start animate-in fade-in slide-in-from-bottom-2">
            <div className="bg-black/40 border border-white/10 rounded-2xl rounded-tl-none px-5 py-3 flex items-center gap-3">
               <div className="flex gap-1">
                  <div className="w-2 h-2 bg-neon-green rounded-full animate-bounce [animation-delay:-0.3s]"></div>
                  <div className="w-2 h-2 bg-neon-green rounded-full animate-bounce [animation-delay:-0.15s]"></div>
                  <div className="w-2 h-2 bg-neon-green rounded-full animate-bounce"></div>
               </div>
               {statusMessage && <span className="text-xs text-gray-400 font-mono animate-pulse">{statusMessage}</span>}
            </div>
         </div>
      )}
      <div ref={scrollRef}></div>
    </div>

    {showScrollDown && (
        <button 
            onClick={() => scrollToBottom()}
            className="absolute bottom-32 right-6 z-30 p-3 rounded-full bg-neon-green text-black shadow-lg hover:bg-white transition-all animate-bounce"
            title="Scroll to bottom"
        >
            <ArrowDown size={20} />
        </button>
    )}

    {/* Quick Replies */}
    {!isProcessing && quickReplies.length > 0 && (
      <div className="px-4 pb-2 flex gap-2 overflow-x-auto scrollbar-hide shrink-0">
        {quickReplies.map((reply, i) => (
          <button key={i} onClick={() => { setCurrentInput(reply); handleSend(); }} className="whitespace-nowrap px-3 py-1.5 rounded-full bg-white/5 border border-white/10 text-xs text-gray-300 hover:bg-neon-blue/20 hover:text-neon-blue hover:border-neon-blue/30 transition-all flex items-center gap-1">
            <Sparkles size={10} /> {reply}
          </button>
        ))}
      </div>
    )}

    <div className="p-4 bg-black/50 border-t border-white/5 z-20 relative shrink-0">
      {showVisionTip && !selectedImage && (
         <div className="absolute -top-12 left-4 z-30 animate-in fade-in slide-in-from-bottom-2">
            <div className="bg-neon-blue/10 backdrop-blur-md border border-neon-blue/30 text-neon-blue text-[10px] md:text-xs px-3 py-2 rounded-lg shadow-lg flex items-center gap-2">
               <ScanEye size={14} /><span><span className="font-bold">SomAI Vision:</span> Upload nutrition labels, skin symptoms, or reports for analysis.</span>
               <button onClick={() => setShowVisionTip(false)} className="hover:text-white ml-2"><X size={12}/></button>
            </div>
            <div className="absolute -bottom-1 left-4 w-2 h-2 bg-neon-blue/10 border-b border-r border-neon-blue/30 transform rotate-45"></div>
         </div>
      )}
      {selectedImage && (
        <div className="flex items-center gap-2 mb-3 bg-white/5 p-2 rounded-lg w-fit border border-white/10">
           <div className="w-8 h-8 rounded bg-gray-800 overflow-hidden"><img src={selectedImage} alt="Selected" className="w-full h-full object-cover" /></div>
           <span className="text-xs text-gray-400">Image attached</span>
           <button onClick={() => setSelectedImage(null)} className="p-1 hover:bg-white/10 rounded-full text-gray-500 hover:text-white ml-2"><X size={14} /></button>
        </div>
      )}
      <div className="flex items-center gap-3">
        <input type="file" accept="image/*" className="hidden" ref={fileInputRef} onChange={handleImageSelect} />
        <button onClick={() => fileInputRef.current?.click()} className={`p-3 rounded-xl transition-all relative ${selectedImage ? 'bg-neon-blue/20 text-neon-blue' : 'bg-white/5 text-gray-400 hover:text-white hover:bg-white/10'}`} title="SomAI Vision"><Camera size={20} /></button>
        <div className="flex-1 relative">
           <input value={currentInput} onChange={(e) => setCurrentInput(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleSend()} placeholder={isListening ? "Listening..." : "Message SomAI..."} className="w-full bg-black/40 border border-white/10 rounded-xl py-3 pl-4 pr-10 text-white placeholder-gray-600 focus:border-neon-blue outline-none transition-all" />
           <button onClick={toggleListening} className={`absolute right-2 top-1/2 -translate-y-1/2 p-1.5 rounded-lg transition-all ${isListening ? 'text-red-500 animate-pulse' : 'text-gray-500 hover:text-white'}`}><Mic size={18} /></button>
        </div>
        <button onClick={handleSend} disabled={(!currentInput.trim() && !selectedImage) || isProcessing} className="p-3 rounded-xl bg-neon-blue text-black font-bold hover:bg-neon-blue/90 transition-all disabled:opacity-50 disabled:cursor-not-allowed shadow-[0_0_15px_rgba(0,204,255,0.3)]"><Send size={20} /></button>
      </div>
    </div>
  </div>
</div>
);
};

export default Chat;