
import React, { useState, useRef, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Send, Plus, Search, Settings, MoreHorizontal, User, Bot, ArrowLeft, Paperclip, Sparkles, Trash2, X, Upload, Package, FileText, BarChart3, ChevronRight } from 'lucide-react';
import { cn } from '../lib/utils';
import { Logo } from './Logo';
import ReactMarkdown from 'react-markdown';

interface Message {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  timestamp: Date;
  file?: {
    name: string;
    size: number;
  };
  reports?: Array<{
    name: string;
    path: string;
  }>;
  plots?: Array<{
    title: string;
    url: string;
    type?: 'image' | 'html';
  }>;
}

interface ChatSession {
  id: string;
  title: string;
  messages: Message[];
  updatedAt: Date;
}

export const ChatInterface: React.FC<{ onBack: () => void }> = ({ onBack }) => {
  const [sessions, setSessions] = useState<ChatSession[]>([
    {
      id: '1',
      title: 'ML Model Analysis',
      messages: [],
      updatedAt: new Date(),
    }
  ]);
  const [activeSessionId, setActiveSessionId] = useState<string>('1');  // Start with default session, update to UUID after first API call
  const [input, setInput] = useState('');
  const [isTyping, setIsTyping] = useState(false);
  const [currentStep, setCurrentStep] = useState<string>('');
  const [uploadedFile, setUploadedFile] = useState<File | null>(null);
  const [reportModalUrl, setReportModalUrl] = useState<string | null>(null);
  const [reportModalTitle, setReportModalTitle] = useState<string>('Visualization');
  const [showAssets, setShowAssets] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const scrollRef = useRef<HTMLDivElement>(null);
  const eventSourceRef = useRef<EventSource | null>(null);
  const processedAnalysisRef = useRef<Set<string>>(new Set()); // Track processed analysis_complete events
  
  const activeSession = sessions.find(s => s.id === activeSessionId) || sessions[0];

  useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [activeSession.messages, isTyping]);

  // Clear uploaded file when switching sessions
  useEffect(() => {
    setUploadedFile(null);
    if (fileInputRef.current) {
      fileInputRef.current.value = '';
    }
  }, [activeSessionId]);

  // Connect to SSE when we receive a valid backend UUID
  useEffect(() => {
    // Only connect if we have a backend UUID (contains hyphens)
    if (!activeSessionId || !activeSessionId.includes('-')) {
      return;
    }

    // Check if we need a new connection for this session
    // Close old connection if it exists and belongs to a different session or is closed
    if (eventSourceRef.current) {
      const currentSource = eventSourceRef.current;
      // If readyState is CLOSED (2), we need a new connection
      // If it's CONNECTING (0) or OPEN (1) for the same session, reuse it
      if (currentSource.readyState === 2) {
        console.log('🔄 Existing connection closed, creating new one');
        currentSource.close();
        eventSourceRef.current = null;
      } else {
        console.log('♻️ Reusing existing SSE connection');
        return;
      }
    }

    // Connect to SSE stream - will receive history + any new events
    const API_URL = window.location.origin;
    console.log(`🔌 Connecting SSE to session: ${activeSessionId}`);
    const eventSource = new EventSource(`${API_URL}/api/progress/stream/${activeSessionId}`);

    eventSource.onopen = () => {
      console.log('✅ SSE connection established');
    };

    // Handle all incoming messages
    eventSource.onmessage = (e) => {
      console.log('📨 SSE received:', e.data);
      try {
        const data = JSON.parse(e.data);
        
        // Handle different event types
        if (data.type === 'connected') {
          console.log('🔗 Connected to progress stream');
        } else if (data.type === 'tool_executing') {
          setCurrentStep(data.message || `🔧 Executing: ${data.tool}`);
        } else if (data.type === 'tool_completed') {
          setCurrentStep(data.message || `✓ Completed: ${data.tool}`);
        } else if (data.type === 'tool_failed') {
          setCurrentStep(data.message || `❌ Failed: ${data.tool}`);
        } else if (data.type === 'token_update') {
          // Optional: Display token budget updates
          console.log('💰 Token update:', data.message);
        } else if (data.type === 'analysis_complete') {
          console.log('✅ Analysis completed', data.result);
          setIsTyping(false);
          
          // Create a unique key based on actual workflow content to prevent duplicates
          // Use the last tool executed + summary hash for uniqueness
          const lastTool = data.result?.workflow_history?.[data.result.workflow_history.length - 1]?.tool || 'unknown';
          const summarySnippet = (data.result?.summary || '').substring(0, 50);
          const resultKey = `${activeSessionId}-${lastTool}-${summarySnippet}`;
          
          // Only process if we haven't seen this exact result before
          if (!processedAnalysisRef.current.has(resultKey)) {
            console.log('🆕 New analysis result, processing...', resultKey);
            processedAnalysisRef.current.add(resultKey);
            
            // Process the final result with the current session ID
            if (data.result) {
              processAnalysisResult(data.result, activeSessionId);
            }
          } else {
            console.log('⏭️ Skipping duplicate analysis result', resultKey);
          }
        }
      } catch (err) {
        console.error('❌ Error parsing SSE event:', err, e.data);
      }
    };

    // Handle errors - DON'T immediately close, just log
    eventSource.onerror = (err) => {
      console.error('❌ SSE connection error/closed:', err);
      // Don't close here - let it reconnect naturally on next request
      // The readyState check above will handle creating a new connection if needed
    };

    eventSourceRef.current = eventSource;

    // Cleanup on unmount or session change
    return () => {
      if (eventSourceRef.current) {
        console.log('🧹 Cleaning up SSE connection');
        eventSourceRef.current.close();
        eventSourceRef.current = null;
      }
    };
  }, [activeSessionId]);

  const processAnalysisResult = (result: any, sessionId: string) => {
    // Extract and display the analysis result from SSE
    let assistantContent = '✅ Analysis Complete!\n\n';
    let reports: Array<{name: string, path: string}> = [];
    let plots: Array<{title: string, url: string, type?: 'image' | 'html'}> = [];
    
    // PRIORITY 1: Extract plots from main result.plots array (backend enhanced summary)
    if (result.plots && Array.isArray(result.plots)) {
      result.plots.forEach((plot: any) => {
        plots.push({
          title: plot.title || 'Visualization',
          url: plot.url || plot.path,
          type: plot.type || (plot.url?.endsWith('.html') ? 'html' : 'image')
        });
      });
    }
    
    // PRIORITY 2: Extract plots and reports from workflow_history (for backward compatibility)
    if (result.workflow_history) {
      const reportTools = ['generate_ydata_profiling_report', 'generate_plotly_dashboard', 'generate_all_plots'];
      const plotTools = [
        'generate_interactive_correlation_heatmap',
        'generate_interactive_scatter',
        'generate_interactive_histogram',
        'generate_interactive_box_plots',
        'generate_interactive_time_series',
        'generate_eda_plots',
        'generate_data_quality_plots',
        'analyze_correlations'
      ];
      
      result.workflow_history.forEach((step: any) => {
        if (reportTools.includes(step.tool)) {
          const reportPath = step.result?.output_path || step.result?.report_path || step.arguments?.output_path;
          if (reportPath && (step.result?.success !== false)) {
            reports.push({
              name: step.tool.replace('generate_', '').replace(/_/g, ' ').trim(),
              path: reportPath
            });
          }
        }
        
        // Only extract from workflow if not already in result.plots
        if (plotTools.includes(step.tool) && step.result?.result?.output_path && plots.length === 0) {
          const outputPath = step.result.result.output_path;
          plots.push({
            title: step.tool.replace('generate_', '').replace('interactive_', '').replace(/_/g, ' ').trim(),
            url: outputPath.startsWith('/') ? outputPath : `/outputs/${outputPath.replace('./outputs/', '')}`,
            type: outputPath.endsWith('.html') ? 'html' : 'image'
          });
        }
      });
    }
    
    if (reports.length > 0) {
      assistantContent += '📊 **Generated Reports:**\n';
      reports.forEach(r => assistantContent += `- ${r.name}\n`);
      assistantContent += '\n';
    }
    
    if (plots.length > 0) {
      assistantContent += `📈 **Generated ${plots.length} Visualizations**\n\n`;
    }
    
    // Extract summary from backend (field changed from final_answer to summary)
    const summaryText = result.summary || result.final_answer || 'Analysis complete. Check the generated artifacts.';
    assistantContent += summaryText;
    
    // Add assistant message with result
    const assistantMessage: Message = {
      id: Date.now().toString(),
      role: 'assistant',
      content: assistantContent,
      timestamp: new Date(),
      reports,
      plots
    };
    
    // Get current session and add message
    setSessions(prev => prev.map(s => {
      if (s.id === sessionId) {
        return { ...s, messages: [...s.messages, assistantMessage], updatedAt: new Date() };
      }
      return s;
    }));
  };

  const handleSend = async () => {
    if ((!input.trim() && !uploadedFile) || isTyping) return;

    const userMessage: Message = {
      id: Date.now().toString(),
      role: 'user',
      content: input || (uploadedFile ? `Uploaded: ${uploadedFile.name}` : ''),
      timestamp: new Date(),
      file: uploadedFile ? { name: uploadedFile.name, size: uploadedFile.size } : undefined,
    };

    const newMessages = [...activeSession.messages, userMessage];
    updateSession(activeSessionId, newMessages);
    setInput('');
    
    // Show loading indicator immediately (for UI feedback)
    setIsTyping(true);

    try {
      
      // Use the current origin if running on same server, otherwise use env variable
      const API_URL = window.location.origin;
      console.log('API URL:', API_URL);
      
      let response;
      const sessionKey = activeSessionId || 'default';
      
      // Check if there's a recent file analysis in the conversation
      const recentFileMessage = newMessages.slice(-5).find(m => m.file || m.content.includes('Uploaded:'));
      const hasRecentFile = recentFileMessage && !uploadedFile;
      
      if (uploadedFile || hasRecentFile) {
        // Use /run endpoint for file analysis or follow-up questions about uploaded data
        const formData = new FormData();
        
        if (uploadedFile) {
          formData.append('file', uploadedFile);
          formData.append('task_description', input || 'Analyze this dataset and provide insights');
          formData.append('session_id', sessionKey); // Add session_id for progress tracking
        } else if (hasRecentFile) {
          // For follow-up questions, extract the filename from recent context
          const fileNameMatch = recentFileMessage?.content.match(/Uploaded: (.+)/);
          const fileName = fileNameMatch ? fileNameMatch[1] : 'dataset.csv';
          
          // Send follow-up request as a new task description
          formData.append('task_description', input);
          formData.append('session_id', sessionKey); // Use same session key
          
          // Note: Backend needs to support session-based file context
          // For now, just send the task which should work with session memory
        }
        
        formData.append('use_cache', 'true');
        formData.append('max_iterations', '20');
        
        response = await fetch(`${API_URL}/run-async`, {
          method: 'POST',
          body: formData
        });
        
        setUploadedFile(null);
      } else {
        response = await fetch(`${API_URL}/chat`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            messages: newMessages.map(m => ({
              role: m.role,
              content: m.content
            })),
            stream: false
          })
        });
      }

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

      const data = await response.json();
      
      // Store UUID from backend to trigger SSE connection
      if (data.session_id) {
        console.log(`🔑 Session UUID from backend: ${data.session_id}`);
        
        const newSessionId = data.session_id;
        
        // CRITICAL: Update sessions first, then activeSessionId
        // React 18 batches these updates automatically, preventing flicker
        setSessions(prev => prev.map(s => 
          s.id === activeSessionId ? { ...s, id: newSessionId } : s
        ));
        setActiveSessionId(newSessionId);
      }
      
      // For async endpoint, result comes via SSE analysis_complete event
      // For now, just wait for SSE to deliver the result
      if (data.status === 'started') {
        console.log('🚀 Analysis started, waiting for SSE events...');
        return; // Don't process result here, will come via SSE
      }
      
      // Legacy sync endpoint handling (if data.result exists)
      let assistantContent = '';
      let reports: Array<{name: string, path: string}> = [];
      let plots: Array<{title: string, url: string, type?: 'image' | 'html'}> = [];
      
      // Check for reports in any /run endpoint response (not just when file is uploaded)
      if (data.result) {
        const result = data.result;
        assistantContent = `✅ Analysis Complete!\n\n`;
        
        // Extract plots from workflow_history (PRIMARY SOURCE)
        if (result.workflow_history) {
          const reportTools = ['generate_ydata_profiling_report', 'generate_plotly_dashboard', 'generate_all_plots'];
          const plotTools = [
            'generate_interactive_correlation_heatmap',
            'generate_interactive_scatter',
            'generate_interactive_histogram',
            'generate_interactive_box_plots',
            'generate_interactive_time_series',
            'generate_eda_plots',
            'generate_data_quality_plots',
            'analyze_correlations'
          ];
          
          result.workflow_history.forEach((step: any) => {
            // Extract reports
            if (reportTools.includes(step.tool)) {
              const reportPath = step.result?.output_path || step.result?.report_path || step.arguments?.output_path;
              
              if (reportPath && (step.result?.success !== false)) {
                reports.push({
                  name: step.tool.replace('generate_', '').replace(/_/g, ' ').replace('report', '').trim(),
                  path: reportPath
                });
              }
            }
            
            // Extract plots
            if (plotTools.includes(step.tool)) {
              const plotPath = step.result?.output_path || step.arguments?.output_path;
              
              if (plotPath && (step.result?.success !== false)) {
                const plotTitle = step.tool
                  .replace('generate_', '')
                  .replace('interactive_', '')
                  .replace(/_/g, ' ')
                  .replace('plots', 'plot')
                  .trim();
                
                plots.push({
                  title: plotTitle.charAt(0).toUpperCase() + plotTitle.slice(1),
                  url: plotPath.replace('./outputs/', '/outputs/'),
                  type: plotPath.endsWith('.html') ? 'html' : 'image'
                });
              }
            }
          });
        }
        
        // Also check for report paths mentioned in the summary text
        if (result.summary && !reports.length) {
          const reportPathMatch = result.summary.match(/\.(\/outputs\/reports\/[^\s]+\.html)/);
          if (reportPathMatch) {
            reports.push({
              name: 'ydata profiling',
              path: reportPathMatch[1]
            });
          }
        }
        
        if (result.summary) {
          assistantContent += `**Summary:**\n${result.summary}\n\n`;
        }
        
        if (result.workflow_history && result.workflow_history.length > 0) {
          assistantContent += `**Tools Used:** ${result.workflow_history.length} steps\n\n`;
          assistantContent += `**Final Result:**\n${result.final_result || 'Analysis completed successfully'}`;
        }
      } else if (data.success && data.message) {
        assistantContent = data.message;
      } else {
        throw new Error('Invalid response from API');
      }

      // Aggressive text cleaning to remove malformed content
      assistantContent = assistantContent
        // Remove broken markdown tables (lines with just | symbols)
        .replace(/^\s*\|\s*\|\s*$/gm, '')
        // Remove confusing phrases
        .replace(/Printed in logs \(see above\)/gi, '')
        .replace(/\(see above\)/gi, '')
        .replace(/see above/gi, '')
        // Remove broken table rows (just dashes and pipes)
        .replace(/^\s*[-|]+\s*$/gm, '')
        // Remove code block markers without content
        .replace(/```\s*```/g, '')
        // Remove empty markdown sections
        .replace(/\n{3,}/g, '\n\n')
        // Clean up broken table syntax
        .replace(/\|\s*\n\s*\|/g, '')
        .trim();
      
      updateSession(activeSessionId, [...newMessages, {
        id: (Date.now() + 1).toString(),
        role: 'assistant',
        content: assistantContent,
        timestamp: new Date(),
        reports: reports.length > 0 ? reports : undefined,
        plots: plots.length > 0 ? plots : undefined
      }]);
    } catch (error: any) {
      console.error("Chat Error:", error);
      
      let errorMessage = "I'm sorry, I encountered an error processing your request.";
      
      if (error.message) {
        errorMessage += `\n\n**Error:** ${error.message}`;
      }
      
      // Try to parse response error
      try {
        const errorText = await error.text?.();
        if (errorText) {
          const errorData = JSON.parse(errorText);
          if (errorData.detail) {
            errorMessage = `**Error:** ${typeof errorData.detail === 'string' ? errorData.detail : JSON.stringify(errorData.detail)}`;
          }
        }
      } catch (e) {
        // Ignore parsing errors
      }
      
      updateSession(activeSessionId, [...newMessages, {
        id: 'err-' + Date.now(),
        role: 'assistant',
        content: errorMessage,
        timestamp: new Date()
      }]);
      
      // On error, stop loading indicator
      setIsTyping(false);
    }
    // NOTE: No finally block - isTyping is set to false by SSE analysis_complete event
  };

  const updateSession = (id: string, messages: Message[]) => {
    setSessions(prev => prev.map(s => {
      if (s.id === id) {
        return { ...s, messages, updatedAt: new Date() };
      }
      return s;
    }));
  };

  const createNewChat = () => {
    const newId = Date.now().toString();
    const newSession: ChatSession = {
      id: newId,
      title: 'New Chat',
      messages: [],
      updatedAt: new Date()
    };
    setSessions([newSession, ...sessions]);
    setActiveSessionId(newId);
    
    // Clear file upload state for new chat
    setUploadedFile(null);
    if (fileInputRef.current) {
      fileInputRef.current.value = '';
    }
  };

  const deleteSession = (e: React.MouseEvent, id: string) => {
    e.stopPropagation();
    if (sessions.length === 1) return;
    setSessions(prev => prev.filter(s => s.id !== id));
    if (activeSessionId === id) {
      setActiveSessionId(sessions.find(s => s.id !== id)?.id || '');
    }
  };

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      const validTypes = ['.csv', '.parquet'];
      const fileExt = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
      
      if (validTypes.includes(fileExt)) {
        setUploadedFile(file);
      } else {
        alert('Please upload a CSV or Parquet file');
      }
    }
  };

  const removeFile = () => {
    setUploadedFile(null);
    if (fileInputRef.current) {
      fileInputRef.current.value = '';
    }
  };

  return (
    <div className="flex h-screen w-full bg-[#050505] overflow-hidden text-white/90">
      {/* Sidebar */}
      <aside className="w-[280px] hidden md:flex flex-col border-r border-white/5 bg-[#0a0a0a]/50 backdrop-blur-xl">
        <div className="p-4 flex flex-col h-full">
          <div className="flex items-center gap-3 mb-8 px-2">
            <Logo className="w-8 h-8" />
            <span className="font-bold tracking-tight text-sm uppercase">Console</span>
          </div>

          <button 
            onClick={createNewChat}
            className="w-full flex items-center gap-3 px-4 py-3 rounded-xl bg-white/5 hover:bg-white/10 border border-white/10 transition-all text-sm font-medium mb-6 group"
          >
            <Plus className="w-4 h-4 group-hover:scale-110 transition-transform" />
            New Conversation
          </button>

          <div className="flex-1 overflow-y-auto space-y-2 custom-scrollbar">
            <p className="px-3 text-[10px] uppercase tracking-widest text-white/30 font-bold mb-2">History</p>
            {sessions.map(session => (
              <div
                key={session.id}
                onClick={() => setActiveSessionId(session.id)}
                className={cn(
                  "group flex items-center justify-between px-4 py-3 rounded-xl cursor-pointer transition-all text-sm",
                  activeSessionId === session.id 
                    ? "bg-white/10 text-white border border-white/10 shadow-lg" 
                    : "text-white/40 hover:text-white/70 hover:bg-white/5"
                )}
              >
                <span className="truncate flex-1 pr-2">{session.title}</span>
                <Trash2 
                  onClick={(e) => deleteSession(e, session.id)}
                  className="w-4 h-4 opacity-0 group-hover:opacity-100 hover:text-rose-400 transition-all" 
                />
              </div>
            ))}
          </div>

          <div className="mt-auto pt-4 border-t border-white/5 flex items-center justify-between px-2">
            <button onClick={onBack} className="p-2 hover:bg-white/5 rounded-lg transition-colors text-white/40 hover:text-white">
              <ArrowLeft className="w-5 h-5" />
            </button>
            <div className="flex gap-2">
              <button className="p-2 hover:bg-white/5 rounded-lg transition-colors text-white/40 hover:text-white">
                <Settings className="w-5 h-5" />
              </button>
              <button className="p-2 hover:bg-white/5 rounded-lg transition-colors text-white/40 hover:text-white">
                <User className="w-5 h-5" />
              </button>
            </div>
          </div>
        </div>
      </aside>

      {/* Main Chat Area */}
      <main className="flex-1 flex flex-col relative bg-gradient-to-b from-[#080808] to-[#050505]">
        {/* Top Header */}
        <header className="h-16 flex items-center justify-between px-6 border-b border-white/5 backdrop-blur-md bg-black/20 sticky top-0 z-10">
          <div className="flex items-center gap-4">
             <button onClick={onBack} className="md:hidden p-2 hover:bg-white/5 rounded-lg">
               <ArrowLeft className="w-5 h-5" />
             </button>
             <div>
               <h2 className="text-sm font-bold text-white tracking-tight">{activeSession.title}</h2>
               <p className="text-[10px] text-white/30 font-medium">{activeSession.messages.length} messages in session</p>
             </div>
          </div>
          <div className="flex items-center gap-3">
            <button 
              onClick={() => setShowAssets(!showAssets)}
              className={cn(
                "p-2 transition-colors rounded-lg",
                showAssets ? "text-emerald-400 bg-emerald-500/10" : "text-white/40 hover:text-white"
              )}
            >
              <Package className="w-5 h-5" />
            </button>
            <button className="p-2 text-white/40 hover:text-white transition-colors">
              <Search className="w-5 h-5" />
            </button>
            <button className="p-2 text-white/40 hover:text-white transition-colors">
              <MoreHorizontal className="w-5 h-5" />
            </button>
          </div>
        </header>

        {/* Message List */}
        <div 
          ref={scrollRef}
          className="flex-1 overflow-y-auto p-4 md:p-8 space-y-8 scroll-smooth"
        >
          {activeSession.messages.length === 0 ? (
            <div className="h-full flex flex-col items-center justify-center text-center px-4">
               <motion.div 
                 initial={{ opacity: 0, scale: 0.9 }}
                 animate={{ opacity: 1, scale: 1 }}
                 className="w-16 h-16 bg-gradient-to-br from-indigo-500/20 to-rose-500/20 rounded-2xl flex items-center justify-center mb-6 border border-white/10"
               >
                 <Sparkles className="w-8 h-8 text-indigo-400" />
               </motion.div>
               <h1 className="text-2xl font-extrabold text-white mb-3">Welcome, Data Scientist</h1>
               <p className="text-white/40 max-w-sm leading-relaxed text-sm">
                 I'm your autonomous agent ready to profile data, train models, or build dashboards. 
                 Try uploading a dataset or describing your ML objective.
               </p>
               <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 mt-8 w-full max-w-lg">
                  {[
                    "Profile my sales.csv",
                    "Train a XGBoost classifier",
                    "Generate a correlation heatmap",
                    "Explain feature importance"
                  ].map(prompt => (
                    <button 
                      key={prompt}
                      onClick={() => setInput(prompt)}
                      className="text-left px-4 py-3 rounded-xl bg-white/[0.03] border border-white/5 hover:bg-white/5 transition-all text-xs text-white/60 hover:text-white"
                    >
                      "{prompt}"
                    </button>
                  ))}
               </div>
            </div>
          ) : (
            activeSession.messages.map((msg) => (
              <motion.div
                key={msg.id}
                initial={{ opacity: 0, y: 10 }}
                animate={{ opacity: 1, y: 0 }}
                className={cn(
                  "flex w-full gap-4",
                  msg.role === 'user' ? "flex-row-reverse" : "flex-row"
                )}
              >
                <div className={cn(
                  "w-8 h-8 rounded-lg flex items-center justify-center shrink-0 border border-white/10",
                  msg.role === 'user' ? "bg-indigo-500/20" : "bg-white/5"
                )}>
                  {msg.role === 'user' ? <User className="w-4 h-4" /> : <Bot className="w-4 h-4 text-indigo-400" />}
                </div>
                <div className={cn(
                  "max-w-[80%] md:max-w-[70%] p-4 rounded-2xl text-sm leading-relaxed",
                  msg.role === 'user' 
                    ? "bg-indigo-600/20 text-indigo-50 border border-indigo-500/20" 
                    : "bg-white/[0.03] text-white/80 border border-white/5"
                )}>
                  {msg.file && (
                    <div className="mb-2 flex items-center gap-2 text-xs bg-white/5 rounded-lg px-3 py-2 border border-white/10">
                      <Paperclip className="w-3 h-3" />
                      <span className="font-medium">{msg.file.name}</span>
                      <span className="text-white/40">({(msg.file.size / 1024).toFixed(1)} KB)</span>
                    </div>
                  )}
                  {msg.role === 'assistant' ? (
                    <ReactMarkdown 
                      className="prose prose-invert prose-sm max-w-none prose-p:leading-relaxed prose-pre:bg-black/40 prose-pre:border prose-pre:border-white/10 prose-headings:text-white prose-strong:text-white prose-li:text-white/80"
                      components={{
                        p: ({node, ...props}) => <p className="mb-3 last:mb-0" {...props} />,
                        ul: ({node, ...props}) => <ul className="mb-3 space-y-1" {...props} />,
                        ol: ({node, ...props}) => <ol className="mb-3 space-y-1" {...props} />,
                        li: ({node, ...props}) => <li className="ml-4" {...props} />,
                        strong: ({node, ...props}) => <strong className="font-semibold text-white" {...props} />,
                        code: ({node, inline, ...props}: any) => 
                          inline ? 
                            <code className="px-1.5 py-0.5 rounded bg-white/10 text-indigo-300 text-xs font-mono" {...props} /> :
                            <code className="block p-3 rounded-lg bg-black/40 border border-white/10 text-xs font-mono overflow-x-auto" {...props} />
                      }}
                    >
                      {msg.content || ''}
                    </ReactMarkdown>
                  ) : (
                    msg.content
                  )}
                  {msg.reports && msg.reports.length > 0 && (
                    <div className="mt-4 flex flex-wrap gap-2">
                      {msg.reports.map((report, idx) => {
                        // Normalize the report path: remove leading ./ and ensure it starts with /
                        const normalizedPath = report.path.replace(/^\.\//, '/');
                        return (
                          <button
                            key={idx}
                            onClick={() => { setReportModalUrl(`${window.location.origin}${normalizedPath}`); setReportModalTitle(report.name || 'Report'); }}
                            className="flex items-center gap-2 px-4 py-2 rounded-lg bg-indigo-500/20 hover:bg-indigo-500/30 border border-indigo-500/30 text-indigo-200 text-xs font-medium transition-all group"
                          >
                            <Sparkles className="w-3.5 h-3.5 group-hover:scale-110 transition-transform" />
                            View {report.name} Report
                          </button>
                        );
                      })}
                    </div>
                  )}
                  {msg.plots && msg.plots.length > 0 && (
                    <>
                      <div className="mt-4 space-y-3">
                        <div className="text-xs font-semibold text-white/60 mb-2">
                          📊 Generated Visualizations ({msg.plots.length})
                        </div>
                        <div className="flex flex-wrap gap-2">
                          {msg.plots.map((plot, idx) => (
                          <button
                            key={idx}
                            onClick={() => { setReportModalUrl(`${window.location.origin}${plot.url}`); setReportModalTitle(plot.title || 'Visualization'); }}
                            className="flex items-center gap-2 px-4 py-2 rounded-lg bg-emerald-500/20 hover:bg-emerald-500/30 border border-emerald-500/30 text-emerald-200 text-xs font-medium transition-all group"
                          >
                            <svg className="w-3.5 h-3.5 group-hover:scale-110 transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z" />
                            </svg>
                            View {plot.title}
                          </button>
                        ))}
                      </div>
                    </div>
                    </>
                  )}
                  <div className="mt-2 text-[10px] opacity-20 font-mono">
                    {msg.timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
                  </div>
                </div>
              </motion.div>
            ))
          )}
          {isTyping && (
             <div className="flex gap-4">
                <div className="w-8 h-8 rounded-lg flex items-center justify-center shrink-0 bg-white/5 border border-white/10">
                  <Bot className="w-4 h-4 text-indigo-400" />
                </div>
                <div className="bg-white/[0.03] p-4 rounded-2xl border border-white/5">
                  <div className="flex items-center gap-3">
                    <div className="flex gap-1">
                      <span className="w-1.5 h-1.5 bg-emerald-500 rounded-full animate-bounce [animation-delay:-0.3s]"></span>
                      <span className="w-1.5 h-1.5 bg-emerald-500 rounded-full animate-bounce [animation-delay:-0.15s]"></span>
                      <span className="w-1.5 h-1.5 bg-emerald-500 rounded-full animate-bounce"></span>
                    </div>
                    <span className="text-sm text-white/60">
                      {currentStep || '🔧 Starting analysis...'}
                    </span>
                  </div>
                </div>
             </div>
          )}
        </div>

        {/* Input Bar */}
        <div className="p-4 md:p-8 pt-0">
          <div className="max-w-4xl mx-auto relative">
            <div className="absolute -top-10 left-4 flex gap-2">
               <input
                 ref={fileInputRef}
                 type="file"
                 accept=".csv,.parquet"
                 onChange={handleFileSelect}
                 className="hidden"
                 id="file-upload"
               />
               <label
                 htmlFor="file-upload"
                 className="flex items-center gap-1.5 px-3 py-1 rounded-full bg-white/[0.03] border border-white/5 text-[10px] text-white/40 hover:text-white hover:bg-white/5 transition-all cursor-pointer"
               >
                  <Upload className="w-3 h-3" /> Upload Dataset
               </label>
               {uploadedFile && (
                 <div className="flex items-center gap-2 px-3 py-1 rounded-full bg-indigo-500/20 border border-indigo-500/30 text-[10px] text-indigo-200">
                   <Paperclip className="w-3 h-3" />
                   <span className="max-w-[150px] truncate">{uploadedFile.name}</span>
                   <button onClick={removeFile} className="hover:text-white transition-colors">
                     <X className="w-3 h-3" />
                   </button>
                 </div>
               )}
            </div>
            <div className="relative group">
               <textarea
                value={input}
                onChange={(e) => setInput(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault();
                    handleSend();
                  }
                }}
                placeholder={uploadedFile ? "Describe what you want to do with this dataset..." : "Ask your agent anything or upload a dataset..."}
                className="w-full bg-[#0d0d0d] border border-white/10 rounded-2xl p-4 pr-16 text-sm min-h-[56px] max-h-48 resize-none focus:outline-none focus:border-indigo-500/50 focus:ring-1 focus:ring-indigo-500/20 transition-all text-white/90 placeholder:text-white/20 shadow-2xl"
              />
              <button
                onClick={handleSend}
                disabled={(!input.trim() && !uploadedFile) || isTyping}
                className={cn(
                  "absolute right-3 bottom-3 p-2.5 rounded-xl transition-all",
                  (input.trim() || uploadedFile) && !isTyping 
                    ? "bg-white text-black hover:scale-105 active:scale-95" 
                    : "bg-white/5 text-white/20 cursor-not-allowed"
                )}
              >
                <Send className="w-4 h-4" />
              </button>
            </div>
            <p className="text-center mt-3 text-[10px] text-white/20 font-medium">
              Enterprise Data Agent v3.1 | Secured with end-to-end encryption
            </p>
          </div>
        </div>
      </main>
      
      {/* Assets Sidebar */}
      <AnimatePresence>
        {showAssets && (
          <motion.aside
            initial={{ x: 320, opacity: 0 }}
            animate={{ x: 0, opacity: 1 }}
            exit={{ x: 320, opacity: 0 }}
            transition={{ type: "spring", damping: 25, stiffness: 200 }}
            className="w-[320px] border-l border-white/5 bg-[#0a0a0a]/95 backdrop-blur-xl flex flex-col"
          >
            <div className="p-4 border-b border-white/5 flex items-center justify-between">
              <div className="flex items-center gap-2">
                <Package className="w-5 h-5 text-emerald-400" />
                <h3 className="font-bold text-sm">Assets</h3>
              </div>
              <button 
                onClick={() => setShowAssets(false)}
                className="p-1.5 rounded-lg hover:bg-white/5 transition-colors"
              >
                <X className="w-4 h-4" />
              </button>
            </div>
            
            <div className="flex-1 overflow-y-auto p-4 space-y-4 custom-scrollbar">
              {(() => {
                const allPlots: Array<{title: string, url: string, type?: string}> = [];
                const allReports: Array<{name: string, path: string}> = [];
                const allDataFiles: string[] = [];
                const baselineModels = ['xgboost', 'random_forest', 'catboost', 'lightgbm', 'ridge', 'lasso'];
                const foundModels = new Set<string>();
                
                activeSession.messages.forEach(msg => {
                  if (msg.plots) allPlots.push(...msg.plots);
                  if (msg.reports) allReports.push(...msg.reports);
                  
                  baselineModels.forEach(model => {
                    if (msg.content.toLowerCase().includes(model)) {
                      const displayName = model.split('_').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
                      foundModels.add(displayName);
                    }
                  });
                  
                  if (msg.content.includes('Cleaned') || msg.content.includes('encoded')) {
                    allDataFiles.push('Cleaned & Encoded Dataset');
                  }
                });
                
                const uniqueDataFiles = [...new Set(allDataFiles)];
                const uniqueModels = Array.from(foundModels);
                
                return (
                  <>
                    {/* Plots Section FIRST */}
                    {allPlots.length > 0 && (
                      <div>
                        <div className="flex items-center gap-2 mb-3">
                          <BarChart3 className="w-4 h-4 text-emerald-400" />
                          <h4 className="text-xs font-bold uppercase tracking-wider text-white/60">Visualizations ({allPlots.length})</h4>
                        </div>
                        <div className="space-y-2">
                          {allPlots.map((plot, idx) => {
                            // Ensure URL is properly formatted
                            let plotUrl = plot.url;
                            if (plotUrl && plotUrl.startsWith('./outputs/')) {
                              plotUrl = plotUrl.replace('./outputs/', '/outputs/');
                            } else if (plotUrl && !plotUrl.startsWith('/outputs/')) {
                              plotUrl = `/outputs/${plotUrl.replace(/^outputs\//, '')}`;
                            }
                            
                            return (
                              <button
                                key={idx}
                                onClick={() => { setReportModalUrl(plotUrl || plot.url); setReportModalTitle(plot.title || 'Visualization'); }}
                                className="w-full p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-emerald-500/10 hover:border-emerald-500/30 transition-all text-left group"
                              >
                                <div className="flex items-center justify-between">
                                  <span className="text-sm text-white/80 truncate flex-1">{plot.title}</span>
                                  <ChevronRight className="w-4 h-4 text-white/40 group-hover:text-emerald-400 transition-all" />
                                </div>
                                <span className="text-xs text-white/40 mt-1 block">{plot.type || 'interactive'}</span>
                              </button>
                            );
                          })}\n                        </div>
                      </div>
                    )}
                    
                    {/* Data Files Section */}
                    {uniqueDataFiles.length > 0 && (
                      <div>
                        <div className="flex items-center gap-2 mb-3">
                          <FileText className="w-4 h-4 text-blue-400" />
                          <h4 className="text-xs font-bold uppercase tracking-wider text-white/60">Data Files ({uniqueDataFiles.length})</h4>
                        </div>
                        <div className="space-y-2">
                          {uniqueDataFiles.map((file, idx) => {
                            // Extract filename from path
                            const fileName = file.split('/').pop() || file;
                            // Create proper download URL
                            let downloadUrl = file;
                            if (downloadUrl.startsWith('./outputs/')) {
                              downloadUrl = downloadUrl.replace('./outputs/', '/outputs/');
                            } else if (!downloadUrl.startsWith('/outputs/')) {
                              downloadUrl = `/outputs/${file.replace(/^outputs\//, '')}`;
                            }
                            
                            return (
                              <a
                                key={idx}
                                href={downloadUrl}
                                download={fileName}
                                className="block w-full p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-blue-500/10 hover:border-blue-500/30 transition-all group"
                              >
                                <div className="flex items-center justify-between">
                                  <span className="text-sm text-white/80 truncate flex-1">{fileName}</span>
                                  <ChevronRight className="w-4 h-4 text-white/40 group-hover:text-blue-400 transition-all" />
                                </div>
                                <span className="text-xs text-white/40 mt-1 block">Click to download</span>
                              </a>
                            );
                          })}
                        </div>
                      </div>
                    )}
                    
                    {/* Models Section */}
                    {uniqueModels.length > 0 && (
                      <div>
                        <div className="flex items-center gap-2 mb-3">
                          <FileText className="w-4 h-4 text-purple-400" />
                          <h4 className="text-xs font-bold uppercase tracking-wider text-white/60">Models ({uniqueModels.length})</h4>
                        </div>
                        <div className="space-y-2">
                          {uniqueModels.map((model, idx) => {
                            // Find the model file path from workflow history
                            let modelPath = '';
                            activeSession.messages.forEach(msg => {
                              if (msg.role === 'assistant' && msg.content.includes(model)) {
                                // Try to extract model path (typically in ./outputs/models/)
                                const match = msg.content.match(/\.\/outputs\/models\/[^\s)]+\.pkl/);
                                if (match) modelPath = match[0].replace('./', '/');
                              }
                            });
                            
                            // Fallback: construct typical path
                            if (!modelPath) {
                              modelPath = `/outputs/models/${model.toLowerCase().replace(/\s+/g, '_')}_model.pkl`;
                            }
                            
                            return (
                              <button
                                key={idx}
                                onClick={() => {
                                  // Trigger download
                                  const link = document.createElement('a');
                                  link.href = modelPath;
                                  link.download = `${model.toLowerCase().replace(/\s+/g, '_')}_model.pkl`;
                                  link.click();
                                }}
                                className="w-full p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-purple-500/10 hover:border-purple-500/30 transition-all text-left group"
                              >
                                <div className="flex items-center justify-between">
                                  <span className="text-sm text-white/80 truncate flex-1">{model}</span>
                                  <ChevronRight className="w-4 h-4 text-white/40 group-hover:text-purple-400 transition-all" />
                                </div>
                                <span className="text-xs text-white/40 mt-1 block">Click to download</span>
                              </button>
                            );
                          })}
                        </div>
                      </div>
                    )}
                    
                    {/* Reports Section */}
                    {allReports.length > 0 && (
                      <div>
                        <div className="flex items-center gap-2 mb-3">
                          <FileText className="w-4 h-4 text-purple-400" />
                          <h4 className="text-xs font-bold uppercase tracking-wider text-white/60">Reports ({allReports.length})</h4>
                        </div>
                        <div className="space-y-2">
                          {allReports.map((report, idx) => (
                            <button
                              key={idx}
                              onClick={() => { setReportModalUrl(report.path); setReportModalTitle(report.name || 'Report'); }}
                              className="w-full p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-purple-500/10 hover:border-purple-500/30 transition-all text-left group"
                            >
                              <div className="flex items-center justify-between">
                                <span className="text-sm text-white/80 truncate flex-1">{report.name}</span>
                                <ChevronRight className="w-4 h-4 text-white/40 group-hover:text-purple-400 transition-all" />
                              </div>
                            </button>
                          ))}
                        </div>
                      </div>
                    )}
                    
                    {/* Empty State */}
                    {allPlots.length === 0 && allReports.length === 0 && uniqueModels.length === 0 && (
                      <div className="flex flex-col items-center justify-center h-full text-center p-8">
                        <Package className="w-12 h-12 text-white/10 mb-3" />
                        <p className="text-sm text-white/40 mb-1">No assets yet</p>
                        <p className="text-xs text-white/30">Upload a dataset to generate visualizations and models</p>
                      </div>
                    )}
                  </>
                );
              })()}
            </div>
          </motion.aside>
        )}
      </AnimatePresence>
      
      {/* Report Modal */}
      <AnimatePresence>
        {reportModalUrl && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4"
            onClick={() => { setReportModalUrl(null); setReportModalTitle('Visualization'); }}
          >
            <motion.div
              initial={{ scale: 0.95, opacity: 0 }}
              animate={{ scale: 1, opacity: 1 }}
              exit={{ scale: 0.95, opacity: 0 }}
              className="bg-[#0a0a0a] border border-white/10 rounded-2xl w-full max-w-7xl h-[90vh] flex flex-col overflow-hidden shadow-2xl"
              onClick={(e) => e.stopPropagation()}
            >
              <div className="flex items-center justify-between p-4 border-b border-white/5">
                <h3 className="text-lg font-semibold text-white">{reportModalTitle}</h3>
                <button
                  onClick={() => { setReportModalUrl(null); setReportModalTitle('Visualization'); }}
                  className="p-2 rounded-lg hover:bg-white/5 transition-colors"
                >
                  <X className="w-5 h-5" />
                </button>
              </div>
              <iframe
                src={reportModalUrl}
                className="flex-1 w-full bg-white"
                title="Report Viewer"
              />
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>
      
      <style>{`
        .custom-scrollbar::-webkit-scrollbar {
          width: 4px;
        }
        .custom-scrollbar::-webkit-scrollbar-track {
          background: transparent;
        }
        .custom-scrollbar::-webkit-scrollbar-thumb {
          background: rgba(255, 255, 255, 0.05);
          border-radius: 10px;
        }
        .custom-scrollbar::-webkit-scrollbar-thumb:hover {
          background: rgba(255, 255, 255, 0.1);
        }
      `}</style>
    </div>
  );
};
