

import React, { useState, useRef, useEffect } from 'react';
import { ChatMessage, Role, MessageType, Language, ChatSession } from '../types';
import { geminiService } from '../services/geminiService';
import ChatBubble from '../components/ChatBubble';
import AudioRecorder from '../components/AudioRecorder';
import { Send, Image as ImageIcon, BrainCircuit, Loader2, Plus, History, MessageSquare, Trash2, X, Sparkles, PanelRightClose, PanelRightOpen, Share2, Download, FileText, Image as ImageIconLucide, Languages } from 'lucide-react';
import { translations } from '../utils/localization';
import html2canvas from 'html2canvas';

interface ChatViewProps {
  language: Language;
  sessions: ChatSession[];
  activeSessionId: string;
  onNewSession: () => void;
  onSelectSession: (id: string) => void;
  onDeleteSession: (id: string) => void;
  onClearAllSessions: () => void;
  onUpdateSession: (id: string, messages: ChatMessage[]) => void;
  selectedModel?: string;
  addToast: (type: 'success' | 'error' | 'info', msg: string) => void;
}

const ChatView: React.FC<ChatViewProps> = ({ 
  language, 
  sessions, 
  activeSessionId, 
  onNewSession, 
  onSelectSession, 
  onDeleteSession,
  onClearAllSessions,
  onUpdateSession,
  selectedModel,
  addToast
}) => {
  const t = translations[language].chat;
  const tCommon = translations[language].common;

  const activeSession = sessions.find(s => s.id === activeSessionId) || sessions[0];
  const messages = activeSession ? activeSession.messages : [];

  const [inputValue, setInputValue] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [useThinking, setUseThinking] = useState(false);
  const [attachedImage, setAttachedImage] = useState<string | null>(null);
  
  // Settings State
  const [aiSpeakingLanguage, setAiSpeakingLanguage] = useState<'ja' | 'native'>('ja');
  const [isShareMenuOpen, setIsShareMenuOpen] = useState(false);
  
  // History Sidebar State - Default Closed as requested
  const [isHistoryOpen, setIsHistoryOpen] = useState(false);

  const messagesEndRef = useRef<HTMLDivElement>(null);
  const messagesContainerRef = useRef<HTMLDivElement>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

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

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

  // Close share menu on click outside
  useEffect(() => {
      const handleClick = () => setIsShareMenuOpen(false);
      if (isShareMenuOpen) window.addEventListener('click', handleClick);
      return () => window.removeEventListener('click', handleClick);
  }, [isShareMenuOpen]);

  const handleUpdateMessage = (updatedMsg: ChatMessage) => {
      const updatedMessages = messages.map(m => m.id === updatedMsg.id ? updatedMsg : m);
      onUpdateSession(activeSessionId, updatedMessages);
  };

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

    const currentText = inputValue;
    const currentImage = attachedImage;
    
    setInputValue('');
    setAttachedImage(null);
    setIsLoading(true);

    // 1. Construct User Message
    const userMsg: ChatMessage = {
      id: Date.now().toString(),
      role: Role.USER,
      type: MessageType.TEXT,
      content: currentText,
      timestamp: Date.now(),
      metadata: { imageUrl: currentImage || undefined }
    };

    // IMPORTANT: Calculate new history locally to avoid stale closure issues after await
    const messagesWithUser = [...messages, userMsg];
    
    // Update UI immediately with user message
    onUpdateSession(activeSessionId, messagesWithUser);

    try {
      // 2. Get Response
      const result = await geminiService.generateTextResponse(
        currentText || "Describe this image", 
        currentImage || undefined, 
        useThinking,
        language,
        selectedModel,
        aiSpeakingLanguage
      );

      // 3. TTS (if short and not thinking)
      let ttsAudio: string | null = null;
      if (!useThinking && result.text.length < 300) {
        try { ttsAudio = await geminiService.generateSpeech(result.text); } catch (e) {}
      }

      const aiMsg: ChatMessage = {
        id: (Date.now() + 1).toString(),
        role: Role.MODEL,
        type: MessageType.TEXT,
        content: result.text,
        model: result.model,
        timestamp: Date.now(),
        metadata: { isThinking: useThinking, audioUrl: ttsAudio || undefined }
      };

      // 4. Add AI Message to the LOCALLY calculated history (messagesWithUser)
      // This ensures we don't lose the user message we just added
      onUpdateSession(activeSessionId, [...messagesWithUser, aiMsg]);

    } catch (error: any) {
      const errorMsg = error?.message || t.error;
      const errorMsgObj: ChatMessage = {
        id: Date.now().toString(),
        role: Role.MODEL,
        type: MessageType.TEXT,
        content: `${t.error}\n(${errorMsg})`,
        timestamp: Date.now()
      };
      onUpdateSession(activeSessionId, [...messagesWithUser, errorMsgObj]);
    } finally {
      setIsLoading(false);
      setUseThinking(false);
    }
  };

  const handleAudioInput = async (base64Audio: string) => {
    setIsLoading(true);
    try {
      // 1. Transcribe first (async)
      const transcription = await geminiService.transcribeAudio(base64Audio);
      
      const userMsg: ChatMessage = {
        id: Date.now().toString(),
        role: Role.USER,
        type: MessageType.AUDIO,
        content: `${t.transcribedPrefix}${transcription}`,
        timestamp: Date.now(),
        metadata: { audioUrl: base64Audio, transcription: transcription }
      };

      // 2. Update UI with User Message
      const messagesWithUser = [...messages, userMsg];
      onUpdateSession(activeSessionId, messagesWithUser);

      // 3. Generate AI Response
      const result = await geminiService.generateTextResponse(transcription, undefined, false, language, selectedModel, aiSpeakingLanguage);
      const ttsAudio = await geminiService.generateSpeech(result.text);

      const aiMsg: ChatMessage = {
        id: (Date.now() + 1).toString(),
        role: Role.MODEL,
        type: MessageType.TEXT,
        content: result.text,
        model: result.model,
        timestamp: Date.now(),
        metadata: { audioUrl: ttsAudio || undefined }
      };

      // 4. Update UI with AI Message using local history
      onUpdateSession(activeSessionId, [...messagesWithUser, aiMsg]);

    } catch (e) {
      console.error(e);
      addToast('error', t.error);
    } finally {
      setIsLoading(false);
    }
  };

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

  // Share Handlers
  const shareAsText = () => {
      const text = messages.map(m => `[${new Date(m.timestamp).toLocaleString()}] ${m.role === Role.USER ? 'User' : 'Sakura'}: ${m.content}`).join('\n\n');
      navigator.clipboard.writeText(text);
      addToast('success', tCommon.copied);
  };

  const shareAsFile = () => {
      const text = messages.map(m => `[${new Date(m.timestamp).toLocaleString()}] ${m.role === Role.USER ? 'User' : 'Sakura'}: ${m.content}`).join('\n\n');
      const blob = new Blob([text], { type: 'text/plain' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `sakura_chat_${Date.now()}.txt`;
      a.click();
      URL.revokeObjectURL(url);
  };

  const shareAsImage = async () => {
    if (!messagesContainerRef.current) return;
    addToast('info', 'Generating image...');
    
    // Clone the element to capture full content
    const original = messagesContainerRef.current;
    const clone = original.cloneNode(true) as HTMLElement;
    
    // We need to maintain the width to ensure text wrapping is identical
    const width = original.offsetWidth;
    
    clone.style.width = `${width}px`;
    clone.style.height = 'auto';
    clone.style.maxHeight = 'none';
    clone.style.overflow = 'visible';
    clone.style.position = 'absolute';
    clone.style.top = '-9999px';
    clone.style.left = '0';
    clone.style.background = '#f8fafc'; // Match bg-slate-50
    clone.style.zIndex = '-1';
    
    document.body.appendChild(clone);

    try {
        // Small delay to ensure DOM rendering
        await new Promise(resolve => setTimeout(resolve, 100));

        const canvas = await html2canvas(clone, {
            useCORS: true,
            scale: 2, // Higher res
            backgroundColor: '#f8fafc',
            windowWidth: width,
            height: clone.scrollHeight,
            windowHeight: clone.scrollHeight
        });
        
        const url = canvas.toDataURL('image/png');
        const a = document.createElement('a');
        a.href = url;
        a.download = `sakura_chat_${Date.now()}.png`;
        a.click();
    } catch (e) {
        console.error(e);
        addToast('error', 'Failed to generate image');
    } finally {
        if (document.body.contains(clone)) {
            document.body.removeChild(clone);
        }
    }
  };

  // --- Sub-components ---

  const HistoryContent = () => (
      <div className="flex flex-col h-full bg-white">
         <div className="p-4 border-b border-slate-100 flex items-center justify-between bg-slate-50/50">
            <h3 className="font-bold text-slate-700 flex items-center gap-2">
                <History size={18} className="text-indigo-500" /> {t.history}
            </h3>
            <div className="flex items-center gap-3">
                {sessions.length > 0 && (
                    <button onClick={onClearAllSessions} className="text-xs text-red-400 hover:text-red-600 hover:underline">
                        {translations[language].reading.clear}
                    </button>
                )}
                <button onClick={() => setIsHistoryOpen(false)} className="md:hidden text-slate-400 hover:text-slate-600">
                    <X size={20} />
                </button>
            </div>
         </div>
         
         <div className="p-4">
            <button 
                onClick={() => { onNewSession(); setIsHistoryOpen(false); }}
                className="w-full py-3 bg-indigo-600 text-white hover:bg-indigo-700 rounded-xl font-bold flex items-center justify-center gap-2 transition-all shadow-md hover:shadow-lg active:scale-95"
            >
                <Plus size={18} /> {t.newChat}
            </button>
         </div>

         <div className="flex-1 overflow-y-auto px-4 pb-20 space-y-3">
            {sessions.length === 0 && <div className="text-center text-slate-400 text-xs mt-4">{t.noHistory}</div>}
            {sessions.slice().sort((a,b) => b.updatedAt - a.updatedAt).map(session => (
                <div 
                    key={session.id}
                    className={`group flex items-start gap-3 p-3 rounded-xl border cursor-pointer relative transition-all ${
                        session.id === activeSessionId 
                        ? 'bg-indigo-50 border-indigo-200 shadow-sm' 
                        : 'bg-slate-50 border-slate-100 hover:bg-white hover:shadow-md'
                    }`}
                    onClick={() => { onSelectSession(session.id); if(window.innerWidth < 768) setIsHistoryOpen(false); }}
                >
                    {/* Icon */}
                    <div className={`w-10 h-10 rounded-xl flex-shrink-0 flex items-center justify-center ${session.id === activeSessionId ? 'bg-indigo-200 text-indigo-700' : 'bg-white text-slate-300 border border-slate-200'}`}>
                        <MessageSquare size={20} />
                    </div>

                    {/* Content */}
                    <div className="flex-1 min-w-0">
                        <div className="flex justify-between items-start">
                            <h4 className={`font-bold text-sm truncate pr-6 ${session.id === activeSessionId ? 'text-indigo-900' : 'text-slate-700'}`}>
                                {session.title || t.untitled}
                            </h4>
                        </div>
                        <div className="flex justify-between items-center mt-1">
                            <span className="text-[10px] text-slate-400">
                                {new Date(session.updatedAt).toLocaleDateString()} {new Date(session.updatedAt).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}
                            </span>
                        </div>
                         <p className="text-[10px] text-slate-400 line-clamp-1 mt-1">
                            {session.messages.length > 1 ? session.messages[session.messages.length-1].content.substring(0, 50) : '...'}
                        </p>
                    </div>

                    {/* Delete Button */}
                    <button 
                        onClick={(e) => { e.stopPropagation(); onDeleteSession(session.id); }}
                        className="absolute bottom-2 right-2 p-1.5 text-slate-300 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-opacity"
                        title={t.deleteChat}
                    >
                        <Trash2 size={14} />
                    </button>
                </div>
            ))}
         </div>
      </div>
  );

  return (
    <div className="flex h-full bg-slate-50 relative overflow-hidden">
      
      {/* MAIN CHAT AREA */}
      <div className="flex-1 flex flex-col h-full min-w-0 bg-slate-50/30 relative">
          
          {/* Header / Toolbar */}
          <div className="flex items-center justify-between px-4 py-3 bg-white/80 backdrop-blur border-b border-slate-200 z-20 sticky top-0">
              <div className="flex items-center gap-2 overflow-x-auto scrollbar-hide">
                   <div className="flex items-center gap-1.5 text-xs font-bold text-indigo-600 bg-indigo-50 px-2.5 py-1 rounded-lg border border-indigo-100 whitespace-nowrap">
                      <Sparkles size={12} />
                      {selectedModel ? selectedModel.replace('gemini-', '').replace('-preview', '') : 'AI'}
                  </div>
                  
                  {/* AI Language Toggle */}
                  <button 
                    onClick={() => setAiSpeakingLanguage(prev => prev === 'ja' ? 'native' : 'ja')}
                    className="flex items-center gap-1.5 text-xs font-bold text-slate-600 bg-white px-2.5 py-1 rounded-lg border border-slate-200 hover:bg-slate-50 whitespace-nowrap"
                    title={tCommon.aiLanguage}
                  >
                      <Languages size={12} />
                      {aiSpeakingLanguage === 'ja' ? tCommon.langJa : tCommon.langNative}
                  </button>
              </div>

              <div className="flex items-center gap-2">
                  {/* Share Button */}
                  <div className="relative">
                      <button 
                          onClick={(e) => { e.stopPropagation(); setIsShareMenuOpen(!isShareMenuOpen); }}
                          className="p-2 rounded-lg text-slate-500 hover:bg-slate-100 transition-colors"
                          title={tCommon.share}
                      >
                          <Share2 size={18} />
                      </button>
                      
                      {/* Share Dropdown */}
                      {isShareMenuOpen && (
                          <div className="absolute right-0 top-full mt-2 w-40 bg-white rounded-xl shadow-xl border border-slate-100 overflow-hidden animate-scale-in z-50">
                              <button onClick={shareAsImage} className="w-full text-left px-4 py-3 text-sm text-slate-700 hover:bg-slate-50 flex items-center gap-2">
                                  <ImageIconLucide size={16} /> {tCommon.shareImage}
                              </button>
                              <button onClick={shareAsText} className="w-full text-left px-4 py-3 text-sm text-slate-700 hover:bg-slate-50 flex items-center gap-2">
                                  <FileText size={16} /> {tCommon.shareText}
                              </button>
                              <button onClick={shareAsFile} className="w-full text-left px-4 py-3 text-sm text-slate-700 hover:bg-slate-50 flex items-center gap-2">
                                  <Download size={16} /> {tCommon.shareFile}
                              </button>
                          </div>
                      )}
                  </div>

                  {/* Toggle History Button */}
                  <button
                      onClick={() => setIsHistoryOpen(!isHistoryOpen)}
                      className={`p-2 rounded-lg border transition-colors flex items-center gap-2 text-sm font-medium ${
                          isHistoryOpen 
                          ? 'bg-indigo-50 text-indigo-600 border-indigo-200' 
                          : 'bg-white text-slate-600 border-slate-200 hover:bg-slate-50'
                      }`}
                      title={t.history}
                  >
                      <History size={18} />
                      <span className="hidden sm:inline">{t.history}</span>
                      {isHistoryOpen ? <PanelRightClose size={16} className="opacity-50" /> : <PanelRightOpen size={16} className="opacity-50" />}
                  </button>
              </div>
          </div>

          {/* Messages Scroll Area */}
          <div className="flex-1 overflow-y-auto p-4 sm:p-6 space-y-6" ref={messagesContainerRef}>
            {messages.length === 0 && (
                <div className="flex flex-col items-center justify-center h-full text-slate-300 animate-fade-in pb-20">
                    <div className="w-20 h-20 bg-white rounded-3xl flex items-center justify-center mb-6 shadow-sm border border-slate-100 rotate-3">
                        <MessageSquare size={36} className="text-indigo-200" />
                    </div>
                    <p className="text-sm font-bold text-slate-400">{t.inputPlaceholder}</p>
                </div>
            )}
            {messages.map((msg) => (
                <ChatBubble 
                    key={msg.id} 
                    message={msg} 
                    language={language} 
                    onUpdateMessage={handleUpdateMessage}
                    onError={(errorMsg) => addToast('error', errorMsg)}
                />
            ))}
            {isLoading && (
                <div className="flex items-center gap-2 text-slate-400 text-sm ml-4 animate-pulse">
                    <div className="w-8 h-8 bg-white rounded-full flex items-center justify-center shadow-sm border border-slate-100">
                        <Loader2 size={14} className="animate-spin text-indigo-500" />
                    </div>
                    {t.sending}
                </div>
            )}
            <div ref={messagesEndRef} />
        </div>

        {/* Input Area */}
        <div className="bg-white border-t border-slate-200 p-3 sm:p-4 z-20 pb-[env(safe-area-inset-bottom)]">
            {attachedImage && (
            <div className="flex items-center gap-2 mb-3 px-1 animate-scale-in">
                <div className="relative group">
                    <img src={attachedImage} alt="Preview" className="h-14 w-14 object-cover rounded-lg border border-slate-200 shadow-sm" />
                    <button 
                        onClick={() => setAttachedImage(null)}
                        className="absolute -top-2 -right-2 bg-slate-800 text-white rounded-full w-5 h-5 flex items-center justify-center text-xs shadow-md hover:bg-red-50 transition-colors"
                    >
                        ×
                    </button>
                </div>
                <span className="text-xs text-indigo-600 font-bold bg-indigo-50 px-3 py-1 rounded-full">{t.imageAttached}</span>
            </div>
            )}

            <div className="max-w-4xl mx-auto flex flex-col sm:flex-row gap-2 items-end">
                <div className="flex gap-1 items-center justify-between w-full sm:w-auto">
                    <div className="flex gap-1">
                        <button 
                            onClick={() => fileInputRef.current?.click()}
                            className="p-3 text-slate-400 hover:text-indigo-600 hover:bg-indigo-50 rounded-xl transition-all"
                            title="Attach Image"
                        >
                            <ImageIcon size={20} />
                        </button>
                        <input type="file" ref={fileInputRef} onChange={handleImageUpload} className="hidden" accept="image/*" />
                        
                        <button 
                            onClick={() => setUseThinking(!useThinking)}
                            className={`p-3 rounded-xl transition-all ${
                                useThinking ? 'bg-amber-50 text-amber-600 ring-1 ring-amber-200' : 'text-slate-400 hover:text-amber-600 hover:bg-amber-50'
                            }`}
                            title={t.thinkingToggle}
                        >
                            <BrainCircuit size={20} />
                        </button>
                        
                        <AudioRecorder onAudioCaptured={handleAudioInput} disabled={isLoading} />
                    </div>
                    
                    <button
                        onClick={handleSendMessage}
                        disabled={!inputValue.trim() && !attachedImage || isLoading}
                        className="sm:hidden p-3 bg-indigo-600 hover:bg-indigo-700 text-white rounded-xl disabled:opacity-50 disabled:scale-95 transition-all shadow-md shadow-indigo-200"
                    >
                        {isLoading ? <Loader2 size={20} className="animate-spin" /> : <Send size={20} />}
                    </button>
                </div>

                <div className="flex-1 w-full">
                    <textarea
                    value={inputValue}
                    onChange={(e) => setInputValue(e.target.value)}
                    onKeyDown={(e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSendMessage(); }}}
                    placeholder={useThinking ? t.thinkingPlaceholder : t.inputPlaceholder}
                    className="w-full border-2 border-transparent bg-slate-100 focus:bg-white rounded-2xl px-4 py-3 focus:border-indigo-500 focus:ring-0 resize-y min-h-[50px] max-h-[200px] text-sm md:text-base transition-all placeholder:text-slate-400 text-slate-800"
                    style={{ minHeight: '50px' }}
                    />
                </div>

                <button
                    onClick={handleSendMessage}
                    disabled={!inputValue.trim() && !attachedImage || isLoading}
                    className="hidden sm:flex p-3.5 bg-indigo-600 hover:bg-indigo-700 text-white rounded-xl disabled:opacity-50 transition-all shadow-lg shadow-indigo-200 hover:scale-105 active:scale-95"
                >
                    {isLoading ? <Loader2 size={20} className="animate-spin" /> : <Send size={20} />}
                </button>
            </div>
        </div>
      </div>

      {/* RIGHT SIDEBAR - DESKTOP */}
      <div className={`
        hidden md:block h-full bg-white border-l border-slate-200 transition-all duration-300 ease-in-out overflow-hidden z-30
        ${isHistoryOpen ? 'w-80 opacity-100' : 'w-0 opacity-0 border-none'}
      `}>
         <HistoryContent />
      </div>

      {/* MOBILE DRAWER (Slide over) */}
      {isHistoryOpen && (
        <div className="fixed inset-0 z-50 md:hidden flex justify-end">
             <div className="absolute inset-0 bg-slate-900/30 backdrop-blur-sm transition-opacity" onClick={() => setIsHistoryOpen(false)} />
             <div className="relative w-[85%] max-w-sm bg-white h-full shadow-2xl animate-slide-in-right z-50">
                 <HistoryContent />
             </div>
        </div>
      )}
    </div>
  );
};

export default ChatView;