import { useState, useEffect, useRef, useCallback, useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
import {
  Rocket, Shield, ChevronDown, ChevronUp, Loader2,
  AlertTriangle, CheckCircle2, Globe, Lock, Bug, MessageSquare,
  FileText, ScrollText, X, ExternalLink, Download, Sparkles, Trash2,
  Brain, Wrench, Layers, Clock, Search, Activity, Terminal, Crosshair
} from 'lucide-react'
import { PieChart, Pie, Cell, Tooltip as RechartsTooltip, ResponsiveContainer } from 'recharts'
import { agentApi, reportsApi, promptsApi, cliAgentApi } from '../services/api'
import type { AgentStatus, AgentFinding, AgentLog, Prompt, ToolExecution, ContainerStatus } from '../types'
import VulnAgentGrid from '../components/VulnAgentGrid'

// ─── Constants ────────────────────────────────────────────────────────────────

const PHASES = [
  { key: 'recon', label: 'Reconnaissance', icon: Globe, range: [0, 20] as const },
  { key: 'agents', label: 'Agent Grid (108 agents)', icon: Layers, range: [20, 85] as const },
  { key: 'final', label: 'Finalization', icon: Shield, range: [85, 100] as const },
]

const STREAMS = [
  { key: 'recon', label: 'Recon', icon: Globe, color: 'blue', activeUntil: 20 },
  { key: 'agents', label: 'Agent Grid', icon: Brain, color: 'purple', activeUntil: 85 },
  { key: 'final', label: 'Report', icon: Wrench, color: 'orange', activeUntil: 100 },
] as const

const STREAM_COLORS: Record<string, { bg: string; text: string; border: string; pulse: string }> = {
  blue:   { bg: 'bg-blue-500/20',   text: 'text-blue-400',   border: 'border-blue-500/40',   pulse: 'bg-blue-400' },
  purple: { bg: 'bg-purple-500/20', text: 'text-purple-400', border: 'border-purple-500/40', pulse: 'bg-purple-400' },
  orange: { bg: 'bg-orange-500/20', text: 'text-orange-400', border: 'border-orange-500/40', pulse: 'bg-orange-400' },
}

const SEVERITY_COLORS: Record<string, string> = {
  critical: 'bg-red-500', high: 'bg-orange-500', medium: 'bg-yellow-500',
  low: 'bg-blue-500', info: 'bg-gray-500',
}

const SEVERITY_BORDER: Record<string, string> = {
  critical: 'border-red-500/40', high: 'border-orange-500/40', medium: 'border-yellow-500/40',
  low: 'border-blue-500/40', info: 'border-gray-500/40',
}

const SEVERITY_CHART_COLORS: Record<string, string> = {
  critical: '#ef4444', high: '#f97316', medium: '#eab308', low: '#3b82f6', info: '#6b7280',
}

const CONFIDENCE_STYLES: Record<string, string> = {
  green: 'bg-green-500/15 text-green-400 border-green-500/30',
  yellow: 'bg-yellow-500/15 text-yellow-400 border-yellow-500/30',
  red: 'bg-red-500/15 text-red-400 border-red-500/30',
}

const LOG_FILTERS = [
  { key: 'all', label: 'All', color: '' },
  { key: 'recon', label: 'Recon', color: 'text-blue-400' },
  { key: 'agents', label: 'Agents', color: 'text-green-400' },
  { key: 'judge', label: 'Validation', color: 'text-amber-300' },
  { key: 'final', label: 'Final', color: 'text-cyan-400' },
  { key: 'error', label: 'Errors', color: 'text-red-400' },
]

const SESSIONS_KEY = 'neurosploit_autopentest_sessions'
const LEGACY_SESSION_KEY = 'neurosploit_autopentest_session'
const POLL_INTERVAL = 1500
const POLL_INTERVAL_ERROR = 5000
const TOAST_DURATION = 5000
const MAX_TOASTS = 5

// ─── Types ────────────────────────────────────────────────────────────────────

interface SavedSession {
  agentId: string
  target: string
  startedAt: string
  status: 'running' | 'completed' | 'error' | 'stopped'
}

interface Toast {
  id: string
  message: string
  severity: string
  timestamp: number
}

// ─── Utility Functions ────────────────────────────────────────────────────────

function phaseFromProgress(progress: number): number {
  if (progress < 20) return 0
  if (progress < 85) return 1
  return 2
}

function formatElapsed(totalSeconds: number): string {
  const h = Math.floor(totalSeconds / 3600)
  const m = Math.floor((totalSeconds % 3600) / 60)
  const s = totalSeconds % 60
  return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
}

function logMessageColor(message: string): string {
  if (message.startsWith('[STREAM 1]')) return 'text-blue-400'
  if (message.startsWith('[STREAM 2]')) return 'text-purple-400'
  if (message.startsWith('[STREAM 3]')) return 'text-orange-400'
  if (message.startsWith('[TOOL]')) return 'text-orange-300'
  if (message.startsWith('[DEEP]')) return 'text-cyan-400'
  if (message.startsWith('[FINAL]')) return 'text-green-400'
  if (message.startsWith('[CONTAINER]')) return 'text-cyan-300'
  if (message.startsWith('[CLI-AGENT]')) return 'text-pink-400'
  if (message.startsWith('[PHASE]')) return 'text-yellow-400'
  if (message.startsWith('[PHASE FAIL]')) return 'text-red-400'
  if (message.startsWith('[BANNER]')) return 'text-teal-400'
  if (message.startsWith('[WAF]')) return 'text-amber-400'
  if (message.startsWith('[PLAYBOOK]')) return 'text-indigo-400'
  if (message.startsWith('[SITE ANALYZER]')) return 'text-emerald-400'
  if (message.startsWith('[MD-AGENTS]')) return 'text-cyan-300'
  if (message.startsWith('[AGENT GRID]')) return 'text-green-400'
  if (message.startsWith('[PHASE 1]')) return 'text-blue-300'
  if (message.startsWith('[PHASE 2]')) return 'text-purple-300'
  if (message.startsWith('[PHASE 3]')) return 'text-yellow-300'
  if (message.startsWith('[RECON]')) return 'text-blue-400'
  if (message.startsWith('[CVE]')) return 'text-red-300'
  if (message.startsWith('[CHAIN]')) return 'text-orange-300'
  if (message.startsWith('[JUDGE]')) return 'text-amber-300'
  if (message.includes('Starting (real HTTP)')) return 'text-green-300'
  return ''
}

function matchLogFilter(log: AgentLog, filter: string): boolean {
  if (filter === 'all') return true
  if (filter === 'stream1') return log.message.startsWith('[STREAM 1]')
  if (filter === 'stream2') return log.message.startsWith('[STREAM 2]')
  if (filter === 'stream3') return log.message.startsWith('[STREAM 3]')
  if (filter === 'deep') return log.message.startsWith('[DEEP]')
  if (filter === 'container') return log.message.startsWith('[CONTAINER]')
  if (filter === 'cli_agent') return log.message.startsWith('[CLI-AGENT]')
  if (filter === 'error') return log.level === 'error' || log.level === 'warning'
  return true
}

function getConfidenceDisplay(finding: { confidence_score?: number; confidence?: string }): { score: number; color: string; label: string } | null {
  let score: number | null = null
  if (typeof finding.confidence_score === 'number') {
    score = finding.confidence_score
  } else if (finding.confidence) {
    const parsed = Number(finding.confidence)
    if (!isNaN(parsed)) score = parsed
    else {
      const map: Record<string, number> = { high: 90, medium: 60, low: 30 }
      score = map[finding.confidence.toLowerCase()] ?? null
    }
  }
  if (score === null) return null
  const color = score >= 90 ? 'green' : score >= 60 ? 'yellow' : 'red'
  const label = score >= 90 ? 'Confirmed' : score >= 60 ? 'Likely' : 'Low'
  return { score, color, label }
}

// ─── Sub-Components ───────────────────────────────────────────────────────────

function StreamBadge({ stream, progress, isRunning }: {
  stream: typeof STREAMS[number]; progress: number; isRunning: boolean
}) {
  const active = isRunning && progress < stream.activeUntil
  const done = progress >= stream.activeUntil
  const colors = STREAM_COLORS[stream.color]
  const Icon = stream.icon

  return (
    <div className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full border text-xs font-medium transition-all duration-300 ${
      active ? `${colors.bg} ${colors.text} ${colors.border}` :
      done   ? 'bg-dark-700/50 text-dark-400 border-dark-600' :
               'bg-dark-900 text-dark-500 border-dark-700'
    }`}>
      {active && (
        <span className="relative flex h-2 w-2">
          <span className={`animate-ping absolute inline-flex h-full w-full rounded-full ${colors.pulse} opacity-75`} />
          <span className={`relative inline-flex rounded-full h-2 w-2 ${colors.pulse}`} />
        </span>
      )}
      {done && <CheckCircle2 className="w-3 h-3 text-green-500" />}
      {!active && !done && <Icon className="w-3 h-3" />}
      <span>{stream.label}</span>
    </div>
  )
}

function LiveStatsDashboard({ status, elapsedSeconds, toolExecutions }: {
  status: AgentStatus; elapsedSeconds: number; toolExecutions: ToolExecution[]
}) {
  return (
    <div className="grid grid-cols-2 lg:grid-cols-4 gap-3 mb-4">
      <div className="bg-dark-800 border border-dark-700 rounded-xl p-4">
        <div className="flex items-center gap-2 mb-1">
          <Clock className="w-4 h-4 text-blue-400" />
          <span className="text-[10px] text-dark-400 uppercase font-semibold tracking-wider">Elapsed</span>
        </div>
        <span className="text-2xl font-mono text-white tabular-nums">{formatElapsed(elapsedSeconds)}</span>
      </div>
      <div className="bg-dark-800 border border-dark-700 rounded-xl p-4">
        <div className="flex items-center gap-2 mb-1">
          <Bug className="w-4 h-4 text-red-400" />
          <span className="text-[10px] text-dark-400 uppercase font-semibold tracking-wider">Findings</span>
        </div>
        <div className="flex items-baseline gap-2">
          <span className="text-2xl font-mono text-white">{status.findings_count}</span>
          {(status.rejected_findings_count ?? 0) > 0 && (
            <span className="text-xs text-dark-500">+{status.rejected_findings_count} rej</span>
          )}
        </div>
      </div>
      <div className="bg-dark-800 border border-dark-700 rounded-xl p-4">
        <div className="flex items-center gap-2 mb-1">
          <Terminal className="w-4 h-4 text-cyan-400" />
          <span className="text-[10px] text-dark-400 uppercase font-semibold tracking-wider">Tools Run</span>
        </div>
        <span className="text-2xl font-mono text-white">{toolExecutions.length}</span>
      </div>
      <div className="bg-dark-800 border border-dark-700 rounded-xl p-4">
        <div className="flex items-center gap-2 mb-1">
          <Activity className="w-4 h-4 text-green-400" />
          <span className="text-[10px] text-dark-400 uppercase font-semibold tracking-wider">Progress</span>
        </div>
        <div className="flex items-baseline gap-2">
          <span className="text-2xl font-mono text-white">{status.progress}%</span>
          <span className="text-xs text-dark-500 truncate">{status.phase || 'Init'}</span>
        </div>
      </div>
    </div>
  )
}

function ToolExecutionRow({ exec, expanded, onToggle }: {
  exec: ToolExecution; expanded: boolean; onToggle: () => void
}) {
  const hasExpandable = !!(exec.stdout_preview || exec.stderr_preview || exec.reason)
  return (
    <div className="border-b border-dark-800 last:border-0">
      <button
        onClick={hasExpandable ? onToggle : undefined}
        className={`w-full grid grid-cols-[50px_70px_1fr_50px_65px_55px_20px] sm:grid-cols-[60px_80px_1fr_50px_70px_60px_24px] gap-2 items-center px-2 py-2 text-xs transition-colors ${
          hasExpandable ? 'hover:bg-dark-700/50 cursor-pointer' : 'cursor-default'
        }`}
      >
        <span className="font-mono text-dark-500 truncate">{exec.task_id?.slice(0, 6) || '---'}</span>
        <span className="text-cyan-400 font-medium truncate">{exec.tool}</span>
        <span className="text-dark-300 truncate text-left" title={exec.command}>{exec.command}</span>
        <span className={`font-bold text-center ${exec.exit_code === 0 ? 'text-green-400' : exec.exit_code === -1 ? 'text-yellow-400' : exec.exit_code !== null ? 'text-red-400' : 'text-dark-500'}`}>
          {exec.exit_code === null || exec.exit_code === undefined ? '...' : exec.exit_code === -1 ? 'ERR' : exec.exit_code}
        </span>
        <span className="text-dark-400 text-right">{exec.duration != null && exec.duration > 0 ? `${exec.duration.toFixed(1)}s` : exec.exit_code === -1 ? 'N/A' : '---'}</span>
        <span className="text-dark-300 text-center">{exec.findings_count ?? 0}</span>
        <span className="text-dark-500">
          {hasExpandable ? (expanded ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />) : null}
        </span>
      </button>
      {expanded && (
        <div className="px-3 pb-3 space-y-2 bg-dark-900/50 border-t border-dark-800">
          {exec.reason && (
            <p className="text-xs text-dark-400 pt-2"><span className="text-dark-500 font-medium">Reason: </span>{exec.reason}</p>
          )}
          {exec.stdout_preview && (
            <div>
              <p className="text-[10px] font-medium text-dark-500 mb-1 uppercase tracking-wider">stdout</p>
              <pre className="bg-dark-950 rounded p-2 text-xs text-green-400/80 max-h-[200px] overflow-y-auto whitespace-pre-wrap font-mono">{exec.stdout_preview}</pre>
            </div>
          )}
          {exec.stderr_preview && (
            <div>
              <p className="text-[10px] font-medium text-dark-500 mb-1 uppercase tracking-wider">stderr</p>
              <pre className="bg-dark-950 rounded p-2 text-xs text-red-400/70 max-h-[200px] overflow-y-auto whitespace-pre-wrap font-mono">{exec.stderr_preview}</pre>
            </div>
          )}
          {exec.container_name && (
            <p className="text-[10px] text-dark-500">Container: <span className="font-mono text-dark-400">{exec.container_name}</span></p>
          )}
        </div>
      )}
    </div>
  )
}

function SeverityMiniChart({ sevCounts }: { sevCounts: Record<string, number> }) {
  const data = ['critical', 'high', 'medium', 'low', 'info']
    .filter(s => (sevCounts[s] || 0) > 0)
    .map(s => ({ name: s, value: sevCounts[s] || 0 }))

  if (data.length === 0) return null

  return (
    <div className="w-20 h-20 flex-shrink-0">
      <ResponsiveContainer width="100%" height="100%">
        <PieChart>
          <Pie data={data} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={32} innerRadius={16} strokeWidth={0}>
            {data.map(entry => (
              <Cell key={entry.name} fill={SEVERITY_CHART_COLORS[entry.name]} />
            ))}
          </Pie>
          <RechartsTooltip
            contentStyle={{ backgroundColor: '#1a1a2e', border: '1px solid #334155', borderRadius: '8px', fontSize: '11px', padding: '4px 8px' }}
            itemStyle={{ color: '#e2e8f0' }}
            formatter={(value: number, name: string) => [`${value}`, name.charAt(0).toUpperCase() + name.slice(1)]}
          />
        </PieChart>
      </ResponsiveContainer>
    </div>
  )
}

function LogViewer({ logs, logFilter, setLogFilter, logSearch, setLogSearch, logsEndRef }: {
  logs: AgentLog[]; logFilter: string; setLogFilter: (f: string) => void
  logSearch: string; setLogSearch: (s: string) => void; logsEndRef: React.RefObject<HTMLDivElement>
}) {
  const filteredLogs = useMemo(() =>
    logs.filter(log => {
      if (!matchLogFilter(log, logFilter)) return false
      if (logSearch && !log.message.toLowerCase().includes(logSearch.toLowerCase())) return false
      return true
    }), [logs, logFilter, logSearch]
  )

  return (
    <div className="bg-dark-900 rounded-xl overflow-hidden">
      <div className="flex items-center gap-1.5 p-2 border-b border-dark-700 flex-wrap">
        {LOG_FILTERS.map(f => (
          <button
            key={f.key}
            onClick={() => setLogFilter(f.key)}
            className={`px-2 py-0.5 rounded text-[10px] font-medium transition-colors ${
              logFilter === f.key ? 'bg-dark-700 text-white' : `text-dark-500 hover:text-dark-300 ${f.color}`
            }`}
          >
            {f.label}
          </button>
        ))}
        <div className="flex-1 min-w-0" />
        <div className="relative">
          <Search className="w-3 h-3 absolute left-2 top-1/2 -translate-y-1/2 text-dark-500 pointer-events-none" />
          <input
            type="text"
            value={logSearch}
            onChange={e => setLogSearch(e.target.value)}
            placeholder="Search..."
            className="pl-6 pr-2 py-1 bg-dark-800 border border-dark-700 rounded text-xs text-white placeholder-dark-500 focus:outline-none focus:border-dark-500 w-32 sm:w-40"
          />
        </div>
        <span className="text-[10px] text-dark-600 tabular-nums">{filteredLogs.length}/{logs.length}</span>
      </div>
      <div className="p-3 max-h-[400px] overflow-y-auto font-mono text-xs space-y-px">
        {filteredLogs.length === 0 ? (
          <p className="text-dark-500 text-center py-4">
            {logs.length === 0 ? 'Waiting for logs...' : 'No logs match filter'}
          </p>
        ) : (
          filteredLogs.map((log, i) => (
            <div key={i} className="flex gap-2 py-0.5 hover:bg-dark-800/30 rounded px-1 -mx-1">
              <span className="text-dark-600 flex-shrink-0 text-[10px] tabular-nums">{log.time?.slice(11, 19) || ''}</span>
              <span className={`flex-shrink-0 uppercase w-10 text-[10px] ${
                log.level === 'error' ? 'text-red-400' :
                log.level === 'warning' ? 'text-yellow-400' :
                log.level === 'success' ? 'text-green-400' :
                log.level === 'info' ? 'text-blue-400' : 'text-dark-500'
              }`}>{log.level}</span>
              <span className={`break-all ${logMessageColor(log.message) || (log.source === 'llm' ? 'text-purple-400' : 'text-dark-300')}`}>
                {log.message}
              </span>
            </div>
          ))
        )}
        <div ref={logsEndRef} />
      </div>
    </div>
  )
}

function ToastContainer({ toasts, onDismiss }: { toasts: Toast[]; onDismiss: (id: string) => void }) {
  if (toasts.length === 0) return null
  return (
    <div className="fixed top-4 right-4 z-50 space-y-2 max-w-sm pointer-events-none">
      {toasts.map(toast => (
        <div
          key={toast.id}
          style={{ animation: 'fadeSlideIn 0.3s ease-out' }}
          className={`flex items-center gap-2 px-4 py-3 rounded-xl border shadow-2xl pointer-events-auto ${
            toast.severity === 'critical' ? 'bg-red-950/90 border-red-500/40 text-red-300' :
            toast.severity === 'high' ? 'bg-orange-950/90 border-orange-500/40 text-orange-300' :
            toast.severity === 'medium' ? 'bg-yellow-950/90 border-yellow-500/40 text-yellow-300' :
            toast.severity === 'completed' ? 'bg-green-950/90 border-green-500/40 text-green-300' :
            toast.severity === 'error' ? 'bg-red-950/90 border-red-500/40 text-red-300' :
            'bg-dark-800/95 border-dark-600 text-dark-300'
          }`}
        >
          {toast.severity === 'completed' ? (
            <CheckCircle2 className="w-4 h-4 flex-shrink-0" />
          ) : toast.severity === 'error' || toast.severity === 'critical' ? (
            <AlertTriangle className="w-4 h-4 flex-shrink-0" />
          ) : (
            <Bug className="w-4 h-4 flex-shrink-0" />
          )}
          <span className="text-sm flex-1 line-clamp-2">{toast.message}</span>
          <button onClick={() => onDismiss(toast.id)} className="text-dark-500 hover:text-white flex-shrink-0">
            <X className="w-3 h-3" />
          </button>
        </div>
      ))}
    </div>
  )
}

// ─── Main Component ───────────────────────────────────────────────────────────

export default function AutoPentestPage() {
  const navigate = useNavigate()

  // Form state
  const [target, setTarget] = useState('')
  const [multiTarget, setMultiTarget] = useState(false)
  const [targets, setTargets] = useState('')
  const [subdomainDiscovery, setSubdomainDiscovery] = useState(false)
  const [enableKaliSandbox, setEnableKaliSandbox] = useState(false)
  const [showAuth, setShowAuth] = useState(false)
  const [authType, setAuthType] = useState<string>('')
  const [authValue, setAuthValue] = useState('')
  const [showPrompt, setShowPrompt] = useState(false)
  const [customPrompt, setCustomPrompt] = useState('')
  const [savedPrompts, setSavedPrompts] = useState<Prompt[]>([])
  const [selectedPromptIds, setSelectedPromptIds] = useState<string[]>([])
  const [showSavedPrompts, setShowSavedPrompts] = useState(false)

  // Model selection
  const [availableModels, setAvailableModels] = useState<Array<{ provider_id: string; provider_name: string; default_model: string; tier: number; available_models: string[] }>>([])
  const [selectedProvider, setSelectedProvider] = useState('anthropic')
  const [selectedModel, setSelectedModel] = useState('claude-sonnet-4-20250514')

  // MD Agent selection
  const [availableMdAgents, setAvailableMdAgents] = useState<Array<{ name: string; display_name: string; category: string }>>([])
  const [selectedMdAgents, setSelectedMdAgents] = useState<string[]>([])
  const [showAgentSelector, setShowAgentSelector] = useState(false)

  // CLI Agent mode
  const [testMode, setTestMode] = useState<'auto_pentest' | 'cli_agent' | 'full_llm_pentest'>('auto_pentest')
  const [cliProviders, setCliProviders] = useState<Array<{ id: string; name: string; connected: boolean; account_label?: string; source?: string }>>([])
  const [cliEnabled, setCliEnabled] = useState(false)
  const [selectedCliProvider, setSelectedCliProvider] = useState('')
  const [methodologies, setMethodologies] = useState<Array<{ name: string; path: string; size_human: string; is_default: boolean }>>([])
  const [selectedMethodology, setSelectedMethodology] = useState('')
  const [enableCliPhase, setEnableCliPhase] = useState(false)  // Checkbox in auto_pentest mode

  // Learning stats (TP/FP per vuln type)
  const [learningStats, setLearningStats] = useState<Record<string, { tp: number; fp: number }>>({})

  // History
  const [showHistory, setShowHistory] = useState(false)
  const [history, setHistory] = useState<Array<any>>([])
  const [historyLoading, setHistoryLoading] = useState(false)

  // Triple-check
  const [tripleCheckScanId, setTripleCheckScanId] = useState<string | null>(null)
  const [tripleCheckProvider, setTripleCheckProvider] = useState('')
  const [tripleCheckModel, setTripleCheckModel] = useState('')

  // Multi-session state
  const [sessions, setSessions] = useState<SavedSession[]>([])
  const [activeSessionIdx, setActiveSessionIdx] = useState(-1)
  const [maxConcurrent, setMaxConcurrent] = useState(5)
  const [statusCache, setStatusCache] = useState<Record<string, AgentStatus>>({})
  const [error, setError] = useState<string | null>(null)

  // Derived from active session
  const activeSession = activeSessionIdx >= 0 && activeSessionIdx < sessions.length ? sessions[activeSessionIdx] : null
  const agentId = activeSession?.agentId ?? null
  const isRunning = activeSession?.status === 'running'
  const status = agentId ? statusCache[agentId] ?? null : null

  // Live stats
  const [elapsedSeconds, setElapsedSeconds] = useState(0)

  // UI state
  const [activeTab, setActiveTab] = useState<'findings' | 'logs' | 'agents'>('findings')
  const [expandedFinding, setExpandedFinding] = useState<string | null>(null)
  const [expandedTool, setExpandedTool] = useState<string | null>(null)
  const [findingsFilter, setFindingsFilter] = useState<'confirmed' | 'rejected' | 'all'>('all')
  const [logFilter, setLogFilter] = useState('all')
  const [logSearch, setLogSearch] = useState('')

  // Toast notifications
  const [toasts, setToasts] = useState<Toast[]>([])

  // Finding animations
  const [newFindingIds, setNewFindingIds] = useState<Set<string>>(new Set())

  // Connection state
  const [connectionLost, setConnectionLost] = useState(false)

  // Logs & Report
  const [logs, setLogs] = useState<AgentLog[]>([])
  const [generatingReport, setGeneratingReport] = useState(false)
  const [reportId, setReportId] = useState<string | null>(null)

  // Refs
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null)
  const logsEndRef = useRef<HTMLDivElement>(null)
  const failCountRef = useRef<Record<string, number>>({})
  const seenFindingIdsRef = useRef<Set<string>>(new Set())
  const prevPhaseRef = useRef<string | null>(null)
  const prevStatusRef = useRef<string | null>(null)
  const newFindingTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  // ─── Toast Helper ─────────────────────────────────────────────────────────

  const addToast = useCallback((message: string, severity: string = 'info') => {
    const id = `${Date.now()}-${Math.random().toString(36).slice(2, 6)}`
    setToasts(prev => [...prev.slice(-(MAX_TOASTS - 1)), { id, message, severity, timestamp: Date.now() }])
    setTimeout(() => setToasts(prev => prev.filter(t => t.id !== id)), TOAST_DURATION)
  }, [])

  const dismissToast = useCallback((id: string) => {
    setToasts(prev => prev.filter(t => t.id !== id))
  }, [])

  // ─── Mount: restore sessions + load prompts + models ───────────────────────

  useEffect(() => {
    // Migrate legacy single-session key
    try {
      const legacy = localStorage.getItem(LEGACY_SESSION_KEY)
      if (legacy) {
        const old = JSON.parse(legacy)
        const migrated: SavedSession = {
          agentId: old.agentId,
          target: old.target,
          startedAt: old.startedAt,
          status: 'running',
        }
        setSessions([migrated])
        setActiveSessionIdx(0)
        localStorage.removeItem(LEGACY_SESSION_KEY)
        localStorage.setItem(SESSIONS_KEY, JSON.stringify([migrated]))
      }
    } catch { /* ignore */ }

    // Restore multi-session array
    try {
      const saved = localStorage.getItem(SESSIONS_KEY)
      if (saved) {
        const parsed: SavedSession[] = JSON.parse(saved)
        setSessions(parsed)
        const runningIdx = parsed.findIndex(s => s.status === 'running')
        setActiveSessionIdx(runningIdx >= 0 ? runningIdx : parsed.length > 0 ? 0 : -1)
      }
    } catch { /* ignore */ }

    // Fetch backend limits
    agentApi.listActive().then(data => {
      setMaxConcurrent(data.max_concurrent)
    }).catch(() => {})

    promptsApi.list().then(p => setSavedPrompts(p || [])).catch(() => {})

    // Fetch available LLM providers/models
    fetch('/api/v1/providers/available-models')
      .then(r => r.json())
      .then(data => setAvailableModels(data.models || []))
      .catch(() => {})

    // Fetch available MD agents
    fetch('/api/v1/agent/md-agents')
      .then(r => r.json())
      .then(data => setAvailableMdAgents(data.agents || []))
      .catch(() => {})

    // Fetch learning stats (TP/FP counts per vuln type)
    fetch('/api/v1/scans/vulnerabilities/learning/stats')
      .then(r => r.json())
      .then(data => {
        if (data.vuln_types) {
          const stats: Record<string, { tp: number; fp: number }> = {}
          for (const [vt, info] of Object.entries(data.vuln_types as Record<string, any>)) {
            stats[vt] = { tp: info.true_positives || 0, fp: info.false_positives || 0 }
          }
          setLearningStats(stats)
        }
      })
      .catch(() => {})

    // Fetch CLI agent providers and methodologies
    cliAgentApi.getProviders()
      .then(data => {
        setCliProviders(data.providers || [])
        setCliEnabled(data.enabled || false)
        const connected = (data.providers || []).find((p: any) => p.connected)
        if (connected) setSelectedCliProvider(connected.id)
      })
      .catch(() => {})
    cliAgentApi.getMethodologies()
      .then(data => {
        setMethodologies(data.methodologies || [])
        const def = (data.methodologies || []).find((m: any) => m.is_default)
        if (def) setSelectedMethodology(def.path)
      })
      .catch(() => {})

    // Restore statusCache for ALL saved sessions on mount
    try {
      const saved = localStorage.getItem(SESSIONS_KEY)
      if (saved) {
        const parsed: SavedSession[] = JSON.parse(saved)
        for (const sess of parsed) {
          agentApi.getStatus(sess.agentId)
            .then(s => {
              setStatusCache(prev => ({ ...prev, [sess.agentId]: s }))
              if (s.status !== sess.status && (s.status === 'completed' || s.status === 'error' || s.status === 'stopped')) {
                setSessions(prev => prev.map(p =>
                  p.agentId === sess.agentId ? { ...p, status: s.status as SavedSession['status'] } : p
                ))
              }
            })
            .catch(() => {})
        }
      }
    } catch { /* ignore */ }
  }, [])

  // Persist sessions to localStorage
  useEffect(() => {
    if (sessions.length > 0) {
      localStorage.setItem(SESSIONS_KEY, JSON.stringify(sessions))
    } else {
      localStorage.removeItem(SESSIONS_KEY)
    }
  }, [sessions])

  // ─── Elapsed Time Ticker ──────────────────────────────────────────────────

  useEffect(() => {
    if (!status?.started_at) return
    const startTime = new Date(status.started_at).getTime()
    if (isRunning) {
      // Live ticker while scan is active
      const tick = () => setElapsedSeconds(Math.floor((Date.now() - startTime) / 1000))
      tick()
      const id = setInterval(tick, 1000)
      return () => clearInterval(id)
    } else {
      // Completed/stopped/error — compute final duration from timestamps
      const endTime = status.completed_at
        ? new Date(status.completed_at).getTime()
        : Date.now()
      setElapsedSeconds(Math.max(0, Math.floor((endTime - startTime) / 1000)))
    }
  }, [isRunning, status?.started_at, status?.completed_at])

  // ─── Polling — ALL running sessions + active session logs ─────────────────

  useEffect(() => {
    const runningSessions = sessions.filter(s => s.status === 'running')
    const needsPoll = runningSessions.length > 0 || agentId
    if (!needsPoll) return

    const poll = async () => {
      // Poll all running sessions
      for (const sess of runningSessions) {
        try {
          const s = await agentApi.getStatus(sess.agentId)
          setStatusCache(prev => ({ ...prev, [sess.agentId]: s }))
          failCountRef.current[sess.agentId] = 0

          if (s.status === 'completed' || s.status === 'error' || s.status === 'stopped') {
            setSessions(prev => prev.map(p =>
              p.agentId === sess.agentId
                ? { ...p, status: s.status as SavedSession['status'] }
                : p
            ))
            // Toast for completion of active session
            if (sess.agentId === agentId) {
              if (s.status === 'completed') addToast(`Pentest complete! ${s.findings_count} findings`, 'completed')
              else if (s.status === 'error') addToast('Pentest failed', 'error')
              else if (s.status === 'stopped') addToast('Pentest stopped', 'info')
            }
          }
        } catch (err: any) {
          const httpStatus = err?.response?.status
          const fails = (failCountRef.current[sess.agentId] || 0) + 1
          failCountRef.current[sess.agentId] = fails

          if (httpStatus === 404 || fails >= 3) {
            setSessions(prev => prev.map(p =>
              p.agentId === sess.agentId ? { ...p, status: 'stopped' } : p
            ))
          }
        }
      }

      // Fetch status + logs for active session
      if (agentId) {
        try {
          const s = await agentApi.getStatus(agentId)
          setStatusCache(prev => ({ ...prev, [agentId]: s }))

          // Connection restored
          if (connectionLost) setConnectionLost(false)

          // Phase change detection
          if (prevPhaseRef.current && s.phase && s.phase !== prevPhaseRef.current) {
            addToast(`Phase: ${s.phase}`, 'info')
          }
          prevPhaseRef.current = s.phase || null

          // Status transition detection
          if (prevStatusRef.current === 'running' && (s.status === 'completed' || s.status === 'error' || s.status === 'stopped')) {
            // Handled above in the running sessions loop
          }
          prevStatusRef.current = s.status

          // New finding detection
          const currentIds = new Set((s.findings || []).map((f: AgentFinding) => f.id))
          if (seenFindingIdsRef.current.size > 0) {
            const newIds = [...currentIds].filter(id => !seenFindingIdsRef.current.has(id))
            if (newIds.length > 0) {
              newIds.forEach(id => {
                const f = s.findings?.find((x: AgentFinding) => x.id === id)
                if (f) addToast(`${f.severity.toUpperCase()}: ${f.title}`, f.severity)
              })
              setNewFindingIds(new Set(newIds))
              if (newFindingTimerRef.current) clearTimeout(newFindingTimerRef.current)
              newFindingTimerRef.current = setTimeout(() => setNewFindingIds(new Set()), 3000)
            }
          }
          seenFindingIdsRef.current = currentIds
        } catch {
          const fails = (failCountRef.current[agentId] || 0) + 1
          failCountRef.current[agentId] = fails
          if (fails >= 3) setConnectionLost(true)
        }

        try {
          const logData = await agentApi.getLogs(agentId, 300)
          setLogs(logData.logs || [])
        } catch { /* ignore */ }
      }
    }

    poll()
    const interval = connectionLost ? POLL_INTERVAL_ERROR : POLL_INTERVAL
    pollRef.current = setInterval(poll, interval)
    return () => { if (pollRef.current) clearInterval(pollRef.current) }
  }, [sessions, agentId, connectionLost, addToast])

  // Auto-scroll logs disabled — user controls scroll position

  // ─── History ──────────────────────────────────────────────────────────────

  const fetchHistory = useCallback(async () => {
    setHistoryLoading(true)
    try {
      const data = await agentApi.getHistory(1, 50)
      setHistory(data.history || [])
    } catch { /* ignore */ }
    setHistoryLoading(false)
  }, [])

  // ─── Triple-Check ─────────────────────────────────────────────────────────

  const handleTripleCheck = async (scanId: string) => {
    try {
      const resp = await agentApi.tripleCheck(scanId, tripleCheckProvider || undefined, tripleCheckModel || undefined)
      const newSession: SavedSession = {
        agentId: resp.agent_id,
        target: `Triple-Check: ${scanId.slice(0, 8)}`,
        startedAt: new Date().toISOString(),
        status: 'running',
      }
      const updated = [...sessions, newSession]
      setSessions(updated)
      setActiveSessionIdx(updated.length - 1)
      localStorage.setItem(SESSIONS_KEY, JSON.stringify(updated))
      setTripleCheckScanId(null)
      addToast('Triple-check started', 'info')
    } catch (e: any) {
      setError(e.response?.data?.detail || 'Triple-check failed')
    }
  }

  // ─── Start / Stop / Clear ──────────────────────────────────────────────────

  const handleStart = async () => {
    const primaryTarget = target.trim()
    if (!primaryTarget) return

    const runningCount = sessions.filter(s => s.status === 'running').length
    if (runningCount >= maxConcurrent) {
      setError(`Maximum ${maxConcurrent} concurrent scans reached. Stop one first.`)
      return
    }

    setError(null)
    setLogs([])
    setReportId(null)
    seenFindingIdsRef.current = new Set()
    prevPhaseRef.current = null
    prevStatusRef.current = null

    try {
      const targetList = multiTarget
        ? targets.split('\n').map(t => t.trim()).filter(Boolean)
        : undefined

      const isCliMode = testMode === 'cli_agent'
      const resp = await agentApi.autoPentest(primaryTarget, {
        mode: testMode,
        subdomain_discovery: subdomainDiscovery,
        targets: targetList,
        auth_type: authType || undefined,
        auth_value: authValue || undefined,
        prompt: customPrompt.trim() || undefined,
        enable_kali_sandbox: isCliMode ? true : (enableKaliSandbox || undefined),
        custom_prompt_ids: selectedPromptIds.length > 0 ? selectedPromptIds : undefined,
        preferred_provider: selectedProvider || undefined,
        preferred_model: selectedModel || undefined,
        enable_cli_agent: isCliMode || enableCliPhase || undefined,
        cli_agent_provider: (isCliMode || enableCliPhase) ? (selectedCliProvider || undefined) : undefined,
        methodology_file: (isCliMode || enableCliPhase) ? (selectedMethodology || undefined) : undefined,
        selected_md_agents: selectedMdAgents.length > 0 ? selectedMdAgents : undefined,
      })

      const newSession: SavedSession = {
        agentId: resp.agent_id,
        target: primaryTarget,
        startedAt: new Date().toISOString(),
        status: 'running',
      }

      setSessions(prev => {
        const updated = [...prev, newSession]
        setActiveSessionIdx(updated.length - 1)
        return updated
      })
      setTarget('')
      addToast('Auto pentest started', 'info')
    } catch (err: any) {
      if (err?.response?.status === 429) {
        setError(err.response.data.detail)
      } else {
        setError(err?.response?.data?.detail || err?.message || 'Failed to start pentest')
      }
    }
  }

  const handleStop = async () => {
    if (!agentId) return
    try {
      await agentApi.stop(agentId)
      setSessions(prev => prev.map(s =>
        s.agentId === agentId ? { ...s, status: 'stopped' as const } : s
      ))
    } catch { /* ignore */ }
  }

  const handleClearSession = (agentIdToClear?: string) => {
    const idToRemove = agentIdToClear || agentId
    if (idToRemove) {
      setSessions(prev => prev.filter(s => s.agentId !== idToRemove))
      if (activeSession?.agentId === idToRemove) {
        setActiveSessionIdx(-1)
      }
    } else {
      setSessions([])
      setActiveSessionIdx(-1)
    }
    setLogs([])
    setError(null)
    setReportId(null)
    setElapsedSeconds(0)
    setNewFindingIds(new Set())
    setConnectionLost(false)
    seenFindingIdsRef.current = new Set()
    prevPhaseRef.current = null
    prevStatusRef.current = null
  }

  // ─── AI Report ─────────────────────────────────────────────────────────────

  const handleGenerateAiReport = useCallback(async (reportProvider?: string, reportModel?: string) => {
    if (!status?.scan_id) return
    setGeneratingReport(true)
    try {
      const report = await reportsApi.generateAiReport({
        scan_id: status.scan_id,
        title: `AI Pentest Report - ${activeSession?.target || target}`,
        preferred_provider: reportProvider || selectedProvider || undefined,
        preferred_model: reportModel || selectedModel || undefined,
      })
      setReportId(report.id)
      addToast('AI Report generated', 'completed')
    } catch (err: any) {
      setError(err?.response?.data?.detail || 'Failed to generate AI report')
    } finally {
      setGeneratingReport(false)
    }
  }, [status?.scan_id, activeSession?.target, target, selectedProvider, selectedModel, addToast])

  // ─── Derived State ──────────────────────────────────────────────────────────

  const currentPhaseIdx = status ? phaseFromProgress(status.progress) : -1
  const findings = status?.findings || []
  const rejectedFindings = status?.rejected_findings || []
  const allFindings = useMemo(() => [...findings, ...rejectedFindings], [findings, rejectedFindings])
  const displayFindings = findingsFilter === 'confirmed' ? findings
    : findingsFilter === 'rejected' ? rejectedFindings : allFindings
  const sevCounts = useMemo(() =>
    findings.reduce((acc, f) => { acc[f.severity] = (acc[f.severity] || 0) + 1; return acc }, {} as Record<string, number>),
    [findings]
  )
  const toolExecutions: ToolExecution[] = status?.tool_executions || []
  const containerStatus: ContainerStatus | undefined = status?.container_status

  // ─── Render ─────────────────────────────────────────────────────────────────

  return (
    <div className="min-h-screen flex flex-col items-center py-8 sm:py-12 px-3 sm:px-4">
      {/* Inline keyframes */}
      <style>{`
        @keyframes fadeSlideIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }
        @keyframes glowPulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 0.8; } }
      `}</style>

      {/* Toast Notifications */}
      <ToastContainer toasts={toasts} onDismiss={dismissToast} />

      {/* Connection Lost Banner */}
      {connectionLost && (
        <div className="w-full max-w-4xl mb-3 p-3 bg-yellow-500/10 border border-yellow-500/20 rounded-xl flex items-center gap-2" style={{ animation: 'fadeSlideIn 0.3s ease-out' }}>
          <AlertTriangle className="w-4 h-4 text-yellow-400 flex-shrink-0" />
          <span className="text-yellow-400 text-sm flex-1">Connection issues — retrying...</span>
          <Loader2 className="w-4 h-4 text-yellow-400 animate-spin flex-shrink-0" />
        </div>
      )}

      {/* Header */}
      <div className="text-center mb-8 sm:mb-10">
        <div className="inline-flex items-center justify-center w-16 h-16 bg-green-500/20 rounded-2xl mb-4">
          <Rocket className="w-8 h-8 text-green-400" />
        </div>
        <h1 className="text-3xl font-bold text-white mb-2">Auto Pentest</h1>
        <p className="text-dark-400 max-w-md mx-auto text-sm">
          One-click comprehensive penetration test. 100 vulnerability types, AI-powered analysis, full report.
        </p>
        <button
          onClick={() => { setShowHistory(!showHistory); if (!showHistory) fetchHistory() }}
          className="mt-3 inline-flex items-center gap-2 px-4 py-2 bg-dark-800 border border-dark-600 rounded-lg text-sm text-dark-300 hover:text-white hover:border-dark-500 transition-all"
        >
          <ScrollText className="w-4 h-4" />
          {showHistory ? 'Hide History' : 'Test History'}
        </button>
      </div>

      {/* History Panel */}
      {showHistory && (
        <div className="w-full max-w-4xl mb-6 bg-dark-800 border border-dark-700 rounded-xl p-4" style={{ animation: 'fadeSlideIn 0.3s ease-out' }}>
          <div className="flex items-center justify-between mb-3">
            <h3 className="text-white font-semibold text-sm">Past Pentest Runs</h3>
            <button onClick={() => setShowHistory(false)} className="text-dark-400 hover:text-white transition-colors">
              <X className="w-4 h-4" />
            </button>
          </div>
          {historyLoading ? (
            <div className="flex justify-center py-6"><Loader2 className="w-6 h-6 animate-spin text-dark-400" /></div>
          ) : history.length === 0 ? (
            <p className="text-dark-500 text-sm text-center py-4">No completed scans yet</p>
          ) : (
            <div className="space-y-2 max-h-80 overflow-y-auto">
              {history.map((h: any) => (
                <div key={h.scan_id} className="flex items-center justify-between px-3 py-2 bg-dark-900 rounded-lg border border-dark-700 hover:border-dark-600 transition-all">
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2">
                      <span className={`text-xs px-1.5 py-0.5 rounded font-medium ${
                        h.status === 'completed' ? 'bg-green-500/20 text-green-400' :
                        h.status === 'stopped' ? 'bg-yellow-500/20 text-yellow-400' :
                        'bg-red-500/20 text-red-400'
                      }`}>{h.status}</span>
                      <span className="text-white text-sm truncate">{h.target}</span>
                    </div>
                    <div className="flex items-center gap-3 mt-1 text-xs text-dark-400">
                      <span>{h.findings_count} findings</span>
                      {h.critical_count > 0 && <span className="text-red-400">{h.critical_count}C</span>}
                      {h.high_count > 0 && <span className="text-orange-400">{h.high_count}H</span>}
                      {h.medium_count > 0 && <span className="text-yellow-400">{h.medium_count}M</span>}
                      <span>{h.endpoints_count} endpoints</span>
                      {h.duration_seconds && <span>{Math.round(h.duration_seconds / 60)}min</span>}
                      <span>{new Date(h.created_at).toLocaleDateString()}</span>
                    </div>
                  </div>
                  <div className="flex items-center gap-2 ml-3 flex-shrink-0">
                    <button
                      onClick={() => navigate(`/scan/${h.scan_id}`)}
                      className="px-2 py-1 text-xs bg-blue-500/20 text-blue-400 rounded hover:bg-blue-500/30 transition-colors"
                    >View</button>
                    <button
                      onClick={() => setTripleCheckScanId(h.scan_id)}
                      className="px-2 py-1 text-xs bg-purple-500/20 text-purple-400 rounded hover:bg-purple-500/30 transition-colors"
                    >Triple-Check</button>
                    <button
                      onClick={() => { setTarget(h.target); setShowHistory(false) }}
                      className="px-2 py-1 text-xs bg-green-500/20 text-green-400 rounded hover:bg-green-500/30 transition-colors"
                    >Re-run</button>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Triple-Check Modal */}
      {tripleCheckScanId && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50" onClick={() => setTripleCheckScanId(null)}>
          <div className="bg-dark-800 border border-dark-700 rounded-xl p-6 w-96 max-w-[90vw]" onClick={e => e.stopPropagation()} style={{ animation: 'fadeSlideIn 0.3s ease-out' }}>
            <h3 className="text-white font-semibold mb-4">Triple-Check Findings</h3>
            <p className="text-dark-400 text-sm mb-4">
              Re-validate all findings from this scan using a different AI model.
            </p>
            <div className="space-y-3 mb-4">
              <div>
                <label className="text-xs text-dark-400 mb-1 block">Provider</label>
                <select
                  value={tripleCheckProvider}
                  onChange={e => { setTripleCheckProvider(e.target.value); setTripleCheckModel('') }}
                  className="w-full px-3 py-2 bg-dark-900 border border-dark-600 rounded-lg text-white text-sm"
                >
                  <option value="">Auto (different from original)</option>
                  {availableModels.map(p => (
                    <option key={p.provider_id} value={p.provider_id}>{p.provider_name}</option>
                  ))}
                </select>
              </div>
              <div>
                <label className="text-xs text-dark-400 mb-1 block">Model</label>
                <select
                  value={tripleCheckModel}
                  onChange={e => setTripleCheckModel(e.target.value)}
                  className="w-full px-3 py-2 bg-dark-900 border border-dark-600 rounded-lg text-white text-sm"
                >
                  <option value="">Auto</option>
                  {(tripleCheckProvider
                    ? availableModels.find(p => p.provider_id === tripleCheckProvider)?.available_models || []
                    : [...new Set(availableModels.flatMap(p => p.available_models))]
                  ).map(m => (
                    <option key={m} value={m}>{m}</option>
                  ))}
                </select>
              </div>
            </div>
            <div className="flex gap-3">
              <button
                onClick={() => setTripleCheckScanId(null)}
                className="flex-1 px-4 py-2 bg-dark-700 text-dark-300 rounded-lg hover:bg-dark-600 text-sm transition-colors"
              >Cancel</button>
              <button
                onClick={() => handleTripleCheck(tripleCheckScanId!)}
                className="flex-1 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-500 text-sm font-medium transition-colors"
              >Start Triple-Check</button>
            </div>
          </div>
        </div>
      )}

      {/* Multi-session tabs */}
      {sessions.length > 0 && (
        <div className="w-full max-w-4xl flex items-center gap-2 mb-4 overflow-x-auto pb-1">
          {sessions.map((sess, idx) => {
            const isActive = idx === activeSessionIdx
            const sessStatus = statusCache[sess.agentId]
            const progress = sessStatus?.progress ?? 0

            return (
              <button
                key={sess.agentId}
                onClick={() => { setActiveSessionIdx(idx); setLogs([]); setReportId(null); seenFindingIdsRef.current = new Set(); prevPhaseRef.current = null }}
                className={`flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium transition-all whitespace-nowrap ${
                  isActive
                    ? 'bg-green-500/20 text-green-400 border border-green-500/30'
                    : 'bg-dark-800 text-dark-400 border border-dark-700 hover:border-dark-600'
                }`}
              >
                {sess.status === 'running' && <Loader2 className="w-3 h-3 animate-spin text-blue-400" />}
                {sess.status === 'completed' && <CheckCircle2 className="w-3 h-3 text-green-400" />}
                {sess.status === 'error' && <AlertTriangle className="w-3 h-3 text-red-400" />}
                {sess.status === 'stopped' && <X className="w-3 h-3 text-dark-400" />}
                <span className="truncate max-w-[120px]">{sess.target}</span>
                <span className={`text-[10px] tabular-nums ${
                  sess.status === 'running' ? 'text-blue-400' :
                  sess.status === 'completed' ? 'text-green-400' :
                  sess.status === 'error' ? 'text-red-400' : 'text-dark-400'
                }`}>{progress}%</span>
                <span
                  onClick={(e) => { e.stopPropagation(); handleClearSession(sess.agentId) }}
                  className="ml-1 text-dark-500 hover:text-red-400 cursor-pointer"
                >
                  <X className="w-3 h-3" />
                </span>
              </button>
            )
          })}
          <span className="text-dark-500 text-[10px] ml-auto whitespace-nowrap tabular-nums">
            {sessions.filter(s => s.status === 'running').length}/{maxConcurrent} slots
          </span>
        </div>
      )}

      {/* ═══ START FORM ═══ */}
      {!agentId && (
        <div className="w-full max-w-2xl bg-dark-800 border border-dark-700 rounded-2xl p-6 sm:p-8">
          {/* URL Input */}
          <div className="mb-6">
            <label className="block text-sm font-medium text-dark-300 mb-2">Target URL</label>
            <input
              type="url"
              value={target}
              onChange={e => setTarget(e.target.value)}
              placeholder="https://example.com"
              className="w-full px-4 py-4 bg-dark-900 border border-dark-600 rounded-xl text-white text-lg placeholder-dark-500 focus:outline-none focus:border-green-500 focus:ring-1 focus:ring-green-500 transition-colors"
            />
          </div>

          {/* Test Mode Toggle */}
          <div className="flex items-center gap-1 mb-4 p-1 bg-dark-900 rounded-lg w-fit">
            <button
              onClick={() => setTestMode('auto_pentest')}
              disabled={isRunning}
              className={`px-4 py-2 rounded-md text-sm font-medium transition-all ${
                testMode === 'auto_pentest'
                  ? 'bg-green-600 text-white shadow-lg'
                  : 'text-dark-400 hover:text-white hover:bg-dark-700'
              } disabled:opacity-50`}
            >
              <Rocket className="w-4 h-4 inline mr-1.5" />
              Auto Pentest
            </button>
            <button
              onClick={() => setTestMode('cli_agent')}
              disabled={isRunning}
              className={`px-4 py-2 rounded-md text-sm font-medium transition-all ${
                testMode === 'cli_agent'
                  ? 'bg-purple-600 text-white shadow-lg'
                  : 'text-dark-400 hover:text-white hover:bg-dark-700'
              } disabled:opacity-50`}
              title={!cliEnabled ? 'Set ENABLE_CLI_AGENT=true in .env' : 'Run AI CLI (Claude/Gemini/Codex) inside Kali container'}
            >
              <Terminal className="w-4 h-4 inline mr-1.5" />
              CLI Agent
              {!cliEnabled && <span className="ml-1 text-xs text-dark-500">(disabled)</span>}
            </button>
            <button
              onClick={() => setTestMode('full_llm_pentest')}
              disabled={isRunning}
              className={`px-4 py-2 rounded-md text-sm font-medium transition-all ${
                testMode === 'full_llm_pentest'
                  ? 'bg-red-600 text-white shadow-lg'
                  : 'text-dark-400 hover:text-white hover:bg-dark-700'
              } disabled:opacity-50`}
              title="Full AI-driven pentest — LLM plans and executes every test"
            >
              <Crosshair className="w-4 h-4 inline mr-1.5" />
              Full LLM Pentest
            </button>
          </div>

          {/* CLI Agent Options (shown in CLI mode) */}
          {testMode === 'cli_agent' && (
            <div className="mb-6 p-4 bg-dark-900/50 border border-purple-500/30 rounded-xl">
              <h4 className="text-sm font-medium text-purple-400 mb-3 flex items-center gap-2">
                <Terminal className="w-4 h-4" />
                CLI Agent Configuration
              </h4>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                <div>
                  <label className="block text-xs font-medium text-dark-400 mb-1">CLI Provider</label>
                  <select
                    value={selectedCliProvider}
                    onChange={e => setSelectedCliProvider(e.target.value)}
                    disabled={isRunning}
                    className="w-full px-3 py-2 bg-dark-900 border border-dark-600 rounded-lg text-sm text-white focus:outline-none focus:border-purple-500 disabled:opacity-50"
                  >
                    <option value="">Select provider...</option>
                    {cliProviders.map(p => (
                      <option key={p.id} value={p.id} disabled={!p.connected}>
                        {p.name} {p.connected ? `(${p.source})` : '(not connected)'}
                      </option>
                    ))}
                  </select>
                </div>
                <div>
                  <label className="block text-xs font-medium text-dark-400 mb-1">Methodology</label>
                  <select
                    value={selectedMethodology}
                    onChange={e => setSelectedMethodology(e.target.value)}
                    disabled={isRunning}
                    className="w-full px-3 py-2 bg-dark-900 border border-dark-600 rounded-lg text-sm text-white focus:outline-none focus:border-purple-500 disabled:opacity-50"
                  >
                    {methodologies.map(m => (
                      <option key={m.path} value={m.path}>
                        {m.name} ({m.size_human}){m.is_default ? ' [default]' : ''}
                      </option>
                    ))}
                  </select>
                </div>
              </div>
              {!cliEnabled && (
                <p className="mt-2 text-xs text-yellow-500">
                  Set ENABLE_CLI_AGENT=true in .env to enable CLI Agent mode
                </p>
              )}
            </div>
          )}

          {/* Toggles */}
          <div className="flex flex-wrap gap-4 mb-6">
            <label className="flex items-center gap-2 cursor-pointer">
              <input
                type="checkbox"
                checked={subdomainDiscovery}
                onChange={e => setSubdomainDiscovery(e.target.checked)}
                disabled={isRunning}
                className="w-4 h-4 rounded bg-dark-900 border-dark-600 text-green-500 focus:ring-green-500"
              />
              <span className="text-sm text-dark-300">Subdomain Discovery</span>
            </label>

            <label className="flex items-center gap-2 cursor-pointer">
              <input
                type="checkbox"
                checked={multiTarget}
                onChange={e => setMultiTarget(e.target.checked)}
                disabled={isRunning}
                className="w-4 h-4 rounded bg-dark-900 border-dark-600 text-green-500 focus:ring-green-500"
              />
              <span className="text-sm text-dark-300">Multiple Targets</span>
            </label>

            <label className="flex items-center gap-2 cursor-pointer" title="Enable Kali Linux sandbox for AI-driven tool execution and 0-day research">
              <input
                type="checkbox"
                checked={testMode === 'cli_agent' ? true : enableKaliSandbox}
                onChange={e => setEnableKaliSandbox(e.target.checked)}
                disabled={isRunning || testMode === 'cli_agent'}
                className="w-4 h-4 rounded bg-dark-900 border-dark-600 text-green-500 focus:ring-green-500"
              />
              <span className="text-sm text-dark-300">Kali Sandbox + AI Researcher</span>
            </label>

            {testMode === 'auto_pentest' && cliProviders.some(p => p.connected) && (
              <label className="flex items-center gap-2 cursor-pointer" title="Also run CLI Agent as additional phase inside Auto Pentest">
                <input
                  type="checkbox"
                  checked={enableCliPhase}
                  onChange={e => setEnableCliPhase(e.target.checked)}
                  disabled={isRunning || !cliEnabled}
                  className="w-4 h-4 rounded bg-dark-900 border-dark-600 text-purple-500 focus:ring-purple-500"
                />
                <span className="text-sm text-dark-300">
                  CLI Agent Phase
                  {!cliEnabled && <span className="text-dark-500 ml-1">(enable in .env)</span>}
                </span>
              </label>
            )}
          </div>

          {/* CLI Agent Phase Options (shown when checkbox enabled in auto_pentest mode) */}
          {testMode === 'auto_pentest' && enableCliPhase && (
            <div className="mb-6 p-3 bg-dark-900/50 border border-purple-500/20 rounded-lg">
              <div className="flex gap-3">
                <div className="flex-1">
                  <label className="block text-xs font-medium text-dark-400 mb-1">CLI Provider</label>
                  <select
                    value={selectedCliProvider}
                    onChange={e => setSelectedCliProvider(e.target.value)}
                    disabled={isRunning}
                    className="w-full px-3 py-1.5 bg-dark-900 border border-dark-600 rounded text-sm text-white focus:outline-none focus:border-purple-500 disabled:opacity-50"
                  >
                    <option value="">Auto</option>
                    {cliProviders.filter(p => p.connected).map(p => (
                      <option key={p.id} value={p.id}>{p.name}</option>
                    ))}
                  </select>
                </div>
                <div className="flex-1">
                  <label className="block text-xs font-medium text-dark-400 mb-1">Methodology</label>
                  <select
                    value={selectedMethodology}
                    onChange={e => setSelectedMethodology(e.target.value)}
                    disabled={isRunning}
                    className="w-full px-3 py-1.5 bg-dark-900 border border-dark-600 rounded text-sm text-white focus:outline-none focus:border-purple-500 disabled:opacity-50"
                  >
                    {methodologies.map(m => (
                      <option key={m.path} value={m.path}>{m.name}{m.is_default ? ' [default]' : ''}</option>
                    ))}
                  </select>
                </div>
              </div>
            </div>
          )}

          {/* MD Agent Selection */}
          {availableMdAgents.length > 0 && (
            <div className="mb-6">
              <button
                type="button"
                onClick={() => setShowAgentSelector(!showAgentSelector)}
                className="flex items-center gap-2 text-sm text-dark-300 hover:text-white transition-colors mb-2"
              >
                {showAgentSelector ? <ChevronUp className="w-4 h-4" /> : <ChevronDown className="w-4 h-4" />}
                <Brain className="w-4 h-4" />
                AI Agents ({selectedMdAgents.length > 0 ? `${selectedMdAgents.length} selected` : `All ${availableMdAgents.length} agents`})
              </button>

              {showAgentSelector && (
                <div className="p-3 bg-dark-900/50 border border-cyan-500/20 rounded-lg">
                  <p className="text-xs text-dark-400 mb-2">
                    Select which AI agents run after recon. Empty = all {availableMdAgents.length} offensive agents.
                  </p>
                  <div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
                    {availableMdAgents.map(agent => {
                      const isSelected = selectedMdAgents.includes(agent.name)
                      const catColor = agent.category === 'offensive' ? 'cyan'
                        : agent.category === 'analysis' ? 'yellow'
                        : agent.category === 'defensive' ? 'blue' : 'gray'
                      const agentKey = agent.name.replace(/\.md$/, '').replace(/_/g, '_')
                      const ls = learningStats[agentKey]
                      return (
                        <label
                          key={agent.name}
                          className={`flex items-center gap-2 p-2 rounded-lg cursor-pointer border transition-colors ${
                            isSelected
                              ? `bg-${catColor}-500/15 border-${catColor}-500/40 text-${catColor}-400`
                              : 'bg-dark-800 border-dark-700 text-dark-400 hover:border-dark-500'
                          }`}
                        >
                          <input
                            type="checkbox"
                            checked={isSelected}
                            onChange={() => {
                              setSelectedMdAgents(prev =>
                                isSelected ? prev.filter(n => n !== agent.name) : [...prev, agent.name]
                              )
                            }}
                            disabled={isRunning}
                            className="w-3.5 h-3.5 rounded bg-dark-900 border-dark-600 text-cyan-500 focus:ring-cyan-500"
                          />
                          <div className="min-w-0 flex-1">
                            <span className="text-xs font-medium block truncate">{agent.display_name}</span>
                            <div className="flex items-center gap-1.5">
                              <span className="text-[10px] text-dark-500 capitalize">{agent.category}</span>
                              {ls && (ls.tp > 0 || ls.fp > 0) && (
                                <span className="text-[9px] font-mono">
                                  {ls.tp > 0 && <span className="text-green-400">{ls.tp}TP</span>}
                                  {ls.tp > 0 && ls.fp > 0 && <span className="text-dark-600">/</span>}
                                  {ls.fp > 0 && <span className="text-red-400">{ls.fp}FP</span>}
                                </span>
                              )}
                            </div>
                          </div>
                        </label>
                      )
                    })}
                  </div>
                  {selectedMdAgents.length > 0 && (
                    <button
                      type="button"
                      onClick={() => setSelectedMdAgents([])}
                      className="mt-2 text-xs text-dark-500 hover:text-dark-300 transition-colors"
                    >
                      Clear selection (use all agents)
                    </button>
                  )}
                </div>
              )}
            </div>
          )}

          {/* LLM Provider / Model Selection */}
          <div className="mb-6 flex flex-col sm:flex-row gap-3 sm:gap-4">
            <div className="flex-1">
              <label className="block text-xs font-medium text-dark-400 mb-1">LLM Provider</label>
              <select
                value={selectedProvider}
                onChange={e => {
                  setSelectedProvider(e.target.value)
                  const m = availableModels.find(m => m.provider_id === e.target.value)
                  if (m) setSelectedModel(m.default_model)
                  else if (e.target.value === 'anthropic') setSelectedModel('claude-sonnet-4-20250514')
                  else setSelectedModel('')
                }}
                disabled={isRunning}
                className="w-full px-3 py-2 bg-dark-900 border border-dark-600 rounded-lg text-sm text-white focus:outline-none focus:border-green-500 disabled:opacity-50 transition-colors"
              >
                <option value="">Auto (best available)</option>
                <option value="anthropic">Anthropic (Claude API)</option>
                <option value="claude_code">Claude Code (OAuth)</option>
                <option value="openai">OpenAI</option>
                <option value="gemini">Gemini</option>
                <option value="openrouter">OpenRouter</option>
                {availableModels.filter(m => !['anthropic','claude_code','openai','gemini','openrouter'].includes(m.provider_id)).map(m => (
                  <option key={m.provider_id} value={m.provider_id}>
                    {m.provider_name} (Tier {m.tier})
                  </option>
                ))}
              </select>
            </div>
            <div className="flex-1">
              <label className="block text-xs font-medium text-dark-400 mb-1">Model</label>
              <select
                value={selectedModel}
                onChange={e => setSelectedModel(e.target.value)}
                disabled={isRunning}
                className="w-full px-3 py-2 bg-dark-900 border border-dark-600 rounded-lg text-sm text-white focus:outline-none focus:border-green-500 disabled:opacity-50 transition-colors"
              >
                <option value="">Auto (default)</option>
                {selectedProvider === 'anthropic' || selectedProvider === 'claude_code' || selectedProvider === '' ? (
                  <>
                    <option value="claude-opus-4-20250514">Claude Opus 4</option>
                    <option value="claude-sonnet-4-20250514">Claude Sonnet 4</option>
                    <option value="claude-sonnet-4-5-20250929">Claude Sonnet 4.5</option>
                    <option value="claude-haiku-4-5-20251001">Claude Haiku 4.5</option>
                  </>
                ) : null}
                {(selectedProvider && availableModels.find(m => m.provider_id === selectedProvider)?.available_models || [])
                  .filter(m => !m.startsWith('claude-'))
                  .map(model => (
                    <option key={model} value={model}>{model}</option>
                  ))
                }
              </select>
            </div>
          </div>

          {/* Multi-target textarea */}
          {multiTarget && (
            <div className="mb-6">
              <label className="block text-sm font-medium text-dark-300 mb-2">Additional Targets (one per line)</label>
              <textarea
                value={targets}
                onChange={e => setTargets(e.target.value)}
                rows={4}
                disabled={isRunning}
                placeholder={"https://api.example.com\nhttps://admin.example.com"}
                className="w-full px-4 py-3 bg-dark-900 border border-dark-600 rounded-xl text-white placeholder-dark-500 focus:outline-none focus:border-green-500 disabled:opacity-50 transition-colors"
              />
            </div>
          )}

          {/* Auth Section (collapsible) */}
          <div className="mb-6">
            <button
              onClick={() => setShowAuth(!showAuth)}
              disabled={isRunning}
              className="flex items-center gap-2 text-sm text-dark-400 hover:text-white transition-colors disabled:opacity-50"
            >
              <Lock className="w-4 h-4" />
              <span>Authentication (Optional)</span>
              {showAuth ? <ChevronUp className="w-4 h-4" /> : <ChevronDown className="w-4 h-4" />}
            </button>

            {showAuth && (
              <div className="mt-3 space-y-3 pl-6">
                <select
                  value={authType}
                  onChange={e => setAuthType(e.target.value)}
                  disabled={isRunning}
                  className="w-full px-3 py-2 bg-dark-900 border border-dark-600 rounded-lg text-white text-sm focus:outline-none focus:border-green-500 transition-colors"
                >
                  <option value="">No Authentication</option>
                  <option value="bearer">Bearer Token</option>
                  <option value="cookie">Cookie</option>
                  <option value="basic">Basic Auth (user:pass)</option>
                  <option value="header">Custom Header (Name:Value)</option>
                </select>
                {authType && (
                  <input
                    type="text"
                    value={authValue}
                    onChange={e => setAuthValue(e.target.value)}
                    disabled={isRunning}
                    placeholder={
                      authType === 'bearer' ? 'eyJhbGciOiJIUzI1NiIs...' :
                      authType === 'cookie' ? 'session=abc123; token=xyz' :
                      authType === 'basic' ? 'admin:password123' :
                      'X-API-Key:your-api-key'
                    }
                    className="w-full px-3 py-2 bg-dark-900 border border-dark-600 rounded-lg text-white text-sm placeholder-dark-500 focus:outline-none focus:border-green-500 transition-colors"
                  />
                )}
              </div>
            )}
          </div>

          {/* Custom AI Prompt (collapsible) */}
          <div className="mb-6">
            <button
              onClick={() => setShowPrompt(!showPrompt)}
              disabled={isRunning}
              className="flex items-center gap-2 text-sm text-dark-400 hover:text-white transition-colors disabled:opacity-50"
            >
              <MessageSquare className="w-4 h-4" />
              <span>Custom AI Prompt (Optional)</span>
              {showPrompt ? <ChevronUp className="w-4 h-4" /> : <ChevronDown className="w-4 h-4" />}
            </button>

            {showPrompt && (
              <div className="mt-3 pl-6">
                <textarea
                  value={customPrompt}
                  onChange={e => setCustomPrompt(e.target.value)}
                  rows={4}
                  disabled={isRunning}
                  placeholder={"Focus on authentication bypass and IDOR vulnerabilities.\nThe app uses JWT tokens in localStorage.\nAdmin panel at /admin requires role=admin cookie."}
                  className="w-full px-4 py-3 bg-dark-900 border border-dark-600 rounded-xl text-white text-sm placeholder-dark-500 focus:outline-none focus:border-green-500 disabled:opacity-50 transition-colors"
                />
                <p className="mt-1 text-xs text-dark-500">
                  Guide the AI agent with additional context, focus areas, or specific instructions.
                </p>
              </div>
            )}
          </div>

          {/* Saved Custom Prompts (multi-select) */}
          {savedPrompts.length > 0 && (
            <div className="mb-6">
              <button
                onClick={() => setShowSavedPrompts(!showSavedPrompts)}
                disabled={isRunning}
                className="flex items-center gap-2 text-sm text-dark-400 hover:text-white transition-colors disabled:opacity-50"
              >
                <ScrollText className="w-4 h-4" />
                <span>Saved Prompts ({selectedPromptIds.length} selected)</span>
                {showSavedPrompts ? <ChevronUp className="w-4 h-4" /> : <ChevronDown className="w-4 h-4" />}
              </button>

              {showSavedPrompts && (
                <div className="mt-3 pl-6 space-y-2 max-h-48 overflow-y-auto">
                  {savedPrompts.map(p => (
                    <label key={p.id} className="flex items-start gap-2 cursor-pointer p-2 rounded-lg hover:bg-dark-900/50 transition-colors">
                      <input
                        type="checkbox"
                        checked={selectedPromptIds.includes(p.id)}
                        onChange={e => {
                          if (e.target.checked) {
                            setSelectedPromptIds(prev => [...prev, p.id])
                          } else {
                            setSelectedPromptIds(prev => prev.filter(id => id !== p.id))
                          }
                        }}
                        disabled={isRunning}
                        className="w-4 h-4 mt-0.5 rounded bg-dark-900 border-dark-600 text-primary-500 focus:ring-primary-500"
                      />
                      <div>
                        <span className="text-sm text-white">{p.name}</span>
                        {p.category && (
                          <span className="ml-2 px-1.5 py-0.5 text-xs rounded bg-primary-500/20 text-primary-400">{p.category}</span>
                        )}
                        {p.description && (
                          <p className="text-xs text-dark-400 mt-0.5">{p.description}</p>
                        )}
                      </div>
                    </label>
                  ))}
                </div>
              )}
            </div>
          )}

          {/* Error */}
          {error && (
            <div className="mb-6 p-3 bg-red-500/10 border border-red-500/20 rounded-lg flex items-center gap-2">
              <AlertTriangle className="w-5 h-5 text-red-400 flex-shrink-0" />
              <span className="text-red-400 text-sm">{error}</span>
            </div>
          )}

          {/* Start Button */}
          <button
            onClick={handleStart}
            disabled={!target.trim() || sessions.filter(s => s.status === 'running').length >= maxConcurrent}
            className="w-full py-4 bg-green-500 hover:bg-green-600 disabled:bg-dark-600 disabled:text-dark-400 text-white font-bold text-lg rounded-xl transition-colors flex items-center justify-center gap-3"
          >
            <Rocket className="w-6 h-6" />
            START PENTEST
          </button>
        </div>
      )}

      {/* ═══ ACTIVE SESSION VIEW ═══ */}
      {agentId && (
        <div className="w-full max-w-4xl">

          {/* Session Header */}
          <div className="bg-dark-800 border border-dark-700 rounded-2xl p-4 sm:p-6 mb-4">
            <div className="flex items-center justify-between flex-wrap gap-3">
              <div className="flex items-center gap-3 min-w-0">
                <div className={`w-3 h-3 rounded-full flex-shrink-0 ${
                  isRunning ? 'bg-green-500 animate-pulse' :
                  status?.status === 'completed' ? 'bg-green-500' :
                  status?.status === 'error' ? 'bg-red-500' : 'bg-gray-500'
                }`} />
                <h3 className="text-white font-semibold truncate">
                  {isRunning ? 'Pentest Running' :
                   status?.status === 'completed' ? 'Pentest Complete' :
                   status?.status === 'error' ? 'Pentest Failed' : 'Pentest Stopped'}
                </h3>
                <span className="text-dark-400 text-sm truncate max-w-[200px] sm:max-w-[300px] hidden sm:inline">{activeSession?.target}</span>
              </div>
              <div className="flex items-center gap-2 flex-shrink-0">
                {isRunning && (
                  <button
                    onClick={handleStop}
                    className="px-4 py-1.5 bg-red-500/20 hover:bg-red-500/30 text-red-400 rounded-lg text-sm transition-colors flex items-center gap-1.5"
                  >
                    <X className="w-4 h-4" /> Stop
                  </button>
                )}
                {!isRunning && (
                  <>
                    <button
                      onClick={() => { setActiveSessionIdx(-1); setLogs([]); setReportId(null); setElapsedSeconds(0) }}
                      className="px-4 py-1.5 bg-green-500/20 hover:bg-green-500/30 text-green-400 rounded-lg text-sm transition-colors flex items-center gap-1.5"
                    >
                      <Rocket className="w-4 h-4" /> New Scan
                    </button>
                    <button
                      onClick={() => handleClearSession()}
                      className="px-4 py-1.5 bg-dark-700 hover:bg-dark-600 text-dark-300 rounded-lg text-sm transition-colors flex items-center gap-1.5"
                    >
                      <Trash2 className="w-4 h-4" /> Remove
                    </button>
                  </>
                )}
              </div>
            </div>
          </div>

          {/* Live Stats Dashboard */}
          {status && (
            <LiveStatsDashboard
              status={status}
              elapsedSeconds={elapsedSeconds}
              toolExecutions={toolExecutions}
            />
          )}

          {/* Progress Panel */}
          {status && (
            <div className="bg-dark-800 border border-dark-700 rounded-2xl p-4 sm:p-6 mb-4">
              <div className="flex items-center justify-between text-sm mb-2">
                <span className="text-dark-400">{status.phase || 'Initializing...'}</span>
                <span className="text-dark-400 tabular-nums font-mono">{status.progress}%</span>
              </div>

              {/* Enhanced Progress Bar */}
              <div className="relative w-full bg-dark-900 rounded-full h-3 mb-4 overflow-hidden">
                <div className="absolute top-0 left-1/2 w-px h-full bg-dark-700 z-10" />
                <div className="absolute top-0 left-3/4 w-px h-full bg-dark-700 z-10" />
                <div
                  className="h-full rounded-full transition-all duration-700 ease-out relative"
                  style={{ width: `${status.progress}%`, background: 'linear-gradient(90deg, #22c55e, #16a34a)' }}
                >
                  {isRunning && (
                    <div
                      className="absolute right-0 top-0 h-full w-6 rounded-full"
                      style={{ background: 'linear-gradient(90deg, transparent, rgba(255,255,255,0.25))', animation: 'glowPulse 1.5s ease-in-out infinite' }}
                    />
                  )}
                </div>
              </div>

              {/* Phase Indicators */}
              <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
                {PHASES.map((phase, idx) => {
                  const Icon = phase.icon
                  const isActive = idx === currentPhaseIdx && isRunning
                  const isDone = idx < currentPhaseIdx || status.status === 'completed' || status.status === 'stopped'

                  return (
                    <div
                      key={phase.key}
                      className={`rounded-xl p-3 border transition-all duration-300 ${
                        isActive ? 'bg-green-500/10 border-green-500/30' :
                        isDone   ? 'bg-dark-700/50 border-dark-600' :
                                   'bg-dark-900 border-dark-700'
                      }`}
                    >
                      <div className="flex items-center gap-2 mb-1">
                        {isActive ? <Loader2 className="w-4 h-4 animate-spin text-green-400 flex-shrink-0" /> :
                         isDone   ? <CheckCircle2 className="w-4 h-4 text-green-500 flex-shrink-0" /> :
                                    <Icon className="w-4 h-4 text-dark-500 flex-shrink-0" />}
                        <span className={`text-xs font-medium ${
                          isActive ? 'text-green-400' :
                          isDone ? 'text-dark-300' :
                          'text-dark-500'
                        }`}>
                          {phase.label}
                        </span>
                        <span className={`ml-auto text-[10px] tabular-nums ${
                          isActive ? 'text-green-500/60' :
                          isDone ? 'text-dark-500' :
                          'text-dark-600'
                        }`}>
                          {phase.range[0]}-{phase.range[1]}%
                        </span>
                      </div>

                      {/* Stream badges for the parallel phase */}
                      {idx === 0 && (
                        <div className="flex flex-wrap gap-1.5 mt-2">
                          {STREAMS.map(stream => (
                            <StreamBadge
                              key={stream.key}
                              stream={stream}
                              progress={status.progress}
                              isRunning={isRunning}
                            />
                          ))}
                        </div>
                      )}
                    </div>
                  )
                })}
              </div>
            </div>
          )}

          {/* Container Telemetry */}
          {containerStatus && (
            <div className="bg-dark-800 border border-dark-700 rounded-2xl p-4 sm:p-6 mb-4">
              <div className="flex items-center justify-between mb-4 flex-wrap gap-2">
                <div className="flex items-center gap-3">
                  <Terminal className="w-5 h-5 text-cyan-400" />
                  <h3 className="text-white font-semibold text-sm">Container Telemetry</h3>
                  <span className={`flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-bold ${
                    containerStatus.online
                      ? 'bg-green-500/20 text-green-400 border border-green-500/40'
                      : 'bg-red-500/20 text-red-400 border border-red-500/40'
                  }`}>
                    <span className={`w-2 h-2 rounded-full ${containerStatus.online ? 'bg-green-400 animate-pulse' : 'bg-red-400'}`} />
                    {containerStatus.online ? 'ONLINE' : 'OFFLINE'}
                  </span>
                </div>
                <div className="flex items-center gap-3 text-xs text-dark-400 font-mono">
                  {containerStatus.container_id && <span>ID: {containerStatus.container_id.slice(0, 12)}</span>}
                  {containerStatus.container_name && <span className="hidden sm:inline">{containerStatus.container_name}</span>}
                </div>
              </div>

              {toolExecutions.length > 0 ? (
                <div className="space-y-0 max-h-[350px] overflow-y-auto rounded-lg border border-dark-700 bg-dark-900/50">
                  <div className="grid grid-cols-[50px_70px_1fr_50px_65px_55px_20px] sm:grid-cols-[60px_80px_1fr_50px_70px_60px_24px] gap-2 text-[10px] text-dark-500 font-semibold uppercase tracking-wider px-2 py-2 border-b border-dark-700 bg-dark-900 sticky top-0">
                    <span>Task</span>
                    <span>Tool</span>
                    <span>Command</span>
                    <span className="text-center">Exit</span>
                    <span className="text-right">Duration</span>
                    <span className="text-center">Finds</span>
                    <span />
                  </div>
                  {toolExecutions.map((exec, i) => (
                    <ToolExecutionRow
                      key={exec.task_id || i}
                      exec={exec}
                      expanded={expandedTool === (exec.task_id || String(i))}
                      onToggle={() => setExpandedTool(expandedTool === (exec.task_id || String(i)) ? null : (exec.task_id || String(i)))}
                    />
                  ))}
                </div>
              ) : (
                <div className="text-center text-dark-500 text-sm py-6">
                  {isRunning ? (
                    <span className="flex items-center justify-center gap-2">
                      <Loader2 className="w-4 h-4 animate-spin" />
                      Waiting for tool executions...
                    </span>
                  ) : 'No tool executions recorded'}
                </div>
              )}

              {toolExecutions.length > 0 && (() => {
                const last = toolExecutions[toolExecutions.length - 1]
                return (
                  <div className="mt-3 pt-3 border-t border-dark-700 flex items-center gap-2 text-xs flex-wrap">
                    <span className="text-dark-500">Last:</span>
                    <span className="text-cyan-400 font-medium">{last.tool}</span>
                    <span className={`font-bold ${last.exit_code === 0 ? 'text-green-400' : last.exit_code === -1 ? 'text-yellow-400' : 'text-red-400'}`}>
                      {last.exit_code === -1 ? 'container error' : `exit:${last.exit_code}`}
                    </span>
                    <span className="text-dark-400">{last.duration != null && last.duration > 0 ? `${last.duration.toFixed(1)}s` : ''}</span>
                    {last.findings_count > 0 && <span className="text-red-400">{last.findings_count} findings</span>}
                  </div>
                )
              })()}
            </div>
          )}

          {/* ═══ Findings / Agents / Logs Tabs ═══ */}
          <div className="bg-dark-800 border border-dark-700 rounded-2xl p-4 sm:p-6 mb-4">
            {/* Tab bar */}
            <div className="flex items-center justify-between mb-4 flex-wrap gap-3">
              <div className="flex items-center gap-3 flex-wrap">
                <h3 className="text-white font-semibold text-sm">
                  {activeTab === 'findings' ? `Findings (${findings.length})` :
                   activeTab === 'agents' ? 'Vulnerability Agents' : 'Activity Log'}
                </h3>
                {activeTab === 'findings' && (
                  <div className="flex gap-1.5 items-center">
                    {['critical', 'high', 'medium', 'low', 'info'].map(sev => {
                      const count = sevCounts[sev] || 0
                      if (count === 0) return null
                      return (
                        <span key={sev} className={`${SEVERITY_COLORS[sev]} text-white px-2 py-0.5 rounded-full text-[10px] font-bold tabular-nums`}>
                          {count}
                        </span>
                      )
                    })}
                    <SeverityMiniChart sevCounts={sevCounts} />
                  </div>
                )}
              </div>
              <div className="flex gap-1.5 flex-wrap">
                <button
                  onClick={() => setActiveTab('findings')}
                  className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors flex items-center gap-1.5 ${
                    activeTab === 'findings' ? 'bg-primary-500/20 text-primary-400 border border-primary-500/30' : 'bg-dark-700 text-dark-400 hover:text-white border border-transparent'
                  }`}
                >
                  <Bug className="w-3 h-3" />Findings
                  {findings.length > 0 && <span className="text-[10px] opacity-70">({findings.length})</span>}
                </button>
                {rejectedFindings.length > 0 && (
                  <button
                    onClick={() => { setActiveTab('findings'); setFindingsFilter(findingsFilter === 'rejected' ? 'all' : 'rejected') }}
                    className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors flex items-center gap-1.5 ${
                      findingsFilter === 'rejected' && activeTab === 'findings'
                        ? 'bg-orange-500/20 text-orange-400 border border-orange-500/30'
                        : 'bg-dark-700 text-orange-400/60 hover:text-orange-400 border border-transparent'
                    }`}
                  >
                    <AlertTriangle className="w-3 h-3" />Rejected ({rejectedFindings.length})
                  </button>
                )}
                <button
                  onClick={() => setActiveTab('agents')}
                  className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors flex items-center gap-1.5 ${
                    activeTab === 'agents' ? 'bg-primary-500/20 text-primary-400 border border-primary-500/30' : 'bg-dark-700 text-dark-400 hover:text-white border border-transparent'
                  }`}
                >
                  <Shield className="w-3 h-3" />Agents
                </button>
                <button
                  onClick={() => setActiveTab('logs')}
                  className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors flex items-center gap-1.5 ${
                    activeTab === 'logs' ? 'bg-primary-500/20 text-primary-400 border border-primary-500/30' : 'bg-dark-700 text-dark-400 hover:text-white border border-transparent'
                  }`}
                >
                  <ScrollText className="w-3 h-3" />Log
                  {logs.length > 0 && <span className="text-[10px] opacity-70">({logs.length})</span>}
                </button>
              </div>
            </div>

            {/* Agents Grid View */}
            {activeTab === 'agents' && agentId && (
              <VulnAgentGrid agentId={agentId} isRunning={isRunning} />
            )}

            {/* Findings Filter Tabs */}
            {activeTab === 'findings' && allFindings.length > 0 && rejectedFindings.length > 0 && (
              <div className="flex gap-1 mb-3">
                {(['all', 'confirmed', 'rejected'] as const).map(f => (
                  <button
                    key={f}
                    onClick={() => setFindingsFilter(f)}
                    className={`px-2.5 py-1 rounded-full text-xs transition-colors ${
                      findingsFilter === f ? 'bg-primary-500/20 text-primary-400' : 'text-dark-500 hover:text-dark-300'
                    }`}
                  >
                    {f === 'all' ? `All (${allFindings.length})` :
                     f === 'confirmed' ? `Confirmed (${findings.length})` :
                     `Rejected (${rejectedFindings.length})`}
                  </button>
                ))}
              </div>
            )}

            {/* Findings List */}
            {activeTab === 'findings' && (
              displayFindings.length > 0 ? (
                <div className="space-y-2 max-h-[500px] overflow-y-auto pr-1">
                  {displayFindings.map((f: AgentFinding) => {
                    const isNew = newFindingIds.has(f.id)
                    return (
                      <div
                        key={f.id}
                        className={`border ${f.ai_status === 'rejected' ? 'border-orange-500/30 opacity-70' : (SEVERITY_BORDER[f.severity] || 'border-dark-600')} rounded-xl bg-dark-900 overflow-hidden transition-all duration-300 ${
                          isNew ? 'ring-2 ring-green-500/30' : ''
                        }`}
                        style={isNew ? { animation: 'fadeSlideIn 0.5s ease-out' } : undefined}
                      >
                        <button
                          onClick={() => setExpandedFinding(expandedFinding === f.id ? null : f.id)}
                          className="w-full flex items-center gap-2 sm:gap-3 p-3 text-left hover:bg-dark-800/50 transition-colors"
                        >
                          <span className={`${SEVERITY_COLORS[f.severity]} text-white px-2 py-0.5 rounded text-[10px] font-bold uppercase flex-shrink-0`}>
                            {f.severity}
                          </span>
                          <span className={`text-sm flex-1 truncate ${f.ai_status === 'rejected' ? 'text-dark-400' : 'text-white'}`}>{f.title}</span>
                          {f.ai_status === 'rejected' && (
                            <span className="text-[10px] px-1.5 py-0.5 rounded-full bg-orange-500/20 text-orange-400 flex-shrink-0">Rejected</span>
                          )}
                          {(() => {
                            const conf = getConfidenceDisplay(f)
                            if (!conf) return null
                            return (
                              <span className={`text-[10px] font-semibold px-1.5 py-0.5 rounded-full border flex-shrink-0 tabular-nums ${CONFIDENCE_STYLES[conf.color]}`}>
                                {conf.score}
                              </span>
                            )
                          })()}
                          <span className="text-dark-500 text-[10px] flex-shrink-0 hidden sm:inline">{f.vulnerability_type}</span>
                          {expandedFinding === f.id ? <ChevronUp className="w-4 h-4 text-dark-400 flex-shrink-0" /> : <ChevronDown className="w-4 h-4 text-dark-400 flex-shrink-0" />}
                        </button>

                        {expandedFinding === f.id && (
                          <div className="px-3 pb-3 space-y-2 border-t border-dark-700 pt-2">
                            <div className="grid grid-cols-1 sm:grid-cols-2 gap-2 text-xs">
                              {f.affected_endpoint && (
                                <div><span className="text-dark-500">Endpoint: </span><span className="text-dark-300 break-all">{f.affected_endpoint}</span></div>
                              )}
                              {f.parameter && (
                                <div><span className="text-dark-500">Parameter: </span><span className="text-dark-300">{f.parameter}</span></div>
                              )}
                              {f.cwe_id && (
                                <div><span className="text-dark-500">CWE: </span><span className="text-dark-300">{f.cwe_id}</span></div>
                              )}
                              {f.cvss_score > 0 && (
                                <div><span className="text-dark-500">CVSS: </span><span className="text-dark-300">{f.cvss_score}</span></div>
                              )}
                            </div>
                            {f.description && (
                              <p className="text-dark-400 text-xs">{f.description.substring(0, 400)}{f.description.length > 400 ? '...' : ''}</p>
                            )}
                            {f.payload && (
                              <div className="bg-dark-800 rounded-lg p-2">
                                <span className="text-dark-500 text-xs">Payload: </span>
                                <code className="text-green-400 text-xs break-all">{f.payload.substring(0, 300)}</code>
                              </div>
                            )}
                            {f.evidence && (
                              <div className="bg-dark-800 rounded-lg p-2">
                                <span className="text-dark-500 text-xs">Evidence: </span>
                                <span className="text-dark-300 text-xs">{f.evidence.substring(0, 400)}</span>
                              </div>
                            )}
                            {f.poc_code && (
                              <div>
                                <p className="text-xs font-medium text-dark-400 mb-1">PoC Code</p>
                                <pre className="p-2 bg-dark-950 rounded text-xs text-green-400 overflow-x-auto max-h-[300px] overflow-y-auto whitespace-pre-wrap font-mono">{f.poc_code}</pre>
                              </div>
                            )}
                            {f.ai_status === 'rejected' && f.rejection_reason && (
                              <div className="bg-orange-500/10 border border-orange-500/20 rounded-lg p-2">
                                <span className="text-orange-400 text-xs font-medium">Rejection: </span>
                                <span className="text-orange-300/80 text-xs">{f.rejection_reason}</span>
                              </div>
                            )}
                            <div className="flex items-center gap-2 flex-wrap">
                              <span className={`text-xs ${f.ai_status === 'rejected' ? 'text-orange-400' : f.ai_verified ? 'text-green-400' : 'text-dark-500'}`}>
                                {f.ai_status === 'rejected' ? 'AI Rejected' : f.ai_verified ? 'AI Verified' : 'Tool Detected'}
                              </span>
                              {(() => {
                                const conf = getConfidenceDisplay(f)
                                if (!conf) return null
                                return (
                                  <span className={`text-xs font-semibold px-1.5 py-0.5 rounded-full border tabular-nums ${CONFIDENCE_STYLES[conf.color]}`}>
                                    Confidence: {conf.score}/100 ({conf.label})
                                  </span>
                                )
                              })()}
                            </div>
                            {(() => {
                              const hasBreakdown = f.confidence_breakdown && Object.keys(f.confidence_breakdown).length > 0
                              const hasProof = !!f.proof_of_execution
                              const hasControls = !!f.negative_controls
                              if (!hasBreakdown && !hasProof && !hasControls) return null
                              return (
                                <div className="bg-dark-800 rounded-lg p-2 space-y-1">
                                  {hasBreakdown && (
                                    <div className="grid grid-cols-2 gap-x-4 gap-y-0.5 text-xs text-dark-400">
                                      {Object.entries(f.confidence_breakdown!).map(([key, val]) => (
                                        <div key={key} className="flex justify-between">
                                          <span className="capitalize">{key.replace(/_/g, ' ')}</span>
                                          <span className={`font-mono font-medium tabular-nums ${
                                            Number(val) > 0 ? 'text-green-400' : Number(val) < 0 ? 'text-red-400' : 'text-dark-500'
                                          }`}>{Number(val) > 0 ? '+' : ''}{val}</span>
                                        </div>
                                      ))}
                                    </div>
                                  )}
                                  {hasProof && (
                                    <p className="text-xs text-dark-400 flex items-start gap-1">
                                      <CheckCircle2 className="w-3 h-3 text-green-400 flex-shrink-0 mt-0.5" />
                                      <span>Proof: <span className="text-dark-300">{f.proof_of_execution}</span></span>
                                    </p>
                                  )}
                                  {hasControls && (
                                    <p className="text-xs text-dark-400 flex items-start gap-1">
                                      <Shield className="w-3 h-3 text-blue-400 flex-shrink-0 mt-0.5" />
                                      <span>Controls: <span className="text-dark-300">{f.negative_controls}</span></span>
                                    </p>
                                  )}
                                </div>
                              )
                            })()}
                          </div>
                        )}
                      </div>
                    )
                  })}
                </div>
              ) : (
                <div className="flex items-center justify-center py-8 text-dark-500">
                  {isRunning ? (
                    <span className="flex items-center gap-2">
                      <Loader2 className="w-5 h-5 animate-spin" />
                      Scanning in progress... Findings will appear as discovered.
                    </span>
                  ) : (
                    'No findings'
                  )}
                </div>
              )
            )}

            {/* Activity Log */}
            {activeTab === 'logs' && (
              <LogViewer
                logs={logs}
                logFilter={logFilter}
                setLogFilter={setLogFilter}
                logSearch={logSearch}
                setLogSearch={setLogSearch}
                logsEndRef={logsEndRef}
              />
            )}
          </div>

          {/* Completion / Stopped Actions */}
          {(status?.status === 'completed' || status?.status === 'stopped') && (
            <div className={`bg-dark-800 border ${status.status === 'completed' ? 'border-green-500/30' : 'border-yellow-500/30'} rounded-2xl p-4 sm:p-6 mb-4`} style={{ animation: 'fadeSlideIn 0.5s ease-out' }}>
              <div className="flex items-center gap-3 mb-4">
                {status.status === 'completed' ? (
                  <CheckCircle2 className="w-6 h-6 text-green-500" />
                ) : (
                  <AlertTriangle className="w-6 h-6 text-yellow-500" />
                )}
                <h3 className={`${status.status === 'completed' ? 'text-green-400' : 'text-yellow-400'} font-semibold text-lg`}>
                  {status.status === 'completed' ? 'Pentest Complete' : 'Pentest Stopped'}
                </h3>
              </div>

              <div className="flex items-center gap-4 mb-4 flex-wrap">
                <p className="text-dark-400 text-sm">
                  {status.status === 'completed'
                    ? `Found ${findings.length} vulnerabilities across ${activeSession?.target || target}.`
                    : `Stopped at ${status.progress}% — found ${findings.length} finding${findings.length !== 1 ? 's' : ''}.`}
                </p>
                {elapsedSeconds > 0 && (
                  <span className="text-dark-500 text-xs font-mono">Duration: {formatElapsed(elapsedSeconds)}</span>
                )}
              </div>

              {/* Report Generation */}
              {generatingReport && (
                <div className="mb-4 p-4 bg-purple-500/10 border border-purple-500/20 rounded-xl flex items-center gap-3">
                  <Loader2 className="w-5 h-5 text-purple-400 animate-spin flex-shrink-0" />
                  <div>
                    <p className="text-purple-400 font-medium text-sm">Generating AI Report...</p>
                    <p className="text-dark-400 text-xs">Analyzing findings and writing executive summary.</p>
                  </div>
                </div>
              )}

              <div className="flex flex-wrap gap-3">
                <button
                  onClick={() => navigate(`/agent/${agentId}`)}
                  className="px-5 py-2 bg-primary-500 hover:bg-primary-600 text-white rounded-lg transition-colors flex items-center gap-2 text-sm"
                >
                  <ExternalLink className="w-4 h-4" /> View Full Results
                </button>

                {!reportId ? (
                  <button
                    onClick={() => handleGenerateAiReport()}
                    disabled={generatingReport || !status.scan_id}
                    className="px-5 py-2 bg-purple-500 hover:bg-purple-600 disabled:opacity-50 text-white rounded-lg transition-colors flex items-center gap-2 text-sm"
                    title={selectedProvider ? `Using: ${selectedProvider}/${selectedModel || 'auto'}` : 'Using: auto'}
                  >
                    <Sparkles className="w-4 h-4" /> Generate AI Report
                    {selectedProvider && <span className="text-xs opacity-70">({selectedProvider})</span>}
                  </button>
                ) : (
                  <>
                    <a
                      href={reportsApi.getViewUrl(reportId)}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="px-5 py-2 bg-green-500 hover:bg-green-600 text-white rounded-lg transition-colors flex items-center gap-2 text-sm"
                    >
                      <FileText className="w-4 h-4" /> View Report
                    </a>
                    <a
                      href={reportsApi.getDownloadZipUrl(reportId)}
                      className="px-5 py-2 bg-dark-700 hover:bg-dark-600 text-white rounded-lg transition-colors flex items-center gap-2 text-sm"
                    >
                      <Download className="w-4 h-4" /> Download ZIP
                    </a>
                  </>
                )}
              </div>
            </div>
          )}

          {/* Error state */}
          {status?.status === 'error' && (
            <div className="bg-dark-800 border border-red-500/30 rounded-2xl p-4 sm:p-6" style={{ animation: 'fadeSlideIn 0.5s ease-out' }}>
              <div className="flex items-center gap-3 mb-2">
                <AlertTriangle className="w-6 h-6 text-red-400" />
                <h3 className="text-red-400 font-semibold">Pentest Failed</h3>
              </div>
              <p className="text-dark-400">{status.error || 'An unexpected error occurred.'}</p>
            </div>
          )}
        </div>
      )}
    </div>
  )
}
