import React, { useMemo, useState, useRef, useCallback } from 'react';
import { useQuery } from '@tanstack/react-query';
import {
  Activity,
  Zap,
  Target,
  TrendingUp,
  Database,
  Cpu,
  Globe,
  Play,
  Pause,
  ChevronDown,
  ChevronRight,
  Terminal,
  Plug,
  Eye,
  Bot,
  X,
  Check,
  Layers,
  FileText,
  Plus,
  Info,
  Link,
  MessageSquare,
  Image as ImageIcon,
  FolderOpen,
  Trash2,
  AlertCircle,
  Download,
  Copy,
  Navigation,
  Search,
  Code,
  CheckCircle,
  XCircle,
  Clock,
  FileJson,
  Sparkles,
  Brain,
  Compass,
  Shield,
  type LucideIcon,
} from 'lucide-react';
import { Badge } from '@/components/ui/Badge';
import { classNames } from '@/utils/helpers';
import { apiClient, type ScrapeStep, type ScrapeResponse, type ScrapeRequest } from '@/api/client';

// Step action to icon mapping
const getStepIcon = (action: string): LucideIcon => {
  const iconMap: Record<string, LucideIcon> = {
    'initialize': Sparkles,
    'navigate': Navigation,
    'extract': Search,
    'plugins': Plug,
    'planner': Brain,
    'planner_python': Code,
    'navigator': Compass,
    'navigator_python': Code,
    'extractor_python': Code,
    'verify': Shield,
    'verifier': Shield,
    'complete': CheckCircle,
    'mcp_search': Search,
    'python_sandbox': Terminal,
    'site_template': FileText,
    'tool_call': Zap,
    'error': XCircle,
  };
  return iconMap[action] || Activity;
};

// Step action color mapping
const getStepColor = (action: string, status: string): string => {
  if (status === 'failed') return 'text-red-400 bg-red-500/20 border-red-500/30';
  if (status === 'running') return 'text-cyan-400 bg-cyan-500/20 border-cyan-500/30 animate-pulse';
  
  const colorMap: Record<string, string> = {
    'initialize': 'text-purple-400 bg-purple-500/20 border-purple-500/30',
    'navigate': 'text-blue-400 bg-blue-500/20 border-blue-500/30',
    'extract': 'text-emerald-400 bg-emerald-500/20 border-emerald-500/30',
    'plugins': 'text-amber-400 bg-amber-500/20 border-amber-500/30',
    'planner': 'text-pink-400 bg-pink-500/20 border-pink-500/30',
    'planner_python': 'text-orange-400 bg-orange-500/20 border-orange-500/30',
    'navigator': 'text-indigo-400 bg-indigo-500/20 border-indigo-500/30',
    'navigator_python': 'text-orange-400 bg-orange-500/20 border-orange-500/30',
    'extractor_python': 'text-orange-400 bg-orange-500/20 border-orange-500/30',
    'verify': 'text-teal-400 bg-teal-500/20 border-teal-500/30',
    'verifier': 'text-teal-400 bg-teal-500/20 border-teal-500/30',
    'complete': 'text-green-400 bg-green-500/20 border-green-500/30',
    'mcp_search': 'text-cyan-400 bg-cyan-500/20 border-cyan-500/30',
    'python_sandbox': 'text-yellow-400 bg-yellow-500/20 border-yellow-500/30',
    'site_template': 'text-violet-400 bg-violet-500/20 border-violet-500/30',
    'tool_call': 'text-yellow-300 bg-yellow-500/20 border-yellow-500/30',
  };
  return colorMap[action] || 'text-slate-400 bg-slate-500/20 border-slate-500/30';
};

const isAgentPluginId = (pluginId: string): boolean => {
  const lowered = pluginId.toLowerCase();
  return lowered.startsWith('skill-') || lowered === 'web_scraper';
};

// Step Accordion Component
interface StepAccordionItemProps {
  step: ScrapeStep;
  isExpanded: boolean;
  onToggle: () => void;
  isLatest: boolean;
}

const StepAccordionItem: React.FC<StepAccordionItemProps> = ({ step, isExpanded, onToggle, isLatest }) => {
  const Icon = getStepIcon(step.action);
  const colorClasses = getStepColor(step.action, step.status);
  
  // Check if this is a tool call
  const isToolCall = step.action === 'tool_call';
  const toolName = (step.extracted_data?.tool_name as string) || '';
  const toolDescription = (step.extracted_data?.tool_description as string) || '';
  const toolParameters = (step.extracted_data?.parameters as Record<string, any>) || {};
  const toolResult = (step.extracted_data?.result as Record<string, any>) || {};
  
  return (
    <div className={classNames(
      'border rounded-lg overflow-hidden transition-all',
      isLatest ? 'ring-2 ring-cyan-500/50' : '',
      colorClasses.split(' ').slice(1).join(' ')
    )}>
      <button
        onClick={onToggle}
        className="w-full flex items-center justify-between px-4 py-3 hover:bg-white/5 transition-colors"
      >
        <div className="flex items-center gap-3 flex-1 min-w-0">
          <div className={classNames('p-2 rounded-lg flex-shrink-0', colorClasses.split(' ').slice(1, 3).join(' '))}>
            <Icon className={classNames('w-4 h-4', colorClasses.split(' ')[0])} />
          </div>
          <div className="text-left min-w-0 flex-1">
            <div className="flex items-center gap-2">
              <span className="text-sm font-medium text-white">
                {isToolCall 
                  ? (toolName ? `🔧 ${toolName}` : 'Tool Call')
                  : step.action.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase())}
              </span>
              <Badge 
                variant={step.status === 'completed' ? 'success' : step.status === 'failed' ? 'error' : 'info'} 
                size="sm"
              >
                {step.status}
              </Badge>
            </div>
            <p className="text-xs text-slate-400 truncate">{step.message}</p>
            {isToolCall && toolDescription && (
              <p className="text-[10px] text-slate-500 mt-0.5">{toolDescription}</p>
            )}
          </div>
        </div>
        <div className="flex items-center gap-3 flex-shrink-0">
          <div className="text-right">
            <span className="text-xs text-slate-500">Step {step.step_number}</span>
            {step.reward > 0 && (
              <p className="text-xs text-emerald-400">+{step.reward.toFixed(2)}</p>
            )}
          </div>
          {isExpanded ? (
            <ChevronDown className="w-4 h-4 text-slate-400" />
          ) : (
            <ChevronRight className="w-4 h-4 text-slate-400" />
          )}
        </div>
      </button>
      
      {isExpanded && (
        <div className="px-4 py-3 border-t border-white/10 bg-slate-900/50 space-y-3">
          {/* Tool Call Specific Details */}
          {isToolCall && (
            <>
              <div className="bg-slate-800/50 rounded-lg p-3 space-y-2">
                <div className="flex items-center gap-2">
                  <Zap className="w-3 h-3 text-yellow-400" />
                  <span className="text-xs font-semibold text-yellow-400">Tool Call Details</span>
                </div>
                
                {toolDescription && (
                  <div className="text-xs text-slate-300">
                    <span className="text-slate-500">Description:</span> {toolDescription}
                  </div>
                )}
                
                {Object.keys(toolParameters).length > 0 && (
                  <div>
                    <span className="text-xs text-slate-500">Parameters:</span>
                    <pre className="text-xs text-cyan-300 bg-slate-900/70 rounded p-2 mt-1 overflow-auto max-h-20 font-mono">
                      {JSON.stringify(toolParameters, null, 2)}
                    </pre>
                  </div>
                )}
                
                {Object.keys(toolResult).length > 0 && (
                  <div>
                    <span className="text-xs text-slate-500">Result:</span>
                    <pre className="text-xs text-emerald-300 bg-slate-900/70 rounded p-2 mt-1 overflow-auto max-h-20 font-mono">
                      {JSON.stringify(toolResult, null, 2)}
                    </pre>
                  </div>
                )}
              </div>
            </>
          )}
          
          {/* Step Details */}
          <div className="grid grid-cols-2 gap-4 text-xs">
            <div>
              <span className="text-slate-500">Action:</span>
              <span className="ml-2 text-slate-300">{step.action}</span>
            </div>
            <div>
              <span className="text-slate-500">Status:</span>
              <span className={classNames(
                'ml-2',
                step.status === 'completed' ? 'text-emerald-400' : 
                step.status === 'failed' ? 'text-red-400' : 'text-cyan-400'
              )}>{step.status}</span>
            </div>
            {step.url && (
              <div className="col-span-2">
                <span className="text-slate-500">URL:</span>
                <span className="ml-2 text-cyan-400 truncate">{step.url}</span>
              </div>
            )}
            {step.duration_ms && (
              <div>
                <span className="text-slate-500">Duration:</span>
                <span className="ml-2 text-slate-300">{step.duration_ms.toFixed(0)}ms</span>
              </div>
            )}
            <div>
              <span className="text-slate-500">Reward:</span>
              <span className="ml-2 text-emerald-400">{step.reward.toFixed(2)}</span>
            </div>
          </div>
          
          {/* Extracted Data (non-tool calls or if additional data exists) */}
          {step.extracted_data && Object.keys(step.extracted_data).length > 0 && !isToolCall && (
            <div className="mt-3">
              <p className="text-xs text-slate-500 mb-2">Extracted Data:</p>
              <pre className="text-xs text-slate-300 bg-slate-800/50 rounded-lg p-3 overflow-auto max-h-40 font-mono">
                {JSON.stringify(step.extracted_data, null, 2)}
              </pre>
            </div>
          )}
          
          {/* Timestamp */}
          <div className="flex items-center gap-2 text-[10px] text-slate-600">
            <Clock className="w-3 h-3" />
            {new Date(step.timestamp).toLocaleTimeString()}
          </div>
        </div>
      )}
    </div>
  );
};

// Types
interface TaskInput {
  urls: string[];
  instruction: string;
  outputInstruction: string;
  taskType: 'low' | 'medium' | 'high';
  selectedModel: string;
  selectedVisionModel: string;
  selectedAgents: string[];
  enabledPlugins: string[];
}

interface LogEntry {
  id: string;
  timestamp: string;
  level: 'info' | 'warn' | 'error' | 'debug';
  message: string;
  source?: string;
}

interface Asset {
  id: string;
  type: 'url' | 'image' | 'file' | 'data';
  name: string;
  source: 'user' | 'ai';
  content: string;
  timestamp: string;
}

interface MemoryEntry {
  id: string;
  type: 'short_term' | 'working' | 'long_term' | 'shared';
  content: string;
  timestamp: string;
}

interface PluginInfo {
  id: string;
  name: string;
  description: string;
  category: string;
  installed: boolean;
}

interface AgentInfo {
  type: string;
  name: string;
  description: string;
}

interface ModelInfo {
  provider: string;
  model: string;
  name: string;
  description?: string;
}

// View type
type ViewType = 'input' | 'dashboard';

// Info Popup Component
const InfoPopup: React.FC<{
  isOpen: boolean;
  onClose: () => void;
  title: string;
  description: string;
  details?: Record<string, string>;
}> = ({ isOpen, onClose, title, description, details }) => {
  if (!isOpen) return null;
  return (
    <div className="fixed inset-0 z-[60] flex items-center justify-center bg-black/70 backdrop-blur-sm">
      <div className="bg-gray-800 border border-gray-600 rounded-xl shadow-2xl w-full max-w-md p-5">
        <div className="flex items-start justify-between mb-4">
          <div className="flex items-center gap-3">
            <div className="p-2 bg-cyan-500/20 rounded-lg">
              <Info className="w-5 h-5 text-cyan-400" />
            </div>
            <h3 className="font-semibold text-white text-lg">{title}</h3>
          </div>
          <button onClick={onClose} className="p-1 text-gray-400 hover:text-white transition-colors">
            <X className="w-5 h-5" />
          </button>
        </div>
        <p className="text-gray-300 text-sm mb-4">{description}</p>
        {details && (
          <div className="space-y-2 pt-3 border-t border-gray-700">
            {Object.entries(details).map(([key, value]) => (
              <div key={key} className="flex justify-between text-sm">
                <span className="text-gray-500">{key}</span>
                <span className="text-gray-300">{value}</span>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

// Popup Components
interface PopupProps {
  title: string;
  isOpen: boolean;
  onClose: () => void;
  children: React.ReactNode;
  size?: 'sm' | 'md' | 'lg';
}

const Popup: React.FC<PopupProps> = ({ title, isOpen, onClose, children, size = 'md' }) => {
  if (!isOpen) return null;
  const sizeClasses = {
    sm: 'max-w-sm',
    md: 'max-w-lg',
    lg: 'max-w-2xl',
  };
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
      <div className={`bg-gray-800 border border-gray-700 rounded-xl shadow-2xl w-full ${sizeClasses[size]} max-h-[80vh] overflow-hidden`}>
        <div className="flex items-center justify-between px-4 py-3 border-b border-gray-700">
          <h3 className="font-semibold text-white">{title}</h3>
          <button onClick={onClose} className="p-1 text-gray-400 hover:text-white transition-colors">
            <X className="w-5 h-5" />
          </button>
        </div>
        <div className="p-4 overflow-y-auto max-h-[65vh]">{children}</div>
      </div>
    </div>
  );
};

// Accordion Component for sidebar
interface AccordionProps {
  title: string;
  icon: React.ElementType;
  badge?: string | number;
  color: string;
  children: React.ReactNode;
  defaultOpen?: boolean;
}

const Accordion: React.FC<AccordionProps> = ({ title, icon: Icon, badge, color, children, defaultOpen = false }) => {
  const [isOpen, setIsOpen] = useState(defaultOpen);
  
  return (
    <div className="border border-gray-700/50 rounded-lg overflow-hidden">
      <button
        onClick={() => setIsOpen(!isOpen)}
        className="w-full flex items-center justify-between px-3 py-2 bg-gray-800/50 hover:bg-gray-800 transition-colors"
      >
        <div className="flex items-center gap-2">
          <Icon className={`w-4 h-4 ${color}`} />
          <span className="text-xs font-medium text-white">{title}</span>
          {badge !== undefined && Number(badge) > 0 && (
            <Badge variant="neutral" size="sm">{badge}</Badge>
          )}
        </div>
        {isOpen ? <ChevronDown className="w-3 h-3 text-gray-400" /> : <ChevronRight className="w-3 h-3 text-gray-400" />}
      </button>
      {isOpen && <div className="p-2 bg-gray-900/30 border-t border-gray-700/50 space-y-1">{children}</div>}
    </div>
  );
};

// Main Dashboard Component
export const Dashboard: React.FC = () => {
  // View state - 'input' or 'dashboard'
  const [currentView, setCurrentView] = useState<ViewType>('input');
  
  // Task input state
  const [taskInput, setTaskInput] = useState<TaskInput>({
    urls: [],
    instruction: '',
    outputInstruction: '',
    taskType: 'medium',
    selectedModel: 'groq/gpt-oss-120b',
    selectedVisionModel: '',
    selectedAgents: [],
    enabledPlugins: [],
  });
  
  // URL input for adding
  const [newUrl, setNewUrl] = useState('');
  
  // Logs
  const [logs, setLogs] = useState<LogEntry[]>([]);
  
  // Running state
  const [isRunning, setIsRunning] = useState(false);
  
  // Streaming state
  const [sessionId, setSessionId] = useState<string | null>(null);
  const [currentStep, setCurrentStep] = useState<ScrapeStep | null>(null);
  const [allSteps, setAllSteps] = useState<ScrapeStep[]>([]);
  const [expandedStepIndex, setExpandedStepIndex] = useState<number | null>(null);
  const [scrapeResult, setScrapeResult] = useState<ScrapeResponse | null>(null);
  const [progress, setProgress] = useState({ urlIndex: 0, totalUrls: 0, currentUrl: '' });
  const [extractedData, setExtractedData] = useState<Record<string, unknown>>({});
  const abortControllerRef = useRef<{ abort: () => void } | null>(null);
  const startLockRef = useRef(false);
  const seenStepKeysRef = useRef<Set<string>>(new Set());
  const lastSessionInitRef = useRef<string | null>(null);
  
  // Assets
  const [assets, setAssets] = useState<Asset[]>([]);
  
  // Memories
  const [memories, setMemories] = useState<MemoryEntry[]>([]);
  const [newMemory, setNewMemory] = useState('');
  
  // Popup states
  const [showModelPopup, setShowModelPopup] = useState(false);
  const [showVisionPopup, setShowVisionPopup] = useState(false);
  const [showAgentPopup, setShowAgentPopup] = useState(false);
  const [showPluginPopup, setShowPluginPopup] = useState(false);
  const [showTaskTypePopup, setShowTaskTypePopup] = useState(false);
  const [showMemoriesPopup, setShowMemoriesPopup] = useState(false);
  const [showAssetsPopup, setShowAssetsPopup] = useState(false);
  
  // Info popup
  const [infoPopup, setInfoPopup] = useState<{ isOpen: boolean; title: string; description: string; details?: Record<string, string> }>({
    isOpen: false,
    title: '',
    description: '',
  });

  // Episode stats - session-based, start at 0
  const [stats, setStats] = useState({ episodes: 0, steps: 0, totalReward: 0, avgReward: 0 });

  // API Queries
  const { data: health, isError: healthError } = useQuery({
    queryKey: ['health'],
    queryFn: () => apiClient.healthCheck(),
    refetchInterval: 5000,
  });

  const { data: agentsData } = useQuery({
    queryKey: ['agents'],
    queryFn: async () => {
      const res = await fetch('/api/agents/list');
      if (!res.ok) return { agent_types: [] };
      return res.json();
    },
  });

  const { data: pluginsData } = useQuery({
    queryKey: ['plugins'],
    queryFn: async () => {
      const res = await fetch('/api/plugins');
      if (!res.ok) return { plugins: {} };
      return res.json();
    },
  });

  const { data: memoryData } = useQuery({
    queryKey: ['memory-stats'],
    queryFn: async () => {
      const res = await fetch('/api/memory/stats/overview');
      if (!res.ok) return { total_count: 0 };
      return res.json();
    },
    refetchInterval: 3000,
  });

  const { data: settingsData } = useQuery({
    queryKey: ['client-settings'],
    queryFn: async () => {
      const res = await fetch('/api/settings');
      if (!res.ok) return { available_models: [], api_keys_configured: {} };
      return res.json();
    },
  });

  // Get installed plugins only
  const getInstalledPlugins = () => {
    if (!pluginsData?.plugins) return { mcps: [], apis: [], processors: [] };
    const result: Record<string, PluginInfo[]> = {};
    for (const [category, plugins] of Object.entries(pluginsData.plugins)) {
      if (category === 'skills') continue;
      result[category] = (plugins as PluginInfo[]).filter(p => p.installed);
    }
    return result;
  };

  const installedPlugins = getInstalledPlugins();
  const enabledNonAgentPlugins = useMemo(
    () => taskInput.enabledPlugins.filter((pluginId) => !isAgentPluginId(pluginId)),
    [taskInput.enabledPlugins]
  );
  
  // Get agents
  const agents: AgentInfo[] = agentsData?.agent_types || [];
  
  // Get models grouped by provider
  const modelsByProvider = (): Record<string, ModelInfo[]> => {
    const models = settingsData?.available_models || [];
    const grouped: Record<string, ModelInfo[]> = {};
    models.forEach((m: ModelInfo) => {
      if (!grouped[m.provider]) grouped[m.provider] = [];
      grouped[m.provider].push(m);
    });
    return grouped;
  };

  // Vision models
  const visionModels: ModelInfo[] = [
    { provider: 'openai', model: 'gpt-4-vision-preview', name: 'GPT-4 Vision', description: 'OpenAI vision model' },
    { provider: 'google', model: 'gemini-pro-vision', name: 'Gemini Pro Vision', description: 'Google vision model' },
    { provider: 'anthropic', model: 'claude-3-opus-vision', name: 'Claude 3 Vision', description: 'Anthropic vision model' },
  ];

  // Task types
  const taskTypes = [
    { id: 'low', name: 'Low', description: 'Simple single-page extraction', color: 'emerald', icon: '🟢' },
    { id: 'medium', name: 'Medium', description: 'Multi-page navigation', color: 'amber', icon: '🟡' },
    { id: 'high', name: 'High', description: 'Complex interactive tasks', color: 'red', icon: '🔴' },
  ];

  const detectOutputFormat = (outputInstruction: string): ScrapeRequest['output_format'] => {
    const normalized = outputInstruction.toLowerCase();
    if (normalized.includes('csv')) return 'csv';
    if (normalized.includes('markdown') || normalized.includes('md')) return 'markdown';
    if (normalized.includes('text') || normalized.includes('plain')) return 'text';
    return 'json';
  };

  // Add URL to list
  const handleAddUrl = () => {
    if (newUrl.trim() && !taskInput.urls.includes(newUrl.trim())) {
      const url = newUrl.trim();
      setTaskInput(p => ({ ...p, urls: [...p.urls, url] }));
      // Also add to assets
      setAssets(prev => [...prev, {
        id: Date.now().toString(),
        type: 'url',
        name: url,
        source: 'user',
        content: url,
        timestamp: new Date().toISOString(),
      }]);
      setNewUrl('');
    }
  };

  // Remove URL
  const handleRemoveUrl = (url: string) => {
    setTaskInput(p => ({ ...p, urls: p.urls.filter(u => u !== url) }));
    setAssets(prev => prev.filter(a => a.content !== url));
  };

  // Add memory
  const handleAddMemory = () => {
    if (newMemory.trim()) {
      setMemories(prev => [...prev, {
        id: Date.now().toString(),
        type: 'working',
        content: newMemory.trim(),
        timestamp: new Date().toISOString(),
      }]);
      setNewMemory('');
    }
  };

  // Start task with streaming
  const handleStart = useCallback(() => {
    if (taskInput.urls.length === 0 && !taskInput.instruction) return;
    if (startLockRef.current || abortControllerRef.current) return;
    startLockRef.current = true;
    seenStepKeysRef.current.clear();
    lastSessionInitRef.current = null;
    
    setStats(prev => ({ ...prev, episodes: prev.episodes + 1, steps: 0, totalReward: 0, avgReward: 0 }));
    setIsRunning(true);
    setCurrentView('dashboard');
    setSessionId(null);
    setProgress({ urlIndex: 0, totalUrls: taskInput.urls.length, currentUrl: '' });
    setScrapeResult(null);
    setExtractedData({});
    setCurrentStep(null);
    setAllSteps([]);
    setExpandedStepIndex(null);
    
    // Build scrape request
    const scrapeRequest: ScrapeRequest = {
      assets: taskInput.urls,
      instructions: taskInput.instruction,
      output_instructions: taskInput.outputInstruction || 'Return as JSON',
      output_format: detectOutputFormat(taskInput.outputInstruction),
      complexity: taskInput.taskType,
      model: taskInput.selectedModel.split('/')[1] || 'llama-3.3-70b',
      provider: taskInput.selectedModel.split('/')[0] || 'nvidia',
      enable_memory: true,
      enable_plugins: enabledNonAgentPlugins,
      selected_agents: taskInput.selectedAgents,
      max_steps: 50,
    };
    
    // Add initial log
    setLogs(prev => [...prev, {
      id: Date.now().toString(),
      timestamp: new Date().toISOString(),
      level: 'info',
      message: `Starting scrape with ${taskInput.urls.length} URLs`,
      source: 'system',
    }]);
    
    // Start streaming scrape
    abortControllerRef.current = apiClient.streamScrape(
      scrapeRequest,
      // onInit
      (sid) => {
        if (lastSessionInitRef.current === sid) return;
        lastSessionInitRef.current = sid;
        setSessionId(sid);
        setLogs(prev => [...prev, {
          id: Date.now().toString(),
          timestamp: new Date().toISOString(),
          level: 'info',
          message: `Session started: ${sid.slice(0, 8)}...`,
          source: 'scraper',
        }]);
      },
      // onUrlStart
      (url, index, total) => {
        setProgress({ urlIndex: index, totalUrls: total, currentUrl: url });
        setLogs(prev => [...prev, {
          id: Date.now().toString(),
          timestamp: new Date().toISOString(),
          level: 'info',
          message: `Processing URL ${index + 1}/${total}: ${url}`,
          source: 'scraper',
        }]);
      },
      // onStep
      (step) => {
        const stepKey = `${step.step_number}|${step.action}|${step.url ?? ''}|${step.status}|${step.message}|${step.timestamp}`;
        if (seenStepKeysRef.current.has(stepKey)) return;
        seenStepKeysRef.current.add(stepKey);

        setCurrentStep(step);
        setAllSteps(prev => [...prev, step]);
        setStats(prev => {
          const steps = prev.steps + 1;
          const totalReward = prev.totalReward + step.reward;
          return {
            ...prev,
            steps,
            totalReward,
            avgReward: totalReward / steps,
          };
        });
        
        // Update extracted data
        if (step.extracted_data) {
          setExtractedData(prev => ({ ...prev, ...step.extracted_data }));
        }
        
        setLogs(prev => [...prev, {
          id: Date.now().toString(),
          timestamp: new Date().toISOString(),
          level: step.status === 'failed' ? 'error' : 'info',
          message: `[${step.action}] ${step.message} (reward: ${step.reward.toFixed(2)})`,
          source: step.url?.slice(0, 30) || 'step',
        }]);
      },
      // onUrlComplete
      (url, _index) => {
        setLogs(prev => [...prev, {
          id: Date.now().toString(),
          timestamp: new Date().toISOString(),
          level: 'info',
          message: `Completed: ${url}`,
          source: 'scraper',
        }]);
      },
      // onComplete
      (response) => {
        startLockRef.current = false;
        abortControllerRef.current = null;
        setScrapeResult(response);
        setIsRunning(false);
        setStats(prev => ({
          ...prev,
          totalReward: response.total_reward,
          avgReward: response.total_reward / Math.max(prev.steps, 1),
        }));

        const extractedAssets = Object.entries(response.extracted_data).map(([url, data]) => ({
          id: `${Date.now()}-${url}`,
          type: 'data' as const,
          name: `Data from ${url}`,
          source: 'ai' as const,
          content: JSON.stringify(data),
          timestamp: new Date().toISOString(),
        }));
        setAssets(prev => [...prev, ...extractedAssets]);
        
        setLogs(prev => [...prev, {
          id: Date.now().toString(),
          timestamp: new Date().toISOString(),
          level: response.errors.length > 0 ? 'warn' : 'info',
          message: `Scrape complete! Processed ${response.urls_processed} URLs, total reward: ${response.total_reward.toFixed(2)}`,
          source: 'system',
        }]);
      },
      // onError
      (error, url) => {
        if (!url) {
          startLockRef.current = false;
          abortControllerRef.current = null;
          setIsRunning(false);
        }
        setLogs(prev => [...prev, {
          id: Date.now().toString(),
          timestamp: new Date().toISOString(),
          level: 'error',
          message: `Error${url ? ` (${url})` : ''}: ${error}`,
          source: 'scraper',
        }]);
      }
    );
  }, [taskInput, enabledNonAgentPlugins]);

  // Stop task
  const handleStop = useCallback(() => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
    }
    startLockRef.current = false;
    setIsRunning(false);
    setLogs(prev => [...prev, {
      id: Date.now().toString(),
      timestamp: new Date().toISOString(),
      level: 'warn',
      message: 'Scraping stopped by user',
      source: 'system',
    }]);
  }, []);
  
  // Copy result to clipboard
  const handleCopyResult = useCallback(() => {
    if (scrapeResult?.output) {
      navigator.clipboard.writeText(scrapeResult.output);
      setLogs(prev => [...prev, {
        id: Date.now().toString(),
        timestamp: new Date().toISOString(),
        level: 'info',
        message: 'Result copied to clipboard',
        source: 'system',
      }]);
    }
  }, [scrapeResult]);
  
  // Download result
  const handleDownloadResult = useCallback(() => {
    if (scrapeResult?.output) {
      const fileType =
        scrapeResult.output_format === 'csv'
          ? 'text/csv'
          : scrapeResult.output_format === 'markdown'
            ? 'text/markdown'
            : 'application/json';
      const extension =
        scrapeResult.output_format === 'csv'
          ? 'csv'
          : scrapeResult.output_format === 'markdown'
            ? 'md'
            : scrapeResult.output_format === 'text'
              ? 'txt'
              : 'json';
      const blob = new Blob([scrapeResult.output], { type: fileType });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `scrape-result-${sessionId?.slice(0, 8) || 'unknown'}.${extension}`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    }
  }, [scrapeResult, sessionId]);

  // Format time
  const formatTime = (isoString: string) => {
    return new Date(isoString).toLocaleTimeString('en-US', { hour12: false });
  };

  const safeHostname = (url: string) => {
    try {
      return new URL(url).hostname;
    } catch {
      return url;
    }
  };

  // Log level colors
  const getLogLevelColor = (level: LogEntry['level']) => {
    const colors = { info: 'text-cyan-400', warn: 'text-amber-400', error: 'text-red-400', debug: 'text-gray-400' };
    return colors[level];
  };

  // Check system status
  const normalizedHealthStatus = typeof health?.status === 'string'
    ? health.status.toLowerCase()
    : null;
  const isSystemOnline = !healthError && (
    normalizedHealthStatus === null
    || normalizedHealthStatus === 'healthy'
    || normalizedHealthStatus === 'ok'
    || normalizedHealthStatus === 'ready'
  );

  // Show info popup
  const showInfo = (title: string, description: string, details?: Record<string, string>) => {
    setInfoPopup({ isOpen: true, title, description, details });
  };

  // ========== INPUT VIEW ==========
  if (currentView === 'input') {
    return (
      <div className="h-screen flex flex-col bg-slate-900">
        {/* System Status Banner */}
        {!isSystemOnline && (
          <div className="flex-shrink-0 px-4 py-2 bg-red-500/20 border-b border-red-500/30 flex items-center justify-center gap-2">
            <AlertCircle className="w-4 h-4 text-red-400" />
            <span className="text-sm text-red-400">System is offline. Please check your connection.</span>
          </div>
        )}
        
        {/* Main Content - Full Screen Navy Blue Theme */}
        <div className="flex-1 flex flex-col items-center justify-center p-8 overflow-auto bg-gradient-to-br from-slate-900 via-slate-800 to-cyan-900/30">
          <div className="w-full max-w-4xl space-y-8">
            {/* Header */}
            <div className="text-center mb-12">
              <div className="flex items-center justify-center gap-3 mb-4">
                <div className="p-3 bg-cyan-500/20 rounded-xl border border-cyan-500/30">
                  <Zap className="w-8 h-8 text-cyan-400" />
                </div>
              </div>
              <h1 className="text-4xl font-bold text-white mb-3 tracking-tight">ScrapeRL</h1>
              <p className="text-lg text-cyan-300/70">AI-Powered Intelligent Web Scraping</p>
            </div>

            {/* Assets Section */}
            <div className="bg-slate-800/60 backdrop-blur-sm border border-cyan-500/20 rounded-2xl p-6 shadow-xl shadow-cyan-500/5">
              <div className="flex items-center gap-3 mb-4">
                <div className="p-2 bg-cyan-500/20 rounded-lg">
                  <Link className="w-5 h-5 text-cyan-400" />
                </div>
                <span className="text-lg font-semibold text-white">Assets</span>
                <Badge variant="info" size="sm">{taskInput.urls.length} URLs</Badge>
              </div>
              
              {/* URL Input */}
              <div className="flex gap-3 mb-4">
                <input
                  type="text"
                  placeholder="Enter URL (e.g., https://example.com)"
                  value={newUrl}
                  onChange={(e) => setNewUrl(e.target.value)}
                  onKeyDown={(e) => e.key === 'Enter' && handleAddUrl()}
                  className="flex-1 px-4 py-3 bg-slate-900/70 border border-cyan-500/30 rounded-xl text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/50 focus:border-cyan-500/50 transition-all"
                />
                <button
                  onClick={handleAddUrl}
                  disabled={!newUrl.trim()}
                  className="px-5 py-3 bg-cyan-500/20 hover:bg-cyan-500/30 disabled:bg-slate-700/50 border border-cyan-500/30 disabled:border-slate-600 text-cyan-400 disabled:text-slate-500 rounded-xl font-medium transition-all flex items-center gap-2"
                >
                  <Plus className="w-5 h-5" />
                  Add
                </button>
              </div>
              
              {/* URL List */}
              {taskInput.urls.length > 0 && (
                <div className="flex flex-wrap gap-2 max-h-32 overflow-y-auto p-2 bg-slate-900/50 rounded-xl border border-slate-700/50">
                  {taskInput.urls.map((url, index) => (
                    <div
                      key={index}
                      className="flex items-center gap-2 px-3 py-2 bg-cyan-500/10 border border-cyan-500/30 text-cyan-300 rounded-lg text-sm group hover:bg-cyan-500/20 transition-colors"
                    >
                      <Globe className="w-4 h-4 text-cyan-400" />
                      <span className="max-w-[200px] truncate">{url}</span>
                      <button
                        onClick={() => handleRemoveUrl(url)}
                        className="p-1 opacity-50 group-hover:opacity-100 hover:text-red-400 transition-all"
                      >
                        <X className="w-3 h-3" />
                      </button>
                    </div>
                  ))}
                </div>
              )}
            </div>

            {/* Instructions Section */}
            <div className="bg-slate-800/60 backdrop-blur-sm border border-cyan-500/20 rounded-2xl p-6 shadow-xl shadow-cyan-500/5">
              <div className="flex items-center gap-3 mb-4">
                <div className="p-2 bg-purple-500/20 rounded-lg">
                  <MessageSquare className="w-5 h-5 text-purple-400" />
                </div>
                <span className="text-lg font-semibold text-white">Instructions</span>
              </div>
              <textarea
                placeholder="What should I extract? (e.g., Extract all product names, prices, and descriptions from the page)"
                value={taskInput.instruction}
                onChange={(e) => setTaskInput(p => ({ ...p, instruction: e.target.value }))}
                rows={3}
                className="w-full px-4 py-3 bg-slate-900/70 border border-purple-500/30 rounded-xl text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-purple-500/50 focus:border-purple-500/50 resize-none transition-all"
              />
            </div>

            {/* Output Instructions */}
            <div className="bg-slate-800/60 backdrop-blur-sm border border-cyan-500/20 rounded-2xl p-6 shadow-xl shadow-cyan-500/5">
              <div className="flex items-center gap-3 mb-4">
                <div className="p-2 bg-emerald-500/20 rounded-lg">
                  <FileText className="w-5 h-5 text-emerald-400" />
                </div>
                <span className="text-lg font-semibold text-white">Output Format</span>
              </div>
              <textarea
                placeholder="How should the output be formatted? (e.g., JSON with fields: name, price, description, url)"
                value={taskInput.outputInstruction}
                onChange={(e) => setTaskInput(p => ({ ...p, outputInstruction: e.target.value }))}
                rows={2}
                className="w-full px-4 py-3 bg-slate-900/70 border border-emerald-500/30 rounded-xl text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-emerald-500/50 focus:border-emerald-500/50 resize-none transition-all"
              />
            </div>

            {/* Configuration Options */}
            <div className="flex flex-wrap items-center justify-center gap-4">
              {/* Model */}
              <button
                onClick={() => setShowModelPopup(true)}
                className="px-5 py-3 bg-cyan-500/10 hover:bg-cyan-500/20 border border-cyan-500/30 text-cyan-400 rounded-xl text-sm font-medium transition-all flex items-center gap-2 shadow-lg shadow-cyan-500/5"
              >
                <Cpu className="w-4 h-4" />
                {taskInput.selectedModel ? taskInput.selectedModel.split('/')[1] : 'Select Model'}
              </button>
              
              {/* Vision */}
              <button
                onClick={() => setShowVisionPopup(true)}
                className={classNames(
                  'px-5 py-3 border rounded-xl text-sm font-medium transition-all flex items-center gap-2 shadow-lg',
                  taskInput.selectedVisionModel 
                    ? 'bg-pink-500/10 border-pink-500/30 text-pink-400 shadow-pink-500/5' 
                    : 'bg-slate-700/50 border-slate-600 text-slate-400 hover:border-pink-500/30 hover:text-pink-400'
                )}
              >
                <Eye className="w-4 h-4" />
                {taskInput.selectedVisionModel ? 'Vision ✓' : 'Vision'}
              </button>
              
              {/* Agents */}
              <button
                onClick={() => setShowAgentPopup(true)}
                className="px-5 py-3 bg-purple-500/10 hover:bg-purple-500/20 border border-purple-500/30 text-purple-400 rounded-xl text-sm font-medium transition-all flex items-center gap-2 shadow-lg shadow-purple-500/5"
              >
                <Bot className="w-4 h-4" />
                Agents {taskInput.selectedAgents.length > 0 && `(${taskInput.selectedAgents.length})`}
              </button>
              
              {/* Plugins */}
              <button
                onClick={() => setShowPluginPopup(true)}
                className="px-5 py-3 bg-amber-500/10 hover:bg-amber-500/20 border border-amber-500/30 text-amber-400 rounded-xl text-sm font-medium transition-all flex items-center gap-2 shadow-lg shadow-amber-500/5"
              >
                <Plug className="w-4 h-4" />
                Plugins {enabledNonAgentPlugins.length > 0 && `(${enabledNonAgentPlugins.length})`}
              </button>
              
              {/* Task Type */}
              <button
                onClick={() => setShowTaskTypePopup(true)}
                className={classNames(
                  'px-5 py-3 border rounded-xl text-sm font-medium transition-all flex items-center gap-2 shadow-lg',
                  taskInput.taskType === 'low' && 'bg-emerald-500/10 border-emerald-500/30 text-emerald-400 shadow-emerald-500/5',
                  taskInput.taskType === 'medium' && 'bg-amber-500/10 border-amber-500/30 text-amber-400 shadow-amber-500/5',
                  taskInput.taskType === 'high' && 'bg-red-500/10 border-red-500/30 text-red-400 shadow-red-500/5'
                )}
              >
                <Target className="w-4 h-4" />
                {taskTypes.find(t => t.id === taskInput.taskType)?.icon} {taskInput.taskType.charAt(0).toUpperCase() + taskInput.taskType.slice(1)}
              </button>
            </div>

            {/* Start Button */}
            <div className="flex justify-center pt-6">
              <button
                onClick={handleStart}
                disabled={taskInput.urls.length === 0 || !isSystemOnline}
                className="px-10 py-4 bg-gradient-to-r from-cyan-500 to-cyan-600 hover:from-cyan-400 hover:to-cyan-500 disabled:from-slate-600 disabled:to-slate-700 disabled:cursor-not-allowed text-white rounded-2xl font-semibold text-lg transition-all flex items-center gap-3 shadow-xl shadow-cyan-500/30 disabled:shadow-none transform hover:scale-[1.02] disabled:hover:scale-100"
              >
                <Play className="w-6 h-6" />
                Start Scraping
              </button>
            </div>
          </div>
        </div>

        {/* Popups */}
        {renderPopups()}
      </div>
    );
  }

  // ========== DASHBOARD VIEW ==========
  // Helper function to render popups (used in both views)
  function renderPopups() {
    return (
      <>
        {/* Model Selection Popup */}
        <Popup title="Select Model" isOpen={showModelPopup} onClose={() => setShowModelPopup(false)} size="lg">
          <div className="space-y-4">
            {Object.entries(modelsByProvider()).map(([provider, models]) => (
              <div key={provider}>
                <h4 className="text-xs font-semibold text-gray-400 uppercase mb-2 flex items-center gap-2">
                  <div className="w-2 h-2 rounded-full bg-cyan-400"></div>
                  {provider}
                </h4>
                <div className="space-y-1 pl-4">
                  {models.map((model) => (
                    <button
                      key={`${model.provider}/${model.model}`}
                      onClick={() => {
                        setTaskInput(p => ({ ...p, selectedModel: `${model.provider}/${model.model}` }));
                        setShowModelPopup(false);
                      }}
                      className={classNames(
                        'w-full flex items-center justify-between p-3 rounded-lg transition-colors text-left',
                        taskInput.selectedModel === `${model.provider}/${model.model}`
                          ? 'bg-cyan-500/20 border border-cyan-500/30'
                          : 'bg-gray-900/50 hover:bg-gray-800'
                      )}
                    >
                      <div>
                        <p className="text-sm font-medium text-white">{model.name}</p>
                        <p className="text-xs text-gray-500">{model.description || model.model}</p>
                      </div>
                      {taskInput.selectedModel === `${model.provider}/${model.model}` && (
                        <Check className="w-5 h-5 text-cyan-400" />
                      )}
                    </button>
                  ))}
                </div>
              </div>
            ))}
          </div>
        </Popup>

        {/* Vision Model Popup */}
        <Popup title="Select Vision Model" isOpen={showVisionPopup} onClose={() => setShowVisionPopup(false)}>
          <div className="space-y-2">
            <button
              onClick={() => {
                setTaskInput(p => ({ ...p, selectedVisionModel: '' }));
                setShowVisionPopup(false);
              }}
              className={classNames(
                'w-full flex items-center justify-between p-3 rounded-lg transition-colors text-left',
                !taskInput.selectedVisionModel ? 'bg-gray-700/50 border border-gray-600' : 'bg-gray-900/50 hover:bg-gray-800'
              )}
            >
              <span className="text-sm text-gray-400">None (No vision)</span>
              {!taskInput.selectedVisionModel && <Check className="w-5 h-5 text-gray-400" />}
            </button>
            {visionModels.map((model) => (
              <div key={model.model} className="flex items-center gap-2">
                <button
                  onClick={() => {
                    setTaskInput(p => ({ ...p, selectedVisionModel: model.model }));
                    setShowVisionPopup(false);
                  }}
                  className={classNames(
                    'flex-1 flex items-center justify-between p-3 rounded-lg transition-colors text-left',
                    taskInput.selectedVisionModel === model.model
                      ? 'bg-pink-500/20 border border-pink-500/30'
                      : 'bg-gray-900/50 hover:bg-gray-800'
                  )}
                >
                  <div>
                    <p className="text-sm font-medium text-white">{model.name}</p>
                    <p className="text-xs text-gray-500">{model.provider}</p>
                  </div>
                  {taskInput.selectedVisionModel === model.model && <Check className="w-5 h-5 text-pink-400" />}
                </button>
                <button
                  onClick={() => showInfo(model.name, model.description || 'Vision model for image understanding', { Provider: model.provider, Model: model.model })}
                  className="p-2 text-gray-500 hover:text-gray-300"
                >
                  <Info className="w-4 h-4" />
                </button>
              </div>
            ))}
          </div>
        </Popup>

        {/* Agent Selection Popup */}
        <Popup title="Select Agents" isOpen={showAgentPopup} onClose={() => setShowAgentPopup(false)}>
          <div className="space-y-2">
            {agents.map((agent) => {
              const isSelected = taskInput.selectedAgents.includes(agent.type);
              return (
                <div key={agent.type} className="flex items-center gap-2">
                  <button
                    onClick={() => {
                      setTaskInput(p => ({
                        ...p,
                        selectedAgents: isSelected
                          ? p.selectedAgents.filter(a => a !== agent.type)
                          : [...p.selectedAgents, agent.type],
                      }));
                    }}
                    className={classNames(
                      'flex-1 flex items-center justify-between p-3 rounded-lg transition-colors text-left',
                      isSelected ? 'bg-purple-500/20 border border-purple-500/30' : 'bg-gray-900/50 hover:bg-gray-800'
                    )}
                  >
                    <div>
                      <p className="text-sm font-medium text-white">{agent.name}</p>
                      <p className="text-xs text-gray-500">{agent.description}</p>
                    </div>
                    {isSelected && <Check className="w-5 h-5 text-purple-400" />}
                  </button>
                  <button
                    onClick={() => showInfo(agent.name, agent.description, { Type: agent.type })}
                    className="p-2 text-gray-500 hover:text-gray-300"
                  >
                    <Info className="w-4 h-4" />
                  </button>
                </div>
              );
            })}
          </div>
        </Popup>

        {/* Plugin Selection Popup */}
        <Popup title="Enable Plugins" isOpen={showPluginPopup} onClose={() => setShowPluginPopup(false)} size="lg">
          <div className="space-y-4">
            {Object.entries(installedPlugins).map(([category, plugins]) => {
              if (plugins.length === 0) return null;
              return (
                <div key={category}>
                  <h4 className="text-xs font-semibold text-gray-400 uppercase mb-2">{category}</h4>
                  <div className="space-y-1">
                    {plugins.map((plugin: PluginInfo) => {
                      const isEnabled = taskInput.enabledPlugins.includes(plugin.id);
                      return (
                        <div key={plugin.id} className="flex items-center gap-2">
                          <button
                            onClick={() => {
                              setTaskInput(p => ({
                                ...p,
                                enabledPlugins: isEnabled
                                  ? p.enabledPlugins.filter(a => a !== plugin.id)
                                  : [...p.enabledPlugins, plugin.id],
                              }));
                            }}
                            className={classNames(
                              'flex-1 flex items-center justify-between p-2 rounded-lg transition-colors text-left',
                              isEnabled ? 'bg-amber-500/20 border border-amber-500/30' : 'bg-gray-900/50 hover:bg-gray-800'
                            )}
                          >
                            <span className="text-sm text-white">{plugin.name}</span>
                            {isEnabled && <Check className="w-4 h-4 text-amber-400" />}
                          </button>
                          <button
                            onClick={() => showInfo(plugin.name, plugin.description, { Category: plugin.category, ID: plugin.id })}
                            className="p-2 text-gray-500 hover:text-gray-300"
                          >
                            <Info className="w-4 h-4" />
                          </button>
                        </div>
                      );
                    })}
                  </div>
                </div>
              );
            })}
          </div>
        </Popup>

        {/* Task Type Popup */}
        <Popup title="Select Task Complexity" isOpen={showTaskTypePopup} onClose={() => setShowTaskTypePopup(false)}>
          <div className="space-y-2">
            {taskTypes.map((type) => (
              <button
                key={type.id}
                onClick={() => {
                  setTaskInput(p => ({ ...p, taskType: type.id as 'low' | 'medium' | 'high' }));
                  setShowTaskTypePopup(false);
                }}
                className={classNames(
                  'w-full flex items-center justify-between p-3 rounded-lg transition-colors text-left',
                  taskInput.taskType === type.id
                    ? type.id === 'low' ? 'bg-emerald-500/20 border border-emerald-500/30'
                    : type.id === 'medium' ? 'bg-amber-500/20 border border-amber-500/30'
                    : 'bg-red-500/20 border border-red-500/30'
                    : 'bg-gray-900/50 hover:bg-gray-800'
                )}
              >
                <div className="flex items-center gap-3">
                  <span className="text-xl">{type.icon}</span>
                  <div>
                    <p className="text-sm font-medium text-white">{type.name}</p>
                    <p className="text-xs text-gray-500">{type.description}</p>
                  </div>
                </div>
                {taskInput.taskType === type.id && (
                  <Check className={classNames(
                    'w-5 h-5',
                    type.id === 'low' ? 'text-emerald-400' : type.id === 'medium' ? 'text-amber-400' : 'text-red-400'
                  )} />
                )}
              </button>
            ))}
          </div>
        </Popup>

        {/* Memories Popup */}
        <Popup title="Memories" isOpen={showMemoriesPopup} onClose={() => setShowMemoriesPopup(false)} size="lg">
          <div className="space-y-3">
            {/* Add Memory */}
            <div className="flex gap-2">
              <input
                type="text"
                placeholder="Add a new memory..."
                value={newMemory}
                onChange={(e) => setNewMemory(e.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && handleAddMemory()}
                className="flex-1 px-3 py-2 bg-gray-900/50 border border-gray-700 rounded-lg text-white text-sm"
              />
              <button onClick={handleAddMemory} className="px-3 py-2 bg-purple-500/20 border border-purple-500/30 text-purple-400 rounded-lg">
                <Plus className="w-4 h-4" />
              </button>
            </div>
            
            {/* Memory List */}
            <div className="space-y-2 max-h-80 overflow-y-auto">
              {memories.length === 0 ? (
                <div className="text-center py-8 text-gray-500 text-sm">No memories yet</div>
              ) : (
                memories.map((mem) => (
                  <div key={mem.id} className="p-3 bg-gray-900/50 rounded-lg">
                    <div className="flex items-start justify-between">
                      <p className="text-sm text-gray-300 flex-1">{mem.content}</p>
                      <button
                        onClick={() => setMemories(prev => prev.filter(m => m.id !== mem.id))}
                        className="p-1 text-gray-500 hover:text-red-400 ml-2"
                      >
                        <Trash2 className="w-3 h-3" />
                      </button>
                    </div>
                    <div className="flex items-center gap-2 mt-2">
                      <Badge variant="neutral" size="sm">{mem.type}</Badge>
                      <span className="text-[10px] text-gray-500">{formatTime(mem.timestamp)}</span>
                    </div>
                  </div>
                ))
              )}
            </div>
          </div>
        </Popup>

        {/* Assets Popup */}
        <Popup title="Assets" isOpen={showAssetsPopup} onClose={() => setShowAssetsPopup(false)} size="lg">
          <div className="space-y-3">
            <div className="space-y-2 max-h-80 overflow-y-auto">
              {assets.length === 0 ? (
                <div className="text-center py-8 text-gray-500 text-sm">No assets yet. URLs and fetched data will appear here.</div>
              ) : (
                assets.map((asset) => (
                  <div key={asset.id} className="p-3 bg-gray-900/50 rounded-lg">
                    <div className="flex items-center justify-between">
                      <div className="flex items-center gap-2 flex-1 min-w-0">
                        {asset.type === 'url' && <Link className="w-4 h-4 text-cyan-400 flex-shrink-0" />}
                        {asset.type === 'image' && <ImageIcon className="w-4 h-4 text-pink-400 flex-shrink-0" />}
                        {asset.type === 'file' && <FileText className="w-4 h-4 text-amber-400 flex-shrink-0" />}
                        {asset.type === 'data' && <Database className="w-4 h-4 text-emerald-400 flex-shrink-0" />}
                        <span className="text-sm text-gray-300 truncate">{asset.name}</span>
                      </div>
                      <div className="flex items-center gap-2">
                        <Badge variant={asset.source === 'ai' ? 'info' : 'neutral'} size="sm">{asset.source}</Badge>
                        <button
                          onClick={() => setAssets(prev => prev.filter(a => a.id !== asset.id))}
                          className="p-1 text-gray-500 hover:text-red-400"
                        >
                          <Trash2 className="w-3 h-3" />
                        </button>
                      </div>
                    </div>
                  </div>
                ))
              )}
            </div>
          </div>
        </Popup>

        {/* Info Popup */}
        <InfoPopup
          isOpen={infoPopup.isOpen}
          onClose={() => setInfoPopup({ ...infoPopup, isOpen: false })}
          title={infoPopup.title}
          description={infoPopup.description}
          details={infoPopup.details}
        />
      </>
    );
  }

  return (
    <div className="h-screen flex flex-col bg-slate-900">
      {/* Main 3-Column Layout */}
      <div className="flex-1 flex overflow-hidden">
        {/* Left Sidebar - Active Components */}
        <div className="w-56 flex-shrink-0 bg-slate-800/50 border-r border-cyan-500/10 overflow-y-auto p-3 space-y-3">
          {/* Back to Input */}
          <button
            onClick={() => { setCurrentView('input'); handleStop(); }}
            className="w-full flex items-center gap-2 px-3 py-2 bg-slate-700/50 hover:bg-slate-700 border border-slate-600/50 rounded-xl text-sm text-slate-300 transition-all"
          >
            <ChevronRight className="w-4 h-4 rotate-180" />
            New Task
          </button>

          {/* Progress Bar */}
          {isRunning && progress.totalUrls > 0 && (
            <div className="p-3 bg-cyan-500/10 border border-cyan-500/20 rounded-xl">
              <div className="flex items-center justify-between mb-2">
                <span className="text-xs text-cyan-400 font-medium">Progress</span>
                <span className="text-xs text-cyan-300">{progress.urlIndex + 1}/{progress.totalUrls}</span>
              </div>
              <div className="h-2 bg-slate-700 rounded-full overflow-hidden">
                <div 
                  className="h-full bg-gradient-to-r from-cyan-500 to-cyan-400 transition-all duration-500"
                  style={{ width: `${((progress.urlIndex + 1) / progress.totalUrls) * 100}%` }}
                />
              </div>
              <p className="text-[10px] text-slate-400 mt-2 truncate">{progress.currentUrl}</p>
            </div>
          )}

          {/* Agents */}
          <Accordion title="Agents" icon={Bot} badge={taskInput.selectedAgents.length} color="text-purple-400" defaultOpen>
            {taskInput.selectedAgents.length === 0 ? (
              <p className="text-xs text-slate-500 p-2">No agents selected</p>
            ) : (
              taskInput.selectedAgents.map((agentId) => {
                const agent = agents.find(a => a.type === agentId);
                return (
                  <div key={agentId} className="flex items-center justify-between p-2 bg-purple-500/10 border border-purple-500/30 rounded-lg">
                    <div className="flex items-center gap-2">
                      <div className={`w-2 h-2 rounded-full ${isRunning ? 'bg-emerald-400 animate-pulse' : 'bg-slate-500'}`}></div>
                      <span className="text-xs text-white">{agent?.name || agentId}</span>
                    </div>
                    <button onClick={() => showInfo(agent?.name || agentId, agent?.description || '', { Type: agentId })} className="text-slate-500 hover:text-slate-300">
                      <Info className="w-3 h-3" />
                    </button>
                  </div>
                );
              })
            )}
          </Accordion>

          {/* Plugins */}
          <Accordion title="Plugins" icon={Plug} badge={enabledNonAgentPlugins.length} color="text-amber-400">
            {enabledNonAgentPlugins.length === 0 ? (
              <p className="text-xs text-slate-500 p-2">No plugins enabled</p>
            ) : (
              enabledNonAgentPlugins.map((pluginId) => (
                <div key={pluginId} className="p-2 bg-amber-500/10 border border-amber-500/30 rounded-lg">
                  <span className="text-xs text-white">{pluginId}</span>
                </div>
              ))
            )}
          </Accordion>

          {/* System Status */}
          <div className="p-3 bg-slate-900/50 border border-slate-700/50 rounded-xl">
            <div className="flex items-center justify-between mb-2">
              <span className="text-xs text-slate-400">Status</span>
              <Badge variant={isSystemOnline ? 'success' : 'error'} size="sm">
                {isRunning ? 'Running' : isSystemOnline ? 'Online' : 'Offline'}
              </Badge>
            </div>
            <div className="flex items-center justify-between mb-2">
              <span className="text-xs text-slate-400">Model</span>
              <span className="text-xs text-cyan-300">{taskInput.selectedModel.split('/')[1]}</span>
            </div>
            <div className="flex items-center justify-between">
              <span className="text-xs text-slate-400">Complexity</span>
              <span className={classNames(
                'text-xs',
                taskInput.taskType === 'low' ? 'text-emerald-400' :
                taskInput.taskType === 'medium' ? 'text-amber-400' : 'text-red-400'
              )}>{taskInput.taskType.toUpperCase()}</span>
            </div>
          </div>
        </div>

        {/* Center Content */}
        <div className="flex-1 flex flex-col overflow-hidden bg-gradient-to-br from-slate-900 via-slate-800/50 to-cyan-900/10">
          {/* Stats Header - Session-based, start at 0 */}
          <div className="flex-shrink-0 p-4 bg-slate-800/30 border-b border-cyan-500/10">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-8">
                <div className="flex items-center gap-3">
                  <div className="p-2 bg-cyan-500/20 rounded-lg">
                    <Layers className="w-5 h-5 text-cyan-400" />
                  </div>
                  <div>
                    <p className="text-2xl font-bold text-white">{stats.episodes}</p>
                    <p className="text-xs text-slate-500">Episodes</p>
                  </div>
                </div>

                <div className="flex items-center gap-3">
                  <div className="p-2 bg-purple-500/20 rounded-lg">
                    <Target className="w-5 h-5 text-purple-400" />
                  </div>
                  <div>
                    <p className="text-2xl font-bold text-white">{stats.steps}</p>
                    <p className="text-xs text-slate-500">Steps</p>
                  </div>
                </div>

                <div className="flex items-center gap-3">
                  <div className="p-2 bg-emerald-500/20 rounded-lg">
                    <TrendingUp className="w-5 h-5 text-emerald-400" />
                  </div>
                  <div>
                    <p className="text-2xl font-bold text-white">{stats.totalReward.toFixed(2)}</p>
                    <p className="text-xs text-slate-500">Total Reward</p>
                  </div>
                </div>
              </div>

              <div className="flex items-center gap-4">
                {/* Control Buttons */}
                {isRunning ? (
                  <button
                    onClick={handleStop}
                    className="px-6 py-2.5 bg-red-500 hover:bg-red-600 text-white rounded-xl font-medium transition-all flex items-center gap-2 shadow-lg shadow-red-500/20"
                  >
                    <Pause className="w-4 h-4" />
                    Stop
                  </button>
                ) : (
                  <button
                    onClick={handleStart}
                    disabled={taskInput.urls.length === 0}
                    className="px-6 py-2.5 bg-gradient-to-r from-cyan-500 to-cyan-600 hover:from-cyan-400 hover:to-cyan-500 disabled:from-slate-600 disabled:to-slate-700 text-white rounded-xl font-medium transition-all flex items-center gap-2 shadow-lg shadow-cyan-500/20"
                  >
                    <Play className="w-4 h-4" />
                    Start
                  </button>
                )}
              </div>
            </div>
          </div>

          {/* Main Visualization Area */}
          <div className="flex-1 overflow-y-auto p-4">
            <div className="h-full bg-slate-900/50 border border-cyan-500/10 rounded-2xl p-4">
              {isRunning ? (
                <div className="h-full flex flex-col">
                  {/* Steps Accordion */}
                  <div className="flex-shrink-0 mb-4">
                    <div className="flex items-center justify-between mb-3">
                      <div className="flex items-center gap-2">
                        <Layers className="w-5 h-5 text-cyan-400 animate-pulse" />
                        <span className="text-sm font-semibold text-white">Execution Steps</span>
                        <Badge variant="info" size="sm">{allSteps.length}</Badge>
                      </div>
                      {currentStep && (
                        <Badge 
                          variant={currentStep.status === 'completed' ? 'success' : currentStep.status === 'failed' ? 'error' : 'info'}
                        >
                          {currentStep.action.toUpperCase()}
                        </Badge>
                      )}
                    </div>
                    
                    {/* Step Accordion List */}
                    <div className="space-y-2 max-h-[300px] overflow-y-auto pr-2">
                      {allSteps.length === 0 ? (
                        <div className="p-4 bg-slate-800/50 rounded-xl text-center">
                          <div className="animate-spin w-6 h-6 border-2 border-cyan-500 border-t-transparent rounded-full mx-auto mb-2"></div>
                          <p className="text-sm text-slate-400">Initializing scraper...</p>
                        </div>
                      ) : (
                        allSteps.map((step, index) => (
                          <StepAccordionItem
                            key={`${step.step_number}-${index}`}
                            step={step}
                            isExpanded={expandedStepIndex === index}
                            onToggle={() => setExpandedStepIndex(expandedStepIndex === index ? null : index)}
                            isLatest={index === allSteps.length - 1}
                          />
                        ))
                      )}
                    </div>
                  </div>

                  {/* Extracted Data Preview */}
                  <div className="flex-1 overflow-auto">
                    <div className="flex items-center gap-2 mb-3">
                      <Database className="w-5 h-5 text-emerald-400" />
                      <span className="text-sm font-semibold text-white">Live Extracted Data</span>
                    </div>
                    <div className="p-4 bg-slate-800/50 rounded-xl min-h-[150px] max-h-[250px] overflow-auto">
                      <pre className="text-xs text-slate-300 font-mono whitespace-pre-wrap">
                        {Object.keys(extractedData).length > 0 
                          ? JSON.stringify(extractedData, null, 2)
                          : '{\n  "status": "extracting...",\n  "data": []\n}'
                        }
                      </pre>
                    </div>
                  </div>
                </div>
              ) : scrapeResult ? (
                <div className="h-full flex flex-col">
                  {/* Result Header */}
                  <div className="flex items-center justify-between mb-4">
                    <div className="flex items-center gap-3">
                      <div className={`p-2 rounded-lg ${scrapeResult.status === 'completed' ? 'bg-emerald-500/20' : 'bg-amber-500/20'}`}>
                        {scrapeResult.status === 'completed' ? (
                          <CheckCircle className="w-6 h-6 text-emerald-400" />
                        ) : (
                          <AlertCircle className="w-6 h-6 text-amber-400" />
                        )}
                      </div>
                      <div>
                        <h3 className="text-lg font-semibold text-white">Scraping Complete</h3>
                        <p className="text-sm text-slate-400">
                          {scrapeResult.urls_processed} URLs • {scrapeResult.total_steps} steps • {scrapeResult.duration_seconds.toFixed(1)}s • Reward: {scrapeResult.total_reward.toFixed(2)}
                        </p>
                      </div>
                    </div>
                    <div className="flex items-center gap-2">
                      <button
                        onClick={handleCopyResult}
                        className="px-4 py-2 bg-cyan-500/20 hover:bg-cyan-500/30 border border-cyan-500/30 text-cyan-400 rounded-lg text-sm font-medium transition-all flex items-center gap-2"
                      >
                        <Copy className="w-4 h-4" />
                        Copy
                      </button>
                      <button
                        onClick={handleDownloadResult}
                        className="px-4 py-2 bg-emerald-500/20 hover:bg-emerald-500/30 border border-emerald-500/30 text-emerald-400 rounded-lg text-sm font-medium transition-all flex items-center gap-2"
                      >
                        <Download className="w-4 h-4" />
                        Download
                      </button>
                    </div>
                  </div>

                  {/* Steps Summary (collapsed) */}
                  {allSteps.length > 0 && (
                    <div className="mb-4">
                      <Accordion title={`Execution Steps (${allSteps.length})`} icon={Layers} color="text-cyan-400">
                        <div className="space-y-1 max-h-[200px] overflow-y-auto">
                          {allSteps.map((step, index) => (
                            <div 
                              key={`result-${step.step_number}-${index}`}
                              className="flex items-center justify-between p-2 bg-slate-800/50 rounded-lg text-xs"
                            >
                              <div className="flex items-center gap-2">
                                {React.createElement(getStepIcon(step.action), { 
                                  className: classNames('w-3 h-3', getStepColor(step.action, step.status).split(' ')[0]) 
                                })}
                                <span className="text-slate-300">{step.action}</span>
                              </div>
                              <div className="flex items-center gap-2">
                                <span className="text-emerald-400">+{step.reward.toFixed(2)}</span>
                                {step.status === 'completed' ? (
                                  <CheckCircle className="w-3 h-3 text-emerald-400" />
                                ) : step.status === 'failed' ? (
                                  <XCircle className="w-3 h-3 text-red-400" />
                                ) : (
                                  <Clock className="w-3 h-3 text-cyan-400" />
                                )}
                              </div>
                            </div>
                          ))}
                        </div>
                      </Accordion>
                    </div>
                  )}

                  {/* Result Content - Full Output */}
                  <div className="flex-1 overflow-auto">
                    <div className="flex items-center gap-2 mb-2">
                      <FileJson className="w-4 h-4 text-amber-400" />
                      <span className="text-sm font-medium text-white">Output ({scrapeResult.output_format})</span>
                    </div>
                    <div className="p-4 bg-slate-800/50 rounded-xl overflow-auto max-h-[400px]">
                      <pre className="text-sm text-slate-300 font-mono whitespace-pre-wrap">
                        {scrapeResult.output}
                      </pre>
                    </div>
                  </div>

                  {/* Errors */}
                  {scrapeResult.errors.length > 0 && (
                    <div className="mt-4 p-3 bg-red-500/10 border border-red-500/20 rounded-xl">
                      <h4 className="text-sm font-medium text-red-400 mb-2">Errors ({scrapeResult.errors.length})</h4>
                      {scrapeResult.errors.map((err, idx) => (
                        <p key={idx} className="text-xs text-red-300">{err}</p>
                      ))}
                    </div>
                  )}
                </div>
              ) : (
                <div className="h-full flex flex-col items-center justify-center text-center">
                  <div className="w-20 h-20 bg-cyan-500/10 rounded-2xl flex items-center justify-center mb-6 border border-cyan-500/20">
                    <Globe className="w-10 h-10 text-cyan-400" />
                  </div>
                  <h3 className="text-xl font-semibold text-white mb-2">Ready to Scrape</h3>
                  <p className="text-sm text-slate-400 max-w-md mb-4">
                    {taskInput.urls.length} URLs loaded. Click Start to begin scraping.
                  </p>
                  <div className="flex flex-wrap gap-2 justify-center">
                    {taskInput.urls.slice(0, 3).map((url, idx) => (
                      <Badge key={idx} variant="info" size="sm">{safeHostname(url)}</Badge>
                    ))}
                    {taskInput.urls.length > 3 && (
                      <Badge variant="neutral" size="sm">+{taskInput.urls.length - 3} more</Badge>
                    )}
                  </div>
                </div>
              )}
            </div>
          </div>

          {/* Logs Terminal */}
          <div className="flex-shrink-0 h-36 bg-slate-900 border-t border-cyan-500/10">
            <div className="flex items-center justify-between px-4 py-2 border-b border-slate-800">
              <div className="flex items-center gap-2">
                <Terminal className="w-4 h-4 text-cyan-400" />
                <span className="text-xs font-medium text-slate-300">Live Logs</span>
                {isRunning && <div className="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></div>}
              </div>
              <button onClick={() => setLogs([])} className="text-xs text-slate-500 hover:text-slate-300 transition-colors">
                Clear
              </button>
            </div>
            <div className="h-[calc(100%-32px)] overflow-y-auto p-3 font-mono text-xs">
              {logs.length === 0 ? (
                <p className="text-slate-600">Waiting for logs...</p>
              ) : (
                logs.slice(-50).map((log) => (
                  <div key={log.id} className="flex items-start gap-2 py-0.5">
                    <span className="text-slate-600">[{formatTime(log.timestamp)}]</span>
                    <span className={getLogLevelColor(log.level)}>[{log.level.toUpperCase()}]</span>
                    {log.source && <span className="text-purple-400">[{log.source}]</span>}
                    <span className="text-slate-300">{log.message}</span>
                  </div>
                ))
              )}
            </div>
          </div>
        </div>

        {/* Right Sidebar */}
        <div className="w-72 flex-shrink-0 bg-slate-800/50 border-l border-cyan-500/10 overflow-y-auto p-4 space-y-4">
          {/* Input Summary */}
          <div className="bg-slate-900/50 border border-slate-700/50 rounded-xl p-4">
            <div className="flex items-center justify-between mb-4">
              <div className="flex items-center gap-2">
                <FileText className="w-5 h-5 text-cyan-400" />
                <span className="text-sm font-semibold text-white">Task Input</span>
              </div>
              <button
                onClick={() => setCurrentView('input')}
                className="text-xs text-cyan-400 hover:text-cyan-300 transition-colors"
              >
                Edit
              </button>
            </div>
            <div className="space-y-3 text-sm">
              <div>
                <p className="text-slate-500 text-xs mb-1">URLs ({taskInput.urls.length})</p>
                <p className="text-slate-300 truncate">{taskInput.urls[0] || 'None'}</p>
              </div>
              <div>
                <p className="text-slate-500 text-xs mb-1">Instruction</p>
                <p className="text-slate-300 line-clamp-2">{taskInput.instruction || 'None'}</p>
              </div>
              <div>
                <p className="text-slate-500 text-xs mb-1">Output Format</p>
                <p className="text-slate-300 truncate">{taskInput.outputInstruction || 'JSON'}</p>
              </div>
            </div>
          </div>

          {/* Memories */}
          <div className="bg-slate-900/50 border border-slate-700/50 rounded-xl p-4">
            <div className="flex items-center justify-between mb-4">
              <div className="flex items-center gap-2">
                <Database className="w-5 h-5 text-purple-400" />
                <span className="text-sm font-semibold text-white">Memory</span>
              </div>
              <button onClick={() => setShowMemoriesPopup(true)} className="text-xs text-purple-400 hover:text-purple-300">
                Manage
              </button>
            </div>
            <div className="grid grid-cols-2 gap-2">
              <div className="p-3 bg-slate-800/50 rounded-lg text-center">
                <p className="text-lg font-bold text-emerald-400">{memoryData?.short_term_count || 0}</p>
                <p className="text-[10px] text-slate-500">Short-term</p>
              </div>
              <div className="p-3 bg-slate-800/50 rounded-lg text-center">
                <p className="text-lg font-bold text-cyan-400">{memoryData?.working_count || 0}</p>
                <p className="text-[10px] text-slate-500">Working</p>
              </div>
              <div className="p-3 bg-slate-800/50 rounded-lg text-center">
                <p className="text-lg font-bold text-purple-400">{memoryData?.long_term_count || 0}</p>
                <p className="text-[10px] text-slate-500">Long-term</p>
              </div>
              <div className="p-3 bg-slate-800/50 rounded-lg text-center">
                <p className="text-lg font-bold text-amber-400">{memories.length}</p>
                <p className="text-[10px] text-slate-500">Session</p>
              </div>
            </div>
          </div>

          {/* Assets */}
          <div className="bg-slate-900/50 border border-slate-700/50 rounded-xl p-4">
            <div className="flex items-center justify-between mb-4">
              <div className="flex items-center gap-2">
                <FolderOpen className="w-5 h-5 text-amber-400" />
                <span className="text-sm font-semibold text-white">Assets</span>
              </div>
              <Badge variant="neutral" size="sm">{assets.length}</Badge>
            </div>
            
            {assets.length === 0 ? (
              <p className="text-center py-4 text-slate-500 text-xs">No assets yet</p>
            ) : (
              <div className="space-y-2 max-h-40 overflow-y-auto">
                {assets.slice(0, 5).map((asset) => (
                  <div key={asset.id} className="flex items-center justify-between p-2 bg-slate-800/50 rounded-lg text-xs">
                    <div className="flex items-center gap-2 min-w-0">
                      {asset.type === 'url' && <Link className="w-3 h-3 text-cyan-400 flex-shrink-0" />}
                      {asset.type === 'data' && <Database className="w-3 h-3 text-emerald-400 flex-shrink-0" />}
                      <span className="text-slate-300 truncate">{asset.name.slice(0, 25)}</span>
                    </div>
                    <Badge variant={asset.source === 'ai' ? 'info' : 'neutral'} size="sm">{asset.source}</Badge>
                  </div>
                ))}
              </div>
            )}
            
            <button
              onClick={() => setShowAssetsPopup(true)}
              className="w-full mt-3 px-3 py-2 bg-amber-500/10 hover:bg-amber-500/20 border border-amber-500/30 text-amber-400 rounded-lg text-xs font-medium transition-all"
            >
              View All Assets
            </button>
          </div>
        </div>
      </div>

      {/* Popups */}
      {renderPopups()}
    </div>
  );
};

export default Dashboard;
