import { useState, useMemo } from 'react'
import { format } from 'date-fns'
import { fr } from 'date-fns/locale'
import { AlertTriangle, XCircle, Info, RefreshCw, Trash2, ChevronDown, ChevronRight, Brain, Play, Loader2, Zap, MessageSquare, BarChart2, Clock } from 'lucide-react'
import clsx from 'clsx'
import { useSystemLogs, useLogSources, useLogCycles, useClearLogs, useCycleContextSnapshots, useCycleContextSnapshot, useReplayCycle, useAiCallLogs, type LogFilters } from '../hooks/useApi'
import { useQueryClient } from '@tanstack/react-query'

const LEVELS = ['', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']

function LevelBadge({ level }: { level: string }) {
  const cfg: Record<string, { cls: string; icon: React.ReactNode }> = {
    INFO:     { cls: 'bg-slate-700 text-slate-300',              icon: <Info className="w-3 h-3" /> },
    WARNING:  { cls: 'bg-amber-900/60 text-amber-300 border border-amber-700/40', icon: <AlertTriangle className="w-3 h-3" /> },
    ERROR:    { cls: 'bg-red-900/60 text-red-300 border border-red-700/40',       icon: <XCircle className="w-3 h-3" /> },
    CRITICAL: { cls: 'bg-red-800 text-white border border-red-600',               icon: <XCircle className="w-3 h-3" /> },
  }
  const { cls, icon } = cfg[level] ?? cfg['INFO']
  return (
    <span className={clsx('inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-semibold font-mono', cls)}>
      {icon} {level}
    </span>
  )
}

function LogRow({ log }: { log: any }) {
  const [expanded, setExpanded] = useState(false)
  const hasDetails = !!log.details
  const ts = (() => {
    try { return format(new Date(log.ts), 'dd/MM HH:mm:ss', { locale: fr }) } catch { return log.ts }
  })()

  const rowCls = clsx('border-b border-slate-800 hover:bg-slate-800/40 transition-colors', {
    'bg-amber-950/10': log.level === 'WARNING',
    'bg-red-950/20':   log.level === 'ERROR' || log.level === 'CRITICAL',
  })

  return (
    <>
      <tr className={rowCls}>
        <td className="px-3 py-1.5 text-[10px] font-mono text-slate-500 whitespace-nowrap">{ts}</td>
        <td className="px-3 py-1.5 whitespace-nowrap"><LevelBadge level={log.level} /></td>
        <td className="px-3 py-1.5 text-[10px] text-slate-400 max-w-[120px] truncate font-mono">{log.source}</td>
        <td className="px-3 py-1.5 text-[10px] text-slate-500 max-w-[100px] truncate font-mono">
          {log.cycle_id ? log.cycle_id.slice(0, 16) + '…' : '—'}
        </td>
        <td className="px-3 py-1.5 text-[10px] text-blue-400 font-mono">{log.ticker ?? '—'}</td>
        <td className="px-2 py-1.5 w-full">
          <div className="flex items-start gap-1.5">
            {hasDetails && (
              <button
                onClick={() => setExpanded(!expanded)}
                className="mt-0.5 shrink-0 text-slate-600 hover:text-slate-400"
              >
                {expanded ? <ChevronDown className="w-3 h-3" /> : <ChevronRight className="w-3 h-3" />}
              </button>
            )}
            <span className={clsx('text-[11px] leading-snug break-all', {
              'text-slate-300': log.level === 'INFO',
              'text-amber-200': log.level === 'WARNING',
              'text-red-300':   log.level === 'ERROR' || log.level === 'CRITICAL',
            })}>{log.message}</span>
          </div>
        </td>
      </tr>
      {expanded && hasDetails && (
        <tr className={rowCls}>
          <td colSpan={6} className="px-4 pb-2 pt-0">
            <pre className="text-[10px] text-slate-400 bg-slate-900 rounded p-2 overflow-x-auto max-h-40 leading-relaxed">
              {JSON.stringify(JSON.parse(log.details), null, 2)}
            </pre>
          </td>
        </tr>
      )}
    </>
  )
}

// ── AI call type config ──────────────────────────────────────────────────────
const AI_CALL_CONFIG: Record<string, { label: string; color: string; icon: React.ReactNode }> = {
  suggest:     { label: 'Suggestion patterns',  color: 'text-purple-300 border-purple-700/40 bg-purple-900/20', icon: <Brain className="w-3 h-3" /> },
  score_batch: { label: 'Scoring batch',        color: 'text-cyan-300 border-cyan-700/40 bg-cyan-900/20',     icon: <BarChart2 className="w-3 h-3" /> },
  unknown:     { label: 'AI call',              color: 'text-slate-300 border-slate-700/40 bg-slate-800',     icon: <Zap className="w-3 h-3" /> },
}

function AiCallRow({ call }: { call: any }) {
  const [expanded, setExpanded] = useState(false)
  const [activePane, setActivePane] = useState<'user' | 'system' | 'response'>('user')
  const cfg = AI_CALL_CONFIG[call.call_type] ?? AI_CALL_CONFIG.unknown
  const ts = (() => { try { return format(new Date(call.called_at), 'HH:mm:ss', { locale: fr }) } catch { return call.called_at } })()
  const totalTokens = (call.tokens_prompt ?? 0) + (call.tokens_completion ?? 0)

  const responseStr = useMemo(() => {
    if (!call.response) return ''
    try { return JSON.stringify(call.response, null, 2) } catch { return String(call.response) }
  }, [call.response])

  return (
    <div className="border border-slate-800 rounded overflow-hidden">
      <button
        onClick={() => setExpanded(e => !e)}
        className="w-full flex items-center gap-3 px-3 py-2.5 hover:bg-slate-800/50 transition-colors text-left"
      >
        <span className={clsx('inline-flex items-center gap-1.5 px-2 py-0.5 rounded border text-[10px] font-semibold shrink-0', cfg.color)}>
          {cfg.icon} {cfg.label}
        </span>
        <span className="text-[10px] text-slate-500 font-mono shrink-0">{ts}</span>
        {call.pattern_name && (
          <span className="text-[10px] text-slate-400 truncate">— {call.pattern_name}</span>
        )}
        <div className="ml-auto flex items-center gap-3 shrink-0">
          {totalTokens > 0 && (
            <span className="text-[10px] text-slate-600 font-mono">{totalTokens.toLocaleString()} tokens</span>
          )}
          {call.duration_ms > 0 && (
            <span className="text-[10px] text-slate-600 font-mono flex items-center gap-0.5">
              <Clock className="w-2.5 h-2.5" />{(call.duration_ms / 1000).toFixed(1)}s
            </span>
          )}
          {expanded ? <ChevronDown className="w-3.5 h-3.5 text-slate-500" /> : <ChevronRight className="w-3.5 h-3.5 text-slate-500" />}
        </div>
      </button>

      {expanded && (
        <div className="border-t border-slate-800">
          {/* Token breakdown */}
          {totalTokens > 0 && (
            <div className="flex gap-4 px-3 py-2 bg-slate-900/50 text-[10px] font-mono text-slate-500 border-b border-slate-800">
              <span>Model: <span className="text-slate-300">{call.model || 'gpt-4o'}</span></span>
              <span>Prompt: <span className="text-amber-300">{(call.tokens_prompt ?? 0).toLocaleString()} tok</span></span>
              <span>Completion: <span className="text-green-300">{(call.tokens_completion ?? 0).toLocaleString()} tok</span></span>
              <span>Total: <span className="text-white">{totalTokens.toLocaleString()} tok</span></span>
              <span>Duration: <span className="text-purple-300">{(call.duration_ms / 1000).toFixed(2)}s</span></span>
            </div>
          )}
          {/* Pane selector */}
          <div className="flex gap-0 border-b border-slate-800">
            {([
              { key: 'user' as const,     label: 'User prompt',    icon: <MessageSquare className="w-3 h-3" /> },
              { key: 'system' as const,   label: 'System prompt',  icon: <Brain className="w-3 h-3" /> },
              { key: 'response' as const, label: 'AI response',    icon: <Zap className="w-3 h-3" /> },
            ]).map(p => (
              <button
                key={p.key}
                onClick={() => setActivePane(p.key)}
                className={clsx(
                  'flex items-center gap-1 px-3 py-1.5 text-[10px] font-medium border-b-2 -mb-px transition-colors',
                  activePane === p.key
                    ? 'border-purple-500 text-purple-300'
                    : 'border-transparent text-slate-500 hover:text-slate-300'
                )}
              >
                {p.icon} {p.label}
              </button>
            ))}
          </div>
          {/* Content */}
          <div className="p-3 bg-black/40 max-h-[500px] overflow-y-auto">
            {activePane === 'user' && (
              <pre className="text-[10px] font-mono text-slate-300 whitespace-pre-wrap leading-relaxed">{call.user_prompt || '(empty)'}</pre>
            )}
            {activePane === 'system' && (
              <pre className="text-[10px] font-mono text-slate-400 whitespace-pre-wrap leading-relaxed">{call.system_prompt || '(empty)'}</pre>
            )}
            {activePane === 'response' && (
              <pre className="text-[10px] font-mono text-green-300 whitespace-pre-wrap leading-relaxed">{responseStr || '(no response)'}</pre>
            )}
          </div>
        </div>
      )}
    </div>
  )
}

function AiCallsSection({ runId }: { runId: string }) {
  const { data, isLoading } = useAiCallLogs(runId)
  const calls: any[] = data?.calls ?? []

  if (isLoading) return <div className="p-4 text-xs text-slate-500">Loading AI calls…</div>
  if (calls.length === 0) return (
    <div className="p-4 text-xs text-slate-600 text-center">
      No AI calls recorded for this cycle — logs will be available from the next cycle.
    </div>
  )

  return (
    <div className="space-y-2">
      <div className="text-[10px] text-slate-500 px-1 font-mono">
        {calls.length} AI call(s) — click to view prompts + full response
      </div>
      {calls.map(c => <AiCallRow key={c.id} call={c} />)}
    </div>
  )
}

function ContextTab() {
  const [selectedRunId, setSelectedRunId] = useState<string | null>(null)
  const [replayNotes, setReplayNotes] = useState('')
  const [rightPane, setRightPane] = useState<'context' | 'calls'>('context')
  const [replayResult, setReplayResult] = useState<any>(null)
  const { data: snapshotsData, isLoading: loadingList } = useCycleContextSnapshots(30)
  const { data: snapData, isLoading: loadingSnap } = useCycleContextSnapshot(selectedRunId)
  const { mutate: replayCycle, isPending: replaying } = useReplayCycle()
  const snapshots: any[] = snapshotsData?.snapshots ?? []

  const fmtTs = (ts: string) => {
    try { return format(new Date(ts), 'dd/MM HH:mm:ss', { locale: fr }) } catch { return ts }
  }

  const handleReplay = () => {
    if (!selectedRunId) return
    setReplayResult(null)
    replayCycle(
      { runId: selectedRunId, notes: replayNotes || undefined },
      { onSuccess: (data) => setReplayResult(data) }
    )
  }

  return (
    <div className="grid grid-cols-[280px_1fr] gap-4 min-h-[500px]">
      {/* Left: list of snapshots */}
      <div className="card overflow-y-auto max-h-[700px]">
        {loadingList ? (
          <div className="p-4 text-xs text-slate-500">Loading…</div>
        ) : snapshots.length === 0 ? (
          <div className="p-4 text-xs text-slate-600">
            No snapshot — contexts will be saved on the next cycle.
          </div>
        ) : (
          <div className="divide-y divide-slate-800">
            {snapshots.map(s => (
              <button
                key={s.run_id}
                onClick={() => { setSelectedRunId(s.run_id); setReplayResult(null); setRightPane('context') }}
                className={clsx(
                  'w-full text-left px-3 py-2.5 hover:bg-slate-800/60 transition-colors',
                  selectedRunId === s.run_id && 'bg-purple-900/30 border-l-2 border-purple-500'
                )}
              >
                <div className="text-xs font-mono text-slate-300">{fmtTs(s.ts)}</div>
                <div className="text-[10px] text-slate-600 font-mono mt-0.5">{s.run_id.slice(0, 20)}…</div>
              </button>
            ))}
          </div>
        )}
      </div>

      {/* Right: context JSON viewer + replay */}
      <div className="card overflow-hidden flex flex-col">
        {!selectedRunId ? (
          <div className="p-8 text-center text-slate-600 text-sm flex-1">
            <Brain className="w-8 h-8 mx-auto mb-2 opacity-30" />
            Select a cycle on the left to view the full context sent to the AI.
          </div>
        ) : loadingSnap ? (
          <div className="p-8 text-center text-slate-500 text-sm flex-1">Loading context…</div>
        ) : !snapData ? (
          <div className="p-8 text-center text-slate-500 text-sm flex-1">Loading error.</div>
        ) : (
          <>
            {/* Header strip with meta + replay */}
            <div className="flex items-center gap-3 px-4 py-2 border-b border-slate-800 bg-slate-900/60 flex-wrap">
              <span className="text-[10px] font-mono text-slate-400">{snapData.run_id.slice(0, 24)}…</span>
              <span className="text-[10px] text-slate-500">{fmtTs(snapData.ts)}</span>
              {snapData.context?.cycle_meta && (
                <>
                  <span className="text-[10px] text-purple-400">
                    Δ {snapData.context.cycle_meta.delta_minutes?.toFixed(0)}min
                  </span>
                  <span className="text-[10px] text-slate-400">{snapData.context.cycle_meta.calibration_label}</span>
                </>
              )}
              <div className="flex items-center gap-2 ml-auto">
                <input
                  className="bg-slate-800 border border-slate-700 rounded px-2 py-1 text-[10px] text-slate-300 w-48"
                  placeholder="Replay notes (optional)"
                  value={replayNotes}
                  onChange={e => setReplayNotes(e.target.value)}
                />
                <button
                  onClick={handleReplay}
                  disabled={replaying}
                  className="flex items-center gap-1.5 bg-purple-700 hover:bg-purple-600 disabled:opacity-40 text-white px-3 py-1.5 rounded text-xs font-semibold"
                >
                  {replaying
                    ? <><Loader2 className="w-3 h-3 animate-spin" /> Replaying…</>
                    : <><Play className="w-3 h-3" /> Replay this cycle</>}
                </button>
              </div>
            </div>

            {/* Replay result */}
            {replayResult && (
              <div className="border-b border-slate-800 bg-green-950/20 p-3">
                <div className="flex items-center gap-2 mb-2">
                  <span className="text-xs font-semibold text-green-400">
                    Replay complete — {replayResult.suggestions_count} patterns generated
                  </span>
                  <span className="text-[10px] text-slate-500">à {fmtTs(replayResult.replayed_at)}</span>
                </div>
                <div className="space-y-1 max-h-48 overflow-y-auto">
                  {(replayResult.suggestions || []).map((s: any, i: number) => (
                    <div key={i} className="text-[10px] text-slate-300 bg-slate-900 rounded px-2 py-1">
                      <span className="text-green-400 font-mono">{s.name}</span>
                      {s.macro_fit && <span className="text-slate-500 ml-2">— {s.macro_fit?.slice(0, 80)}</span>}
                    </div>
                  ))}
                </div>
              </div>
            )}

            {/* Sub-tabs: Contexte / Appels IA */}
            <div className="flex gap-0 border-b border-slate-800 bg-slate-900/40 shrink-0">
              {([
                { key: 'context' as const, label: 'AI Context', icon: <Brain className="w-3 h-3" /> },
                { key: 'calls' as const,   label: 'AI Calls',   icon: <Zap className="w-3 h-3" /> },
              ]).map(t => (
                <button
                  key={t.key}
                  onClick={() => setRightPane(t.key)}
                  className={clsx(
                    'flex items-center gap-1.5 px-4 py-2 text-[11px] font-medium border-b-2 -mb-px transition-colors',
                    rightPane === t.key
                      ? 'border-purple-500 text-purple-300'
                      : 'border-transparent text-slate-500 hover:text-slate-300'
                  )}
                >
                  {t.icon} {t.label}
                </button>
              ))}
            </div>

            {rightPane === 'context' && (
              <div className="overflow-y-auto flex-1 p-3 space-y-2">
                {snapData.context && Object.entries(snapData.context).map(([key, val]) => (
                  <ContextSection key={key} label={key} value={val} />
                ))}
              </div>
            )}

            {rightPane === 'calls' && (
              <div className="overflow-y-auto flex-1 p-3">
                <AiCallsSection runId={selectedRunId} />
              </div>
            )}
          </>
        )}
      </div>
    </div>
  )
}

function ContextSection({ label, value }: { label: string; value: any }) {
  const [open, setOpen] = useState(['cycle_meta', 'news_partitioned', 'fred_releases', 'price_discovery'].includes(label))
  const json = JSON.stringify(value, null, 2)
  const lineCount = json.split('\n').length

  const labelColor: Record<string, string> = {
    cycle_meta: 'text-purple-400',
    macro_regime: 'text-blue-400',
    geo_score: 'text-orange-400',
    news_partitioned: 'text-yellow-400',
    fred_releases: 'text-green-400',
    price_discovery: 'text-red-400',
    tech_indicators_block: 'text-cyan-400',
    iv_context_preview: 'text-pink-400',
    calendar: 'text-slate-300',
    quotes_summary: 'text-slate-300',
  }

  return (
    <div className="border border-slate-800 rounded overflow-hidden">
      <button
        onClick={() => setOpen(o => !o)}
        className="w-full flex items-center gap-2 px-3 py-2 bg-slate-900/60 hover:bg-slate-800/60 text-left"
      >
        {open ? <ChevronDown className="w-3 h-3 text-slate-500 shrink-0" /> : <ChevronRight className="w-3 h-3 text-slate-500 shrink-0" />}
        <span className={clsx('text-xs font-mono font-semibold', labelColor[label] ?? 'text-slate-300')}>{label}</span>
        <span className="text-[10px] text-slate-600 ml-auto">{lineCount} lines</span>
      </button>
      {open && (
        <pre className="text-[10px] font-mono text-slate-400 bg-slate-950 p-3 overflow-x-auto max-h-80 leading-relaxed">
          {json}
        </pre>
      )}
    </div>
  )
}

export default function SystemLogs() {
  const qc = useQueryClient()
  const [activeTab, setActiveTab] = useState<'logs' | 'context'>('logs')
  const [filters, setFilters] = useState<LogFilters>({ limit: 300 })
  const [tickerInput, setTickerInput] = useState('')
  const [cycleInput, setCycleInput] = useState('')

  const { data, isLoading, isRefetching } = useSystemLogs(filters)
  const { data: sourcesData } = useLogSources()
  const { data: cyclesData } = useLogCycles()
  const { mutate: clearLogs, isPending: clearing } = useClearLogs()

  const logs: any[] = data?.logs ?? []
  const sources: string[] = sourcesData?.sources ?? []
  const cycles: any[] = cyclesData?.cycles ?? []

  // Summary counts
  const counts = useMemo(() => {
    const c = { INFO: 0, WARNING: 0, ERROR: 0, CRITICAL: 0 }
    for (const l of logs) c[l.level as keyof typeof c] = (c[l.level as keyof typeof c] ?? 0) + 1
    return c
  }, [logs])

  const applyFilter = (key: keyof LogFilters, val: string) => {
    setFilters(f => ({ ...f, [key]: val || undefined }))
  }

  const handleClear = () => {
    if (window.confirm('Delete logs older than 30 days?')) {
      clearLogs(30, { onSuccess: () => qc.invalidateQueries({ queryKey: ['system-logs'] }) })
    }
  }

  return (
    <div className="p-6 space-y-4">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-xl font-bold text-white">System Logs</h1>
          <p className="text-xs text-slate-500 mt-0.5">Errors, warnings and full AI cycle contexts</p>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={() => qc.invalidateQueries({ queryKey: ['system-logs'] })}
            className="btn-secondary flex items-center gap-1.5 text-xs px-3 py-1.5"
          >
            <RefreshCw className={clsx('w-3.5 h-3.5', (isLoading || isRefetching) && 'animate-spin')} />
            Refresh
          </button>
          {activeTab === 'logs' && (
            <button
              onClick={handleClear}
              disabled={clearing}
              className="btn-secondary flex items-center gap-1.5 text-xs px-3 py-1.5 text-red-400 border-red-800/40 hover:bg-red-900/20"
            >
              <Trash2 className="w-3.5 h-3.5" />
              Purge &gt;30d
            </button>
          )}
        </div>
      </div>

      {/* Tabs */}
      <div className="flex gap-1 border-b border-slate-800">
        {([
          { key: 'logs',    label: 'System Logs',  icon: <Info className="w-3.5 h-3.5" /> },
          { key: 'context', label: 'AI Context',   icon: <Brain className="w-3.5 h-3.5" /> },
        ] as const).map(tab => (
          <button
            key={tab.key}
            onClick={() => setActiveTab(tab.key)}
            className={clsx(
              'flex items-center gap-1.5 px-4 py-2 text-xs font-medium border-b-2 -mb-px transition-colors',
              activeTab === tab.key
                ? 'border-purple-500 text-purple-300'
                : 'border-transparent text-slate-500 hover:text-slate-300'
            )}
          >
            {tab.icon} {tab.label}
          </button>
        ))}
      </div>

      {activeTab === 'context' && <ContextTab />}

      {activeTab === 'logs' && <>
      {/* Summary chips */}
      <div className="flex items-center gap-3 flex-wrap">
        {[
          { level: 'INFO',     cls: 'bg-slate-800 text-slate-300' },
          { level: 'WARNING',  cls: 'bg-amber-900/40 text-amber-300 border border-amber-700/30' },
          { level: 'ERROR',    cls: 'bg-red-900/40 text-red-300 border border-red-700/30' },
          { level: 'CRITICAL', cls: 'bg-red-800/60 text-red-200 border border-red-600/30' },
        ].map(({ level, cls }) => (
          <button
            key={level}
            onClick={() => applyFilter('level', filters.level === level ? '' : level)}
            className={clsx(
              'px-3 py-1 rounded text-xs font-semibold transition-all',
              cls,
              filters.level === level ? 'ring-1 ring-white/30' : 'opacity-70 hover:opacity-100'
            )}
          >
            {level} · {counts[level as keyof typeof counts] ?? 0}
          </button>
        ))}
        <span className="text-xs text-slate-600 ml-auto">{logs.length} entries</span>
      </div>

      {/* Filters */}
      <div className="card p-3 grid grid-cols-2 gap-3 md:grid-cols-4">
        <div>
          <label className="text-[9px] text-slate-500 uppercase tracking-wide block mb-1">Source</label>
          <select
            className="w-full bg-slate-800 border border-slate-700 rounded px-2 py-1 text-xs text-slate-300"
            value={filters.source ?? ''}
            onChange={e => applyFilter('source', e.target.value)}
          >
            <option value="">All</option>
            {sources.map(s => <option key={s} value={s}>{s}</option>)}
          </select>
        </div>

        <div>
          <label className="text-[9px] text-slate-500 uppercase tracking-wide block mb-1">Cycle</label>
          <select
            className="w-full bg-slate-800 border border-slate-700 rounded px-2 py-1 text-xs text-slate-300"
            value={filters.cycle_id ?? ''}
            onChange={e => applyFilter('cycle_id', e.target.value)}
          >
            <option value="">All</option>
            {cycles.map(c => (
              <option key={c.cycle_id} value={c.cycle_id}>
                {c.first_ts ? format(new Date(c.first_ts), 'dd/MM HH:mm') : c.cycle_id.slice(0, 16)}
              </option>
            ))}
          </select>
        </div>

        <div>
          <label className="text-[9px] text-slate-500 uppercase tracking-wide block mb-1">Ticker</label>
          <input
            className="w-full bg-slate-800 border border-slate-700 rounded px-2 py-1 text-xs text-slate-300"
            placeholder="ex: SPY"
            value={tickerInput}
            onChange={e => setTickerInput(e.target.value.toUpperCase())}
            onBlur={() => applyFilter('ticker', tickerInput)}
            onKeyDown={e => e.key === 'Enter' && applyFilter('ticker', tickerInput)}
          />
        </div>

        <div className="grid grid-cols-2 gap-2">
          <div>
            <label className="text-[9px] text-slate-500 uppercase tracking-wide block mb-1">From</label>
            <input
              type="date"
              className="w-full bg-slate-800 border border-slate-700 rounded px-2 py-1 text-xs text-slate-300"
              value={filters.date_from ?? ''}
              onChange={e => applyFilter('date_from', e.target.value)}
            />
          </div>
          <div>
            <label className="text-[9px] text-slate-500 uppercase tracking-wide block mb-1">Until</label>
            <input
              type="date"
              className="w-full bg-slate-800 border border-slate-700 rounded px-2 py-1 text-xs text-slate-300"
              value={filters.date_to ?? ''}
              onChange={e => applyFilter('date_to', e.target.value)}
            />
          </div>
        </div>
      </div>

      {/* Log table */}
      <div className="card overflow-hidden">
        {isLoading ? (
          <div className="p-8 text-center text-slate-500 text-sm">Loading…</div>
        ) : logs.length === 0 ? (
          <div className="p-8 text-center text-slate-600 text-sm">
            No logs found for these filters.<br />
            <span className="text-xs text-slate-700">WARNING and ERROR entries from cycles appear here automatically.</span>
          </div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-xs">
              <thead>
                <tr className="border-b border-slate-700 text-[9px] uppercase tracking-wide text-slate-500">
                  <th className="px-3 py-2 text-left font-medium whitespace-nowrap">Timestamp</th>
                  <th className="px-3 py-2 text-left font-medium">Level</th>
                  <th className="px-3 py-2 text-left font-medium">Source</th>
                  <th className="px-3 py-2 text-left font-medium">Cycle</th>
                  <th className="px-3 py-2 text-left font-medium">Ticker</th>
                  <th className="px-3 py-2 text-left font-medium w-full">Message</th>
                </tr>
              </thead>
              <tbody>
                {logs.map(log => <LogRow key={log.id} log={log} />)}
              </tbody>
            </table>
          </div>
        )}
      </div>
      </>}
    </div>
  )
}
