import { useState, useEffect, useRef, Fragment } from 'react'
import { BookOpen, TrendingUp, TrendingDown, Activity, AlertTriangle, RefreshCw, Zap, CheckCircle, XCircle, Brain, Trash2, Search, X, ChevronDown, ChevronUp, Terminal, Lock, ShieldAlert, PieChart, Target } from 'lucide-react'
import { TradeIdeasTab } from '../components/TradeIdeas'
import clsx from 'clsx'
import { useJournalSummary, useMacroHistory, useGeoHistory, useTradeMtm, useClosedTrades, useCloseTrade, useUpdateExitParams, useExitDefaults, useCycleHistory, useCycleStatus, useTriggerCycle, useTradePostmortem, useAnalyzePostmortem, useIvForTrade, useKellySizing, useSimPortfolioRisk, useSkippedTrades, api } from '../hooks/useApi'
import { useQueryClient } from '@tanstack/react-query'
import { format } from 'date-fns'
import { fr } from 'date-fns/locale'

const SCENARIO_META: Record<string, { label: string; color: string; emoji: string }> = {
  goldilocks:      { label: 'Goldilocks',      color: '#22c55e', emoji: '🌟' },
  desinflation:    { label: 'Désinflation',    color: '#06b6d4', emoji: '❄️' },
  soft_landing:    { label: 'Soft Landing',    color: '#3b82f6', emoji: '🛬' },
  reflation:       { label: 'Reflation',       color: '#f97316', emoji: '🔥' },
  stagflation:     { label: 'Stagflation',     color: '#eab308', emoji: '⚡' },
  inflation_shock: { label: 'Inflation Shock', color: '#ef4444', emoji: '💥' },
  recession:       { label: 'Récession',       color: '#8b5cf6', emoji: '📉' },
  crise_liquidite: { label: 'Crise Liquidité', color: '#ec4899', emoji: '🚨' },
  incertain:       { label: 'Incertain',       color: '#64748b', emoji: '❓' },
}

function ScenarioBadge({ dominant, size = 'sm' }: { dominant: string; size?: 'sm' | 'lg' }) {
  const m = SCENARIO_META[dominant] ?? SCENARIO_META.incertain
  return (
    <span
      className={clsx('inline-flex items-center gap-1 rounded font-semibold',
        size === 'lg' ? 'px-2.5 py-1 text-sm' : 'px-1.5 py-0.5 text-[11px]')}
      style={{ background: `${m.color}22`, color: m.color, border: `1px solid ${m.color}44` }}
    >
      {m.emoji} {m.label}
    </span>
  )
}

function PnlBadge({ pnl }: { pnl: number | null | undefined }) {
  if (pnl == null) return <span className="text-slate-600 text-xs">—</span>
  const pos = pnl >= 0
  return (
    <span className={clsx('inline-flex items-center gap-0.5 text-xs font-bold font-mono',
      pos ? 'text-emerald-400' : 'text-red-400')}>
      {pos ? <TrendingUp className="w-3 h-3" /> : <TrendingDown className="w-3 h-3" />}
      {pos ? '+' : ''}{pnl.toFixed(2)}%
    </span>
  )
}

function ScoreDelta({ entry, latest }: { entry: number | null; latest: number | null }) {
  if (entry == null || latest == null) return <span className="text-slate-600 text-[10px]">—</span>
  const delta = latest - entry
  return (
    <span className="flex flex-col items-end gap-0.5">
      <span className={clsx('font-bold font-mono text-xs',
        latest >= 50 ? 'text-emerald-400' : latest >= 25 ? 'text-yellow-400' : 'text-slate-500')}>
        {latest}
      </span>
      {delta !== 0 && (
        <span className={clsx('text-[10px] font-mono', delta > 0 ? 'text-emerald-600' : 'text-red-600')}>
          {delta > 0 ? '+' : ''}{delta}
        </span>
      )}
    </span>
  )
}

// ── Section 1 : Historique des régimes macro ──────────────────────────────────

function IvRankCell({ underlying }: { underlying: string }) {
  const { data, isLoading } = useIvForTrade(underlying)
  if (isLoading) return <span className="text-slate-700 text-[10px]">…</span>
  const rank = data?.iv_rank
  const iv   = data?.iv_current_pct
  if (rank == null) return <span className="text-slate-700 text-[10px]">—</span>

  const color = rank >= 80 ? 'text-red-400' : rank >= 50 ? 'text-amber-400' : rank >= 20 ? 'text-emerald-400' : 'text-blue-400'
  const signal = rank >= 80 ? '↓vol' : rank < 20 ? '↑vol' : ''

  return (
    <div className="flex flex-col items-end gap-0.5">
      <span className={clsx('text-[10px] font-bold font-mono', color)}>
        {rank}%
      </span>
      <span className="text-[8px] text-slate-600">{iv != null ? `IV ${iv}%` : ''}</span>
      {signal && <span className={clsx('text-[8px] font-semibold', color)}>{signal}</span>}
    </div>
  )
}

function KellyCell({ patternId, capital = 10000 }: { patternId: string; capital?: number }) {
  const { data, isLoading } = useKellySizing(patternId, capital)
  if (!patternId || isLoading) return <span className="text-slate-700 text-[10px]">…</span>
  if (!data || data.error) return <span className="text-slate-700 text-[10px]">—</span>
  const pct = data.suggested_capital_pct
  const eur = data.suggested_capital_eur
  const color = pct <= 0 ? 'text-slate-600' : pct < 5 ? 'text-amber-400' : 'text-emerald-400'
  const adjusted = data.cluster_adjustment_reason || data.reliability_adjustment
  return (
    <div className="flex flex-col items-end gap-0.5">
      <span className={clsx('text-[10px] font-bold font-mono', color)}>{pct?.toFixed(1)}%</span>
      <span className="text-[8px] text-slate-600">{eur != null ? `${eur}€` : ''}</span>
      {adjusted && <span className="text-[8px] text-orange-400" title={adjusted}>⚠ ajusté</span>}
    </div>
  )
}

// ── Close Trade Modal ─────────────────────────────────────────────────────────

const CLOSE_REASONS = [
  { value: 'target', label: '🎯 Objectif atteint' },
  { value: 'stop_loss', label: '🛑 Stop-loss déclenché' },
  { value: 'signal_reversal', label: '🔄 Signal IA retourné' },
  { value: 'manual', label: '✍️ Fermeture manuelle' },
]

function CloseTradeModal({ trade, onClose }: { trade: any; onClose: () => void }) {
  const { mutate, isPending, isError } = useCloseTrade()
  const [closePrice, setClosePrice] = useState(String(trade.current_price ?? trade.entry_price ?? ''))
  const [reason, setReason] = useState(trade.alert_type === 'target_reached' ? 'target' :
    trade.alert_type === 'stop_loss' ? 'stop_loss' : 'manual')
  const [note, setNote] = useState('')

  const ep = parseFloat(closePrice) || 0
  const isBearish = trade.direction === 'bearish'
  const pnlPreview = trade.entry_price && ep > 0
    ? (() => {
        const raw = (ep - trade.entry_price) / trade.entry_price * 100
        return round2(isBearish ? -raw : raw)
      })()
    : null

  function round2(n: number) { return Math.round(n * 100) / 100 }

  const handleSubmit = () => {
    mutate({
      id: trade.id,
      body: { close_price: ep, close_reason: reason, close_note: note }
    }, { onSuccess: onClose })
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
      <div className="bg-dark-800 border border-slate-700/60 rounded-xl w-full max-w-md p-6 space-y-5 shadow-2xl">
        <div className="flex items-center justify-between">
          <div>
            <div className="text-sm font-bold text-white flex items-center gap-2">
              <Lock className="w-4 h-4 text-amber-400" /> Fermer le trade
            </div>
            <div className="text-xs text-slate-500 mt-0.5">
              {trade.underlying} · {trade.strategy} · entrée {trade.entry_price?.toFixed(2) ?? '—'}
            </div>
          </div>
          <button onClick={onClose} className="text-slate-600 hover:text-slate-400"><X className="w-4 h-4" /></button>
        </div>

        {trade.alert_type && (
          <div className={clsx('text-xs rounded px-3 py-2 font-semibold border',
            trade.alert_type === 'target_reached'
              ? 'bg-emerald-900/30 border-emerald-700/40 text-emerald-300'
              : 'bg-red-900/30 border-red-700/40 text-red-300')}>
            {trade.alert_type === 'target_reached' ? '🎯 Objectif atteint !' : '🛑 Stop-loss atteint'}
            {' — P&L actuel '}
            <span className="font-mono">{trade.pnl_pct >= 0 ? '+' : ''}{trade.pnl_pct?.toFixed(2)}%</span>
          </div>
        )}

        <div className="space-y-3">
          <div>
            <label className="block text-xs text-slate-500 mb-1">Prix de clôture</label>
            <input
              type="number" step="0.01"
              value={closePrice}
              onChange={e => setClosePrice(e.target.value)}
              className="w-full bg-dark-700 border border-slate-600/50 rounded px-3 py-1.5 text-sm text-white font-mono"
              placeholder="Prix actuel du sous-jacent"
            />
            {pnlPreview !== null && (
              <div className={clsx('text-xs mt-1 font-mono font-bold',
                pnlPreview >= 0 ? 'text-emerald-400' : 'text-red-400')}>
                P&L réalisé : {pnlPreview >= 0 ? '+' : ''}{pnlPreview}%
              </div>
            )}
          </div>

          <div>
            <label className="block text-xs text-slate-500 mb-1">Motif de fermeture</label>
            <select
              value={reason}
              onChange={e => setReason(e.target.value)}
              className="w-full bg-dark-700 border border-slate-600/50 rounded px-3 py-1.5 text-sm text-white"
            >
              {CLOSE_REASONS.map(r => (
                <option key={r.value} value={r.value}>{r.label}</option>
              ))}
            </select>
          </div>

          <div>
            <label className="block text-xs text-slate-500 mb-1">Note (optionnel)</label>
            <input
              type="text"
              value={note}
              onChange={e => setNote(e.target.value)}
              className="w-full bg-dark-700 border border-slate-600/50 rounded px-3 py-1.5 text-sm text-white"
              placeholder="Contexte, raison…"
              maxLength={200}
            />
          </div>
        </div>

        {isError && <div className="text-xs text-red-400">Erreur lors de la fermeture du trade.</div>}

        <div className="flex gap-3 pt-1">
          <button onClick={onClose}
            className="flex-1 px-4 py-2 rounded border border-slate-700/50 text-slate-400 hover:text-slate-200 text-sm">
            Annuler
          </button>
          <button
            onClick={handleSubmit}
            disabled={isPending || ep === 0}
            className="flex-1 px-4 py-2 rounded bg-amber-600 hover:bg-amber-500 disabled:opacity-50 text-white text-sm font-semibold flex items-center justify-center gap-2"
          >
            <Lock className="w-3.5 h-3.5" />
            {isPending ? 'Fermeture…' : 'Confirmer la fermeture'}
          </button>
        </div>
      </div>
    </div>
  )
}

// ── Closed Trades Section ─────────────────────────────────────────────────────

function ClosedTradesSection({ days }: { days: number }) {
  const { data, isLoading, refetch, isFetching } = useClosedTrades(days)
  const trades: any[] = (data as any)?.trades ?? []
  const stats: any = (data as any)?.stats ?? {}

  const REASON_META: Record<string, { label: string; color: string }> = {
    target:          { label: '🎯 Objectif', color: 'text-emerald-400' },
    stop_loss:       { label: '🛑 Stop-loss', color: 'text-red-400' },
    signal_reversal: { label: '🔄 Signal IA', color: 'text-blue-400' },
    manual:          { label: '✍️ Manuel', color: 'text-slate-400' },
  }

  return (
    <div className="space-y-4">
      {/* Stats banner */}
      {trades.length > 0 && (
        <div className="grid grid-cols-4 gap-3">
          {[
            { label: 'Trades fermés', value: stats.total ?? 0, sub: '', color: 'text-white' },
            { label: 'Taux de succès', value: stats.win_rate != null ? `${stats.win_rate}%` : '—', sub: '', color: stats.win_rate >= 50 ? 'text-emerald-400' : 'text-red-400' },
            { label: 'P&L moyen', value: stats.avg_pnl != null ? `${stats.avg_pnl >= 0 ? '+' : ''}${stats.avg_pnl?.toFixed(1)}%` : '—', sub: '', color: (stats.avg_pnl ?? 0) >= 0 ? 'text-emerald-400' : 'text-red-400' },
            { label: 'P&L total', value: stats.total_pnl != null ? `${stats.total_pnl >= 0 ? '+' : ''}${stats.total_pnl?.toFixed(1)}%` : '—', sub: `meilleur ${stats.best?.toFixed(1) ?? '—'}%`, color: (stats.total_pnl ?? 0) >= 0 ? 'text-emerald-400' : 'text-red-400' },
          ].map(s => (
            <div key={s.label} className="card text-center py-3">
              <div className={clsx('text-lg font-bold font-mono', s.color)}>{s.value}</div>
              <div className="text-[11px] text-slate-600">{s.label}</div>
              {s.sub && <div className="text-[10px] text-slate-700 mt-0.5">{s.sub}</div>}
            </div>
          ))}
        </div>
      )}

      <div className="flex items-center justify-between">
        <div className="text-xs font-semibold text-slate-500 uppercase tracking-wide">
          {trades.length} trades clôturés · {days} derniers jours
        </div>
        <button onClick={() => refetch()} disabled={isFetching}
          className="text-slate-600 hover:text-slate-400 disabled:opacity-40">
          <RefreshCw className={clsx('w-3.5 h-3.5', isFetching && 'animate-spin')} />
        </button>
      </div>

      {isLoading ? (
        <div className="card h-32 animate-pulse bg-dark-700" />
      ) : trades.length === 0 ? (
        <div className="card text-center py-12 text-slate-600 text-sm">
          <Lock className="w-8 h-8 mx-auto mb-2 opacity-20" />
          Aucun trade clôturé dans les {days} derniers jours
        </div>
      ) : (
        <div className="overflow-x-auto rounded-lg border border-slate-700/40">
          <table className="w-full text-xs">
            <thead>
              <tr className="text-slate-600 border-b border-slate-700/40">
                <th className="text-left px-3 py-2 font-medium">Pattern</th>
                <th className="text-left px-3 py-2 font-medium">Stratégie</th>
                <th className="text-left px-3 py-2 font-medium">Ticker</th>
                <th className="text-right px-3 py-2 font-medium">Entrée</th>
                <th className="text-right px-3 py-2 font-medium">Sortie</th>
                <th className="text-right px-3 py-2 font-medium">Date entrée</th>
                <th className="text-right px-3 py-2 font-medium">Date sortie</th>
                <th className="text-right px-3 py-2 font-medium">Durée</th>
                <th className="text-right px-3 py-2 font-medium">P&L réalisé</th>
                <th className="text-left px-3 py-2 font-medium">Motif</th>
                <th className="text-left px-3 py-2 font-medium">Note</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-800/60">
              {trades.map((t: any) => {
                const meta = REASON_META[t.close_reason] ?? REASON_META.manual
                const daysHeld = t.entry_date && t.closed_at
                  ? Math.round((new Date(t.closed_at).getTime() - new Date(t.entry_date).getTime()) / 86400000)
                  : null
                return (
                  <tr key={t.id} className="hover:bg-dark-700/30 transition-colors">
                    <td className="px-3 py-2 text-slate-300 max-w-[100px] truncate">{t.pattern_name || t.pattern_id}</td>
                    <td className="px-3 py-2">
                      <span className={clsx('badge text-[10px]',
                        t.strategy?.toLowerCase().includes('put') || t.strategy?.toLowerCase().includes('bear')
                          ? 'badge-red' : 'badge-green')}>
                        {t.strategy || '—'}
                      </span>
                    </td>
                    <td className="px-3 py-2 font-mono text-slate-300">{t.underlying}</td>
                    <td className="px-3 py-2 text-right font-mono text-slate-500 text-[11px]">
                      {t.entry_price != null ? t.entry_price.toFixed(2) : '—'}
                    </td>
                    <td className="px-3 py-2 text-right font-mono text-slate-400 text-[11px]">
                      {t.close_price != null ? t.close_price.toFixed(2) : '—'}
                    </td>
                    <td className="px-3 py-2 text-right text-slate-600 text-[11px]">{t.entry_date ?? '—'}</td>
                    <td className="px-3 py-2 text-right text-slate-600 text-[11px]">
                      {t.closed_at ? t.closed_at.slice(0, 10) : '—'}
                    </td>
                    <td className="px-3 py-2 text-right text-slate-600 text-[11px] font-mono">
                      {daysHeld != null ? `${daysHeld}j` : '—'}
                    </td>
                    <td className="px-3 py-2 text-right">
                      {t.pnl_realized != null ? (
                        <span className={clsx('font-bold font-mono text-xs',
                          t.pnl_realized >= 0 ? 'text-emerald-400' : 'text-red-400')}>
                          {t.pnl_realized >= 0 ? '+' : ''}{t.pnl_realized.toFixed(2)}%
                        </span>
                      ) : <span className="text-slate-600">—</span>}
                    </td>
                    <td className="px-3 py-2">
                      <span className={clsx('text-[10px] font-medium', meta.color)}>{meta.label}</span>
                    </td>
                    <td className="px-3 py-2 text-slate-600 text-[10px] max-w-[120px] truncate" title={t.close_note}>
                      {t.close_note || '—'}
                    </td>
                  </tr>
                )
              })}
            </tbody>
          </table>
        </div>
      )}
    </div>
  )
}

// ── IBKR Ticket helpers ───────────────────────────────────────────────────────

function computeStrikeDollars(price: number, guidance: string, strategy: string): number {
  const g = guidance.toUpperCase()
  const match = g.match(/(\d+)\s*%\s*OTM/)
  if (!match) return price
  const pct = parseInt(match[1]) / 100
  const isBearish = /put|bear/i.test(strategy)
  const raw = isBearish ? price * (1 - pct) : price * (1 + pct)
  const inc = price > 1000 ? 10 : price > 200 ? 5 : price > 50 ? 1 : 0.5
  return Math.round(raw / inc) * inc
}

function estimateExpiryDate(horizonDays: number): Date {
  const d = new Date()
  d.setDate(d.getDate() + horizonDays)
  const dow = d.getDay()
  if (dow !== 5) d.setDate(d.getDate() + ((5 - dow + 7) % 7))
  return d
}

function buildLegs(strategy: string, strike: number | null, price: number | null) {
  const s = strategy.toLowerCase()
  const atm = price ? (() => {
    const inc = price > 1000 ? 10 : price > 200 ? 5 : price > 50 ? 1 : 0.5
    return Math.round(price / inc) * inc
  })() : null
  if (s.includes('bull call spread')) return [
    { action: 'BUY',  type: 'CALL', strike: atm },
    { action: 'SELL', type: 'CALL', strike },
  ]
  if (s.includes('bear put spread')) return [
    { action: 'BUY',  type: 'PUT', strike: atm },
    { action: 'SELL', type: 'PUT', strike },
  ]
  if (s.includes('straddle')) return [
    { action: 'BUY', type: 'CALL', strike: atm ?? strike },
    { action: 'BUY', type: 'PUT',  strike: atm ?? strike },
  ]
  if (s.includes('strangle')) return [
    { action: 'BUY', type: 'CALL', strike: price ? Math.round(price * 1.05) : strike },
    { action: 'BUY', type: 'PUT',  strike: price ? Math.round(price * 0.95) : strike },
  ]
  if (s.includes('call')) return [{ action: 'BUY', type: 'CALL', strike }]
  if (s.includes('put'))  return [{ action: 'BUY', type: 'PUT',  strike }]
  return [{ action: 'BUY', type: strategy.toUpperCase(), strike }]
}

function IBKRTicket({ strategy, underlying, strikeGuidance, expiryDays, entryPrice, maxLoss, targetGain }: {
  strategy: string
  underlying: string
  strikeGuidance?: string | null
  expiryDays?: number | null
  entryPrice?: number | null
  maxLoss?: number | null
  targetGain?: number | null
}) {
  const strike = entryPrice && strikeGuidance
    ? computeStrikeDollars(entryPrice, strikeGuidance, strategy)
    : (entryPrice ?? null)
  const expiryDate = expiryDays ? estimateExpiryDate(expiryDays) : null
  const legs = buildLegs(strategy, strike, entryPrice ?? null)
  const fmtStrike = (s: number | null | undefined) =>
    s == null ? '—' : s >= 100 ? `$${s.toFixed(0)}` : `$${s.toFixed(2)}`

  return (
    <div className="bg-blue-950/20 border border-blue-700/30 rounded p-3 space-y-2.5">
      <div className="text-[10px] font-bold text-blue-300 uppercase tracking-wide flex items-center gap-1.5">
        <Terminal className="w-3 h-3" /> Ticket IBKR
        {!entryPrice && <span className="ml-auto text-slate-600 font-normal normal-case">Prix non disponible — vérifier dans IBKR</span>}
      </div>

      <div className="grid grid-cols-3 gap-3 text-[10px]">
        <div>
          <div className="text-slate-600 mb-0.5">Sous-jacent</div>
          <div className="text-white font-mono font-bold text-sm">{underlying}</div>
          <div className="text-slate-600 text-[9px]">Security Type: OPT</div>
        </div>
        <div>
          <div className="text-slate-600 mb-0.5">Stratégie</div>
          <div className="text-slate-200 font-semibold">{strategy}</div>
          {entryPrice && <div className="text-slate-600 text-[9px]">Sous-jacent: ${entryPrice.toFixed(2)}</div>}
        </div>
        <div>
          <div className="text-slate-600 mb-0.5">Expiration</div>
          <div className="text-slate-200 font-mono">
            {expiryDate ? format(expiryDate, 'd MMM yyyy', { locale: fr }) : expiryDays ? `~${expiryDays}j` : '—'}
          </div>
          <div className="text-slate-600 text-[9px]">{expiryDays ? `${expiryDays}j DTE` : ''}</div>
        </div>
      </div>

      <div className="space-y-1">
        {legs.map((leg, i) => (
          <div key={i} className="flex items-center gap-2 bg-slate-900/70 rounded px-2.5 py-1.5 font-mono text-[10px]">
            <span className={clsx('w-8 font-bold', leg.action === 'BUY' ? 'text-emerald-400' : 'text-red-400')}>{leg.action}</span>
            <span className="text-slate-400">1 contrat</span>
            <span className={clsx('font-bold w-10 text-center', leg.type === 'CALL' ? 'text-blue-300' : leg.type === 'PUT' ? 'text-orange-300' : 'text-slate-300')}>{leg.type}</span>
            <span className="text-slate-600">Strike</span>
            <span className="text-yellow-300 font-bold">{fmtStrike(leg.strike)}</span>
            {leg.strike === null && strikeGuidance && (
              <span className="text-slate-500">({strikeGuidance})</span>
            )}
          </div>
        ))}
      </div>

      <div className="grid grid-cols-3 gap-3 text-[10px]">
        <div>
          <div className="text-slate-600 mb-0.5">Type d'ordre</div>
          <div className="text-slate-300 font-semibold">LIMIT</div>
          <div className="text-slate-600 text-[9px]">Prix = prime dans IBKR</div>
        </div>
        <div>
          <div className="text-slate-600 mb-0.5">Budget max</div>
          <div className="text-slate-300 font-mono">{maxLoss ? `${Math.abs(maxLoss).toFixed(0)}€` : '~1 000€'}</div>
          <div className="text-slate-600 text-[9px]">Perte max estimée</div>
        </div>
        <div>
          <div className="text-slate-600 mb-0.5">Cible</div>
          <div className="text-emerald-400 font-mono">{targetGain ? `+${targetGain.toFixed(0)}€` : '—'}</div>
        </div>
      </div>
    </div>
  )
}

function MacroHistorySection({ days }: { days: number }) {
  const { data, isLoading, refetch, isFetching } = useMacroHistory(days)
  const history: any[] = (data as any)?.history ?? []

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between">
        <div className="text-xs font-semibold text-slate-500 uppercase tracking-wide">
          {history.length} snapshots · {days} derniers jours
        </div>
        <button onClick={() => refetch()} disabled={isFetching}
          className="text-slate-600 hover:text-slate-400 disabled:opacity-40">
          <RefreshCw className={clsx('w-3.5 h-3.5', isFetching && 'animate-spin')} />
        </button>
      </div>

      {isLoading ? (
        <div className="space-y-2">{[1,2,3].map(i => <div key={i} className="card h-14 animate-pulse bg-dark-700" />)}</div>
      ) : history.length === 0 ? (
        <div className="card text-center py-10 text-slate-600 text-sm">
          <Activity className="w-8 h-8 mx-auto mb-2 opacity-20" />
          Aucun snapshot — cliquer "Ré-analyser" dans Régime Macro pour commencer à logger
        </div>
      ) : (
        <div className="space-y-2">
          {history.map((entry: any, i: number) => {
            const scores: Record<string, number> = entry.scores ?? {}
            const maxScore = Math.max(...Object.values(scores), 1)
            const ts = entry.timestamp?.slice(0, 16).replace('T', ' ') ?? ''
            const reasons: string[] = entry.reasons?.[entry.dominant] ?? []
            const isTransition = i > 0 && history[i - 1].dominant !== entry.dominant

            return (
              <div key={entry.id} className={clsx('card', isTransition && 'border-amber-700/30')}>
                <div className="flex items-center gap-3 mb-2">
                  {isTransition && (
                    <span className="text-[10px] bg-amber-900/30 text-amber-400 border border-amber-700/30 rounded px-1.5 py-0.5 shrink-0">
                      ↕ Transition
                    </span>
                  )}
                  <ScenarioBadge dominant={entry.dominant} size="lg" />
                  <span className="text-xs text-slate-600 ml-auto shrink-0">{ts} UTC</span>
                </div>

                <div className="grid grid-cols-4 gap-x-3 gap-y-1 mb-2">
                  {Object.entries(scores)
                    .sort(([, a], [, b]) => (b as number) - (a as number))
                    .slice(0, 8)
                    .map(([key, score]) => {
                      const m = SCENARIO_META[key] ?? SCENARIO_META.incertain
                      return (
                        <div key={key} className="flex items-center gap-1">
                          <div className="w-16 text-[10px] text-slate-600 truncate">{m.label}</div>
                          <div className="flex-1 h-1.5 bg-dark-700 rounded-full overflow-hidden">
                            <div className="h-full rounded-full transition-all"
                              style={{ width: `${((score as number) / maxScore) * 100}%`, background: m.color }} />
                          </div>
                          <span className="text-[10px] font-mono text-slate-500 w-6 text-right">{score}</span>
                        </div>
                      )
                    })}
                </div>

                {reasons.length > 0 && (
                  <div className="flex flex-wrap gap-1">
                    {reasons.slice(0, 4).map((r: string, ri: number) => (
                      <span key={ri} className="text-[10px] text-slate-500 bg-dark-700 px-1.5 py-0.5 rounded">{r}</span>
                    ))}
                  </div>
                )}
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}

// ── Post-mortem panel ─────────────────────────────────────────────────────────

function PostmortemPanel({ tradeId, onClose }: { tradeId: number; onClose: () => void }) {
  const { data, isLoading } = useTradePostmortem(tradeId)
  const { mutate: analyze, isPending: analyzing, data: analysisData } = useAnalyzePostmortem()
  const [showScoring, setShowScoring] = useState(true)
  const [showSuggestion, setShowSuggestion] = useState(false)

  if (isLoading) {
    return (
      <div className="card mt-3 p-4 border border-blue-700/30 animate-pulse">
        <div className="h-4 bg-dark-700 rounded w-48 mb-3" />
        <div className="h-3 bg-dark-700 rounded w-full mb-2" />
        <div className="h-3 bg-dark-700 rounded w-3/4" />
      </div>
    )
  }
  if (!data) return null

  const { trade, scoring_context: sc, suggestion_context: sg, score_history } = data as any
  const scOut = sc?.output ?? {}
  const sgOut = sg?.output ?? {}
  const scCtx = sc?.input_context ?? {}
  const buckets: any[] = scOut.buckets ?? []
  const analysis: any = analysisData?.analysis ?? null

  return (
    <div className="mt-3 rounded-lg border border-blue-700/30 bg-dark-900/80 p-4 space-y-4 text-xs">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <Brain className="w-4 h-4 text-blue-400" />
          <span className="font-semibold text-blue-300">Post-mortem — {trade?.pattern_name}</span>
          <span className="text-slate-500">|</span>
          <span className="font-mono text-slate-400">{trade?.underlying} {trade?.strategy}</span>
        </div>
        <button onClick={onClose} className="text-slate-600 hover:text-slate-400">
          <X className="w-4 h-4" />
        </button>
      </div>

      {/* Score history sparkline */}
      {score_history?.length > 0 && (
        <div className="flex items-center gap-3">
          <span className="text-slate-600 shrink-0">Historique :</span>
          <div className="flex items-center gap-1.5 flex-wrap">
            {[...score_history].reverse().map((h: any, i: number) => (
              <div key={i} className="flex flex-col items-center gap-0.5">
                <div
                  className="w-6 rounded-sm"
                  style={{
                    height: `${Math.max(4, (h.score ?? 0) / 2)}px`,
                    background: (h.score ?? 0) >= 60 ? '#22c55e' : (h.score ?? 0) >= 40 ? '#eab308' : '#64748b',
                  }}
                />
                <span className="text-[9px] font-mono text-slate-600">{h.score ?? '?'}</span>
              </div>
            ))}
          </div>
          {score_history.length > 0 && (
            <span className="text-slate-600 ml-auto shrink-0">
              {score_history[0]?.macro_dominant ?? ''} — géo {score_history[0]?.geo_score ?? '?'}
            </span>
          )}
        </div>
      )}

      {/* Scoring context */}
      <div>
        <button
          className="flex items-center gap-1.5 text-slate-400 hover:text-slate-200 font-semibold mb-2"
          onClick={() => setShowScoring(v => !v)}
        >
          {showScoring ? <ChevronUp className="w-3.5 h-3.5" /> : <ChevronDown className="w-3.5 h-3.5" />}
          Pourquoi noté {scOut.score ?? '?'}/100
          {scOut.key_catalyst && <span className="text-slate-600 font-normal ml-1">· {scOut.key_catalyst}</span>}
        </button>
        {showScoring && (
          <div className="pl-5 space-y-2">
            {/* Regime / bias */}
            <div className="flex flex-wrap gap-3 text-[11px] text-slate-500">
              {sc?.macro_dominant && (
                <span>Régime : <ScenarioBadge dominant={sc.macro_dominant} /></span>
              )}
              {scCtx.asset_bias && (
                <span>Biais asset : <span className="text-slate-300">{scCtx.asset_bias}</span></span>
              )}
              {sc?.geo_score != null && (
                <span>Géo : <span className="font-mono text-slate-300">{sc.geo_score}/100</span></span>
              )}
            </div>
            {/* Buckets */}
            {buckets.length > 0 && (
              <div className="grid grid-cols-2 gap-1.5">
                {buckets.map((b: any, i: number) => {
                  const pct = b.max ? Math.round((b.score / b.max) * 100) : 0
                  const color = pct >= 66 ? '#22c55e' : pct >= 33 ? '#eab308' : '#ef4444'
                  return (
                    <div key={i} className="flex flex-col gap-0.5 bg-dark-800 rounded p-2">
                      <div className="flex items-center justify-between">
                        <span className="text-slate-400 font-medium truncate mr-2">{b.label ?? b.id}</span>
                        <span className="font-mono shrink-0" style={{ color }}>{b.score}/{b.max}</span>
                      </div>
                      <div className="h-1 bg-dark-700 rounded-full overflow-hidden">
                        <div className="h-full rounded-full" style={{ width: `${pct}%`, background: color }} />
                      </div>
                      {b.comment && (
                        <span className="text-[10px] text-slate-600 line-clamp-2">{b.comment}</span>
                      )}
                    </div>
                  )
                })}
              </div>
            )}
            {scOut.summary && (
              <p className="text-slate-500 italic">{scOut.summary}</p>
            )}
          </div>
        )}
      </div>

      {/* Suggestion context */}
      {sg && (
        <div>
          <button
            className="flex items-center gap-1.5 text-slate-400 hover:text-slate-200 font-semibold mb-2"
            onClick={() => setShowSuggestion(v => !v)}
          >
            {showSuggestion ? <ChevronUp className="w-3.5 h-3.5" /> : <ChevronDown className="w-3.5 h-3.5" />}
            Pourquoi ce pattern a été créé
          </button>
          {showSuggestion && (
            <div className="pl-5 space-y-1.5 text-[11px] text-slate-400">
              {sgOut.macro_fit && <p className="italic">{sgOut.macro_fit}</p>}
              {sgOut.description && <p className="text-slate-500">{sgOut.description}</p>}
              {sg.macro_dominant && (
                <div className="flex gap-3 mt-1">
                  <span>Créé sous : <ScenarioBadge dominant={sg.macro_dominant} /></span>
                  {sg.geo_score != null && <span>Géo : <span className="font-mono text-slate-300">{sg.geo_score}/100</span></span>}
                </div>
              )}
            </div>
          )}
        </div>
      )}

      {/* GPT-4o analysis */}
      <div className="border-t border-slate-800 pt-3">
        {!analysis ? (
          <button
            onClick={() => analyze(tradeId)}
            disabled={analyzing}
            className="flex items-center gap-2 px-3 py-1.5 rounded bg-blue-900/30 border border-blue-700/40 text-blue-300 hover:bg-blue-900/50 disabled:opacity-50 text-xs font-medium"
          >
            <Brain className={clsx('w-3.5 h-3.5', analyzing && 'animate-pulse')} />
            {analyzing ? 'Analyse GPT-4o en cours…' : 'Analyser avec GPT-4o'}
          </button>
        ) : (
          <div className="space-y-3">
            <div className="flex items-center gap-2 text-blue-400 font-semibold">
              <Brain className="w-3.5 h-3.5" />
              Analyse GPT-4o
            </div>
            {[
              { key: 'diagnostic', label: 'Diagnostic', color: 'text-slate-200' },
              { key: 'what_worked', label: 'Ce qui a marché', color: 'text-emerald-400' },
              { key: 'what_missed', label: 'Ce qui a manqué', color: 'text-red-400' },
              { key: 'regime_alignment', label: 'Alignement régime', color: 'text-yellow-400' },
              { key: 'contra_assessment', label: 'Contra-signals', color: 'text-orange-400' },
              { key: 'lesson', label: 'Leçon', color: 'text-blue-300' },
              { key: 'next_cycle', label: 'Prochain cycle', color: 'text-purple-400' },
            ].map(({ key, label, color }) =>
              analysis[key] ? (
                <div key={key}>
                  <span className={clsx('font-semibold', color)}>{label} : </span>
                  <span className="text-slate-400">{analysis[key]}</span>
                </div>
              ) : null
            )}
          </div>
        )}
      </div>
    </div>
  )
}

// ── Section 2 : Mark-to-Market des trades ─────────────────────────────────────

function TradeMtmSection({ days }: { days: number }) {
  const { data, isLoading, refetch, isFetching } = useTradeMtm(days)
  const [minScoreFilter, setMinScoreFilter] = useState(0)
  const [selectedTradeId, setSelectedTradeId] = useState<number | null>(null)
  const [closingTrade, setClosingTrade] = useState<any | null>(null)
  const allTrades: any[] = (data as any)?.trades ?? []
  const trades = allTrades.filter((t: any) => (t.latest_score ?? t.score_at_entry ?? 0) >= minScoreFilter)

  const withPnl = trades.filter((t: any) => t.pnl_pct != null)
  const avgPnl = withPnl.length
    ? withPnl.reduce((s: number, t: any) => s + t.pnl_pct, 0) / withPnl.length
    : null

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between gap-4">
        <div className="text-xs font-semibold text-slate-500 uppercase tracking-wide">
          {trades.length}/{allTrades.length} trades · {withPnl.length} pricés
          {avgPnl != null && (
            <span className={clsx('ml-2 font-bold', avgPnl >= 0 ? 'text-emerald-400' : 'text-red-400')}>
              · moy {avgPnl >= 0 ? '+' : ''}{avgPnl.toFixed(1)}%
            </span>
          )}
        </div>

        <div className="flex items-center gap-3">
          {/* Score filter */}
          <div className="flex items-center gap-2 text-xs text-slate-500">
            <span className="shrink-0">Score ≥</span>
            <input type="range" min="0" max="80" step="5"
              value={minScoreFilter}
              onChange={e => setMinScoreFilter(parseInt(e.target.value))}
              className="w-24 accent-blue-500" />
            <span className="w-5 font-mono text-blue-400">{minScoreFilter}</span>
          </div>
          <button onClick={() => refetch()} disabled={isFetching}
            className="text-slate-600 hover:text-slate-400 disabled:opacity-40">
            <RefreshCw className={clsx('w-3.5 h-3.5', isFetching && 'animate-spin')} />
          </button>
        </div>
      </div>

      {closingTrade && (
        <CloseTradeModal trade={closingTrade} onClose={() => setClosingTrade(null)} />
      )}

      {isLoading ? (
        <div className="card h-32 animate-pulse bg-dark-700" />
      ) : trades.length === 0 ? (
        <div className="card text-center py-10 text-slate-600 text-sm">
          <TrendingUp className="w-8 h-8 mx-auto mb-2 opacity-20" />
          {allTrades.length === 0
            ? 'Aucun trade logué — scorer des patterns pour commencer le suivi'
            : `Aucun trade avec score ≥ ${minScoreFilter}`}
        </div>
      ) : (
        <div className="overflow-x-auto rounded-lg border border-slate-700/40">
          <table className="w-full text-xs">
            <thead>
              <tr className="text-slate-600 border-b border-slate-700/40">
                <th className="text-left px-3 py-2 font-medium">Pattern</th>
                <th className="text-left px-3 py-2 font-medium">Profil</th>
                <th className="text-left px-3 py-2 font-medium">Stratégie</th>
                <th className="text-right px-3 py-2 font-medium">Strike</th>
                <th className="text-right px-3 py-2 font-medium">DTE</th>
                <th className="text-left px-3 py-2 font-medium">Ticker</th>
                <th className="text-right px-3 py-2 font-medium">Score</th>
                <th className="text-right px-3 py-2 font-medium">Trade Score</th>
                <th className="text-right px-3 py-2 font-medium">EV nette</th>
                <th className="text-right px-3 py-2 font-medium">Gain prévu</th>
                <th className="text-right px-3 py-2 font-medium">Date</th>
                <th className="text-right px-3 py-2 font-medium">Prix entrée</th>
                <th className="text-right px-3 py-2 font-medium">Prix actuel</th>
                <th className="text-right px-3 py-2 font-medium">Cible/Stop</th>
                <th className="text-right px-3 py-2 font-medium">Maturité</th>
                <th className="text-right px-3 py-2 font-medium">IV Rank</th>
                <th className="text-right px-3 py-2 font-medium">Kelly</th>
                <th className="text-right px-3 py-2 font-medium">P&L</th>
                <th className="px-3 py-2 font-medium w-8"></th>
                <th className="px-3 py-2 font-medium w-8"></th>
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-800/60">
              {trades.map((t: any) => {
                const evNet = t.ev_net ?? null
                const tradeScore = t.trade_score ?? null
                const isExpanded = selectedTradeId === t.id
                return (
                <Fragment key={t.id}>
                <tr
                  className={clsx('hover:bg-dark-700/30 transition-colors cursor-pointer', isExpanded && 'bg-dark-700/40 border-b-0')}
                  onClick={() => setSelectedTradeId(isExpanded ? null : t.id)}
                >
                  <td className="px-3 py-2 text-slate-300 max-w-[110px] truncate">{t.pattern_name || t.pattern_id}</td>
                  <td className="px-3 py-2">
                    {t.matched_profile ? (
                      <span className="text-[10px] font-semibold text-slate-400 bg-dark-700 px-1.5 py-0.5 rounded border border-slate-700/50">
                        {t.matched_profile}
                      </span>
                    ) : <span className="text-slate-700 text-[10px]">—</span>}
                  </td>
                  <td className="px-3 py-2">
                    <span className={clsx('badge text-[10px]',
                      t.direction === 'bearish' ? 'badge-red' : 'badge-green')}>
                      {t.direction === 'bearish' ? '🐻' : '🐂'} {t.strategy || '—'}
                    </span>
                  </td>
                  <td className="px-3 py-2 text-right font-mono text-[11px] text-slate-400">
                    {t.strike_guidance ?? '—'}
                  </td>
                  <td className="px-3 py-2 text-right font-mono text-[11px] text-slate-400">
                    {t.expiry_days_at_entry != null ? `${t.expiry_days_at_entry}j` : t.horizon_days != null ? `${t.horizon_days}j` : '—'}
                  </td>
                  <td className="px-3 py-2 font-mono">
                    <div className="flex items-center gap-1">
                      <span className={clsx(t.price_warning ? 'text-amber-300' : 'text-slate-300')}>{t.underlying}</span>
                      {t.price_warning && (
                        <span
                          className="text-[8px] font-bold bg-amber-900/40 border border-amber-600/40 text-amber-400 rounded px-1 py-0.5 leading-none shrink-0"
                          title={t.price_warning === 'no_price_data' ? 'Aucune donnée prix — monitoring impossible' : t.price_warning === 'no_entry_price' ? 'Prix d\'entrée manquant' : 'Prix live indisponible'}
                        >
                          ⚠ {t.price_warning === 'no_price_data' ? 'NO DATA' : t.price_warning === 'no_entry_price' ? 'NO ENTRY' : 'NO LIVE'}
                        </span>
                      )}
                    </div>
                  </td>
                  <td className="px-3 py-2 text-right">
                    <ScoreDelta entry={t.score_at_entry} latest={t.latest_score ?? t.score_at_entry} />
                  </td>
                  <td className="px-3 py-2 text-right">
                    {tradeScore != null ? (
                      <span className={clsx('font-bold font-mono text-xs',
                        tradeScore >= 55 ? 'text-emerald-400' : tradeScore >= 45 ? 'text-yellow-400' : 'text-slate-500')}>
                        {tradeScore.toFixed(1)}
                      </span>
                    ) : <span className="text-slate-700 text-xs">—</span>}
                  </td>
                  <td className="px-3 py-2 text-right">
                    {evNet != null ? (
                      <span className={clsx('font-mono text-[11px]',
                        evNet > 0.05 ? 'text-emerald-400' : evNet >= -0.01 ? 'text-yellow-400' : 'text-slate-600')}>
                        {evNet > 0 ? '+' : ''}{(evNet * 100).toFixed(0)}%
                      </span>
                    ) : <span className="text-slate-700 text-xs">—</span>}
                  </td>
                  <td className="px-3 py-2 text-right">
                    {t.expected_move_pct != null ? (
                      <span className="font-mono text-[11px] text-slate-500">{t.expected_move_pct.toFixed(0)}%</span>
                    ) : <span className="text-slate-700 text-xs">—</span>}
                  </td>
                  <td className="px-3 py-2 text-right text-slate-600 whitespace-nowrap text-[11px]">{t.entry_date}</td>
                  <td className={clsx('px-3 py-2 text-right font-mono text-[11px]', t.price_warning === 'no_entry_price' || t.price_warning === 'no_price_data' ? 'text-amber-600' : 'text-slate-400')}>
                    {t.entry_price != null ? t.entry_price.toFixed(2) : '—'}
                  </td>
                  <td className={clsx('px-3 py-2 text-right font-mono text-[11px]', t.price_warning === 'no_live_price' || t.price_warning === 'no_price_data' ? 'text-amber-600' : 'text-slate-300')}>
                    {t.current_price != null ? t.current_price.toFixed(2) : '—'}
                  </td>
                  <td className="px-3 py-2 text-right">
                    {t.pnl_pct != null ? (
                      <div className="flex flex-col items-end gap-1">
                        <div className="flex items-center gap-1.5">
                          {t.alert_type === 'target_reached' && (
                            <span className="text-[9px] font-bold text-emerald-400 bg-emerald-900/30 border border-emerald-700/30 rounded px-1">🎯</span>
                          )}
                          {t.alert_type === 'stop_loss' && (
                            <span className="text-[9px] font-bold text-red-400 bg-red-900/30 border border-red-700/30 rounded px-1">🛑</span>
                          )}
                        </div>
                        {/* progress bar: stop_loss (negative) to target (positive) */}
                        <div className="w-16 relative">
                          <div className="h-1.5 bg-slate-700 rounded-full overflow-hidden">
                            <div
                              className={clsx('h-full rounded-full',
                                t.pnl_pct >= 0 ? 'bg-emerald-500' : 'bg-red-500')}
                              style={{
                                width: `${Math.min(
                                  100,
                                  t.pnl_pct >= 0
                                    ? (t.pnl_pct / (t.target_pct || 30)) * 100
                                    : (Math.abs(t.pnl_pct) / Math.abs(t.stop_loss_pct || 50)) * 100
                                )}%`
                              }}
                            />
                          </div>
                          <div className="flex justify-between text-[8px] text-slate-700 mt-0.5 font-mono">
                            <span>{t.stop_loss_pct ?? -50}%</span>
                            <span>+{t.target_pct ?? 30}%</span>
                          </div>
                        </div>
                      </div>
                    ) : <span className="text-slate-700 text-[10px]">—</span>}
                  </td>
                  <td className="px-3 py-2 text-right">
                    {t.maturity ? (
                      <div className="flex flex-col items-end gap-0.5">
                        <span className={clsx('text-[10px] font-semibold',
                          t.maturity.status === 'trop_tot'   ? 'text-slate-500' :
                          t.maturity.status === 'debut'       ? 'text-yellow-400' :
                          t.maturity.status === 'mature'      ? 'text-emerald-400' :
                          'text-orange-400'
                        )}>
                          {t.maturity.emoji} {t.maturity.label}
                        </span>
                        <span className="text-[9px] text-slate-600 font-mono">
                          {t.days_held ?? 0}j / {t.horizon_days ?? 90}j ({t.maturity.ratio_pct}%)
                        </span>
                        <div className="w-16 h-1 bg-slate-700 rounded-full overflow-hidden">
                          <div
                            className={clsx('h-full rounded-full',
                              t.maturity.status === 'trop_tot'   ? 'bg-slate-600' :
                              t.maturity.status === 'debut'       ? 'bg-yellow-500' :
                              t.maturity.status === 'mature'      ? 'bg-emerald-500' :
                              'bg-orange-500'
                            )}
                            style={{ width: `${Math.min(t.maturity.ratio_pct, 100)}%` }}
                          />
                        </div>
                      </div>
                    ) : (
                      <span className="text-slate-700 text-[11px]">
                        {t.days_held != null ? `${t.days_held}j` : '—'}
                      </span>
                    )}
                  </td>
                  <td className="px-3 py-2 text-right">
                    <IvRankCell underlying={t.underlying} />
                  </td>
                  <td className="px-3 py-2 text-right">
                    <KellyCell patternId={t.pattern_id} />
                  </td>
                  <td className="px-3 py-2 text-right">
                    <PnlBadge pnl={t.pnl_pct} />
                  </td>
                  <td className="px-2 py-2" onClick={e => e.stopPropagation()}>
                    <button
                      onClick={() => setSelectedTradeId(isExpanded ? null : t.id)}
                      className={clsx(
                        'p-1 rounded transition-colors',
                        isExpanded
                          ? 'text-blue-400 bg-blue-900/30'
                          : 'text-slate-600 hover:text-blue-400 hover:bg-blue-900/20'
                      )}
                      title="Post-mortem IA"
                    >
                      {isExpanded ? <ChevronUp className="w-3.5 h-3.5" /> : <Search className="w-3.5 h-3.5" />}
                    </button>
                  </td>
                  <td className="px-2 py-2" onClick={e => e.stopPropagation()}>
                    <button
                      onClick={() => setClosingTrade(t)}
                      className={clsx(
                        'p-1 rounded transition-colors',
                        t.alert_type
                          ? 'text-amber-400 bg-amber-900/30 hover:bg-amber-900/50'
                          : 'text-slate-700 hover:text-amber-400 hover:bg-amber-900/20'
                      )}
                      title="Fermer le trade"
                    >
                      <Lock className="w-3.5 h-3.5" />
                    </button>
                  </td>
                </tr>
                {isExpanded && (
                  <tr className="bg-dark-900/60">
                    <td colSpan={20} className="px-4 py-3 border-b border-blue-700/20 space-y-3">
                      <IBKRTicket
                        strategy={t.strategy ?? ''}
                        underlying={t.underlying}
                        strikeGuidance={t.strike_guidance}
                        expiryDays={t.expiry_days_at_entry ?? t.horizon_days}
                        entryPrice={t.entry_price}
                        maxLoss={t.max_loss_eur}
                        targetGain={t.target_gain_eur}
                      />
                      <PostmortemPanel tradeId={t.id} onClose={() => setSelectedTradeId(null)} />
                    </td>
                  </tr>
                )}
                </Fragment>
                )
              })}
            </tbody>
          </table>
        </div>
      )}

    </div>
  )
}

// ── Section 3 : Historique du score géopolitique ──────────────────────────────

function GeoHistorySection({ days }: { days: number }) {
  const { data, isLoading, refetch, isFetching } = useGeoHistory(days)
  const history: any[] = (data as any)?.history ?? []

  const maxScore = Math.max(...history.map((h: any) => h.geo_score), 1)

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between">
        <div className="text-xs font-semibold text-slate-500 uppercase tracking-wide">
          {history.length} alertes · {days} derniers jours
        </div>
        <button onClick={() => refetch()} disabled={isFetching}
          className="text-slate-600 hover:text-slate-400 disabled:opacity-40">
          <RefreshCw className={clsx('w-3.5 h-3.5', isFetching && 'animate-spin')} />
        </button>
      </div>

      {isLoading ? (
        <div className="space-y-2">{[1,2].map(i => <div key={i} className="card h-12 animate-pulse bg-dark-700" />)}</div>
      ) : history.length === 0 ? (
        <div className="card text-center py-10 text-slate-600 text-sm">
          <AlertTriangle className="w-8 h-8 mx-auto mb-2 opacity-20" />
          Aucune alerte — scorer des patterns pour commencer le suivi
        </div>
      ) : (
        <div className="space-y-2">
          {history.map((entry: any) => {
            const score = entry.geo_score ?? 0
            const level = score >= 70 ? 'extreme' : score >= 50 ? 'high' : score >= 30 ? 'medium' : 'low'
            const barColor = { low: '#22c55e', medium: '#eab308', high: '#f97316', extreme: '#ef4444' }[level]
            const ts = entry.timestamp?.slice(0, 16).replace('T', ' ') ?? ''
            const patterns: any[] = entry.top_patterns ?? []

            return (
              <div key={entry.id} className="card">
                <div className="flex items-center gap-3 mb-2">
                  <div className="flex items-center gap-2 shrink-0">
                    <div className="w-10 h-10 rounded-lg flex items-center justify-center text-sm font-bold"
                      style={{ background: `${barColor}22`, color: barColor, border: `1px solid ${barColor}44` }}>
                      {score}
                    </div>
                    <div>
                      <div className="text-[10px] text-slate-600 uppercase">{level}</div>
                      <div className="text-[10px] text-slate-700">{ts}</div>
                    </div>
                  </div>
                  <div className="flex-1">
                    <div className="h-2 bg-dark-700 rounded-full overflow-hidden">
                      <div className="h-full rounded-full" style={{ width: `${(score / 100) * 100}%`, background: barColor }} />
                    </div>
                  </div>
                  <span className="text-[10px] text-slate-700 shrink-0">{entry.news_count} news</span>
                </div>
                {patterns.length > 0 && (
                  <div className="flex flex-wrap gap-1">
                    {patterns.slice(0, 5).map((p: any, i: number) => (
                      <span key={i} className="inline-flex items-center gap-1 text-[10px] bg-dark-700 text-slate-400 rounded px-1.5 py-0.5">
                        <span className="font-mono text-slate-500">{p.score}</span>
                        <span className="max-w-[120px] truncate">{p.name || p.pattern_id}</span>
                      </span>
                    ))}
                  </div>
                )}
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}

// ── Section 4 : Cycles d'intelligence ────────────────────────────────────────

function CyclesSection() {
  const { data: histData, isLoading, refetch, isFetching } = useCycleHistory(20)
  const { data: statusData } = useCycleStatus()
  const { mutate: triggerCycle, isPending: triggering } = useTriggerCycle()
  const runs: any[] = (histData as any)?.runs ?? []
  const cs = statusData as any

  // Auto-refetch history list when the running cycle finishes
  const wasRunning = useRef(false)
  useEffect(() => {
    if (cs?.running) { wasRunning.current = true }
    else if (wasRunning.current) { wasRunning.current = false; refetch() }
  }, [cs?.running])

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between">
        <div className="text-xs font-semibold text-slate-500 uppercase tracking-wide">
          {runs.length} cycles · {cs?.enabled ? `auto ${cs.interval_hours}h` : 'manuel uniquement'}
        </div>
        <div className="flex gap-2">
          <button
            onClick={() => triggerCycle(undefined, { onSuccess: () => setTimeout(() => refetch(), 3000) })}
            disabled={triggering}
            className="flex items-center gap-1 text-xs border border-blue-500/40 text-blue-400 hover:bg-blue-900/20 px-2.5 py-1 rounded disabled:opacity-40">
            <Zap className={clsx('w-3 h-3', triggering && 'animate-pulse')} />
            {triggering ? 'Lancement...' : 'Lancer un cycle'}
          </button>
          <button onClick={() => refetch()} disabled={isFetching}
            className="text-slate-600 hover:text-slate-400 disabled:opacity-40">
            <RefreshCw className={clsx('w-3.5 h-3.5', isFetching && 'animate-spin')} />
          </button>
        </div>
      </div>

      {isLoading ? (
        <div className="space-y-2">{[1,2,3].map(i => <div key={i} className="card h-20 animate-pulse bg-dark-700" />)}</div>
      ) : runs.length === 0 ? (
        <div className="card text-center py-10 text-slate-600 text-sm">
          <Zap className="w-8 h-8 mx-auto mb-2 opacity-20" />
          Aucun cycle — activer l'auto-cycle dans Configuration ou lancer manuellement
        </div>
      ) : (
        <div className="space-y-3">
          {runs.map((run: any) => {
            const commentary = run.commentary_parsed
            const ok = run.status === 'completed'
            const ts = run.started_at?.slice(0, 16).replace('T', ' ') ?? ''
            const duration = run.completed_at
              ? Math.round((new Date(run.completed_at).getTime() - new Date(run.started_at).getTime()) / 1000)
              : null

            return (
              <div key={run.id} className={clsx('card', ok ? 'border-slate-700/40' : 'border-red-800/30')}>
                <div className="flex items-start gap-3 mb-2">
                  {ok
                    ? <CheckCircle className="w-4 h-4 text-emerald-400 shrink-0 mt-0.5" />
                    : <XCircle className="w-4 h-4 text-red-400 shrink-0 mt-0.5" />}
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2 flex-wrap">
                      <span className="text-xs text-slate-300 font-semibold">{ts} UTC</span>
                      <span className={clsx('badge text-[10px]', run.trigger === 'manual' ? 'badge-blue' : 'badge-purple')}>
                        {run.trigger === 'manual' ? 'Manuel' : `Auto ${cs?.interval_hours ?? ''}h`}
                      </span>
                      {run.dominant_regime && <ScenarioBadge dominant={run.dominant_regime} />}
                      {duration != null && <span className="text-[10px] text-slate-600">{duration}s</span>}
                    </div>
                    <div className="flex gap-3 mt-1 text-[11px] text-slate-500 flex-wrap">
                      <span>💡 {run.patterns_suggested} suggérés</span>
                      <span>✚ {run.patterns_added} ajoutés</span>
                      <span>🎯 {run.patterns_scored} scorés</span>
                      {run.geo_score != null && <span>🌐 Géo {run.geo_score}/100</span>}
                    </div>
                  </div>
                </div>

                {commentary && (
                  <div className="bg-blue-900/10 border border-blue-700/20 rounded p-3 space-y-2">
                    <div className="flex items-center gap-1.5 text-[10px] text-blue-400 font-semibold uppercase tracking-wide">
                      <Brain className="w-3 h-3" /> Commentaire IA
                    </div>
                    <p className="text-xs text-slate-300 leading-relaxed">{commentary.commentary}</p>
                    {commentary.key_risk && (
                      <div className="flex items-start gap-1.5 text-[11px] text-orange-400/80 bg-orange-900/10 border border-orange-700/20 rounded px-2 py-1">
                        <span className="shrink-0">⚠</span> {commentary.key_risk}
                      </div>
                    )}
                    {commentary.top_pattern && (
                      <div className="text-[11px] text-emerald-400/80">
                        🎯 Pattern clé : <span className="font-semibold">{commentary.top_pattern}</span>
                      </div>
                    )}
                    {commentary.lessons_from_report ? (
                      <div className="flex items-center gap-1.5 text-[10px] text-purple-400/80 bg-purple-900/10 border border-purple-700/20 rounded px-2 py-1">
                        <BookOpen className="w-3 h-3 shrink-0" />
                        Leçons du rapport du {commentary.lessons_from_report} intégrées dans ce cycle
                        {commentary.lessons_headline && (
                          <span className="text-slate-600 ml-1">· {commentary.lessons_headline}</span>
                        )}
                      </div>
                    ) : (
                      <div className="flex items-center gap-1.5 text-[10px] text-slate-700 italic">
                        <BookOpen className="w-3 h-3 shrink-0" />
                        Aucun rapport de performance disponible — générer un rapport dans "Rapport IA"
                      </div>
                    )}
                  </div>
                )}

                {!commentary && ok && (
                  <div className="text-[11px] text-slate-700 italic">Aucun commentaire IA généré pour ce cycle</div>
                )}
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}

// ── Page principale ────────────────────────────────────────────────────────────

const ASSET_CLASS_COLORS: Record<string, string> = {
  energy: '#f97316', metals: '#eab308', agriculture: '#84cc16',
  equities: '#22c55e', indices: '#3b82f6', forex: '#8b5cf6', rates: '#06b6d4',
  unknown: '#64748b',
}

function SimPortfolioRiskPanel() {
  const { data, isLoading, refetch } = useSimPortfolioRisk()
  const risk = data as any

  if (isLoading) {
    return (
      <div className="card animate-pulse">
        <div className="h-5 bg-dark-700 rounded w-48 mb-4" />
        <div className="space-y-2">{[1, 2, 3].map(i => <div key={i} className="h-8 bg-dark-700 rounded" />)}</div>
      </div>
    )
  }

  if (!risk || risk.open_count === 0) {
    return (
      <div className="card text-center py-8 text-slate-500">
        <PieChart className="w-8 h-8 mx-auto mb-2 opacity-20" />
        <div className="text-sm">Aucune position ouverte dans le portefeuille simulé</div>
        <div className="text-xs mt-1">Les trades logués apparaîtront ici après le prochain cycle</div>
      </div>
    )
  }

  const concentration: Record<string, any> = risk.concentration ?? {}
  const alerts: any[] = risk.alerts ?? []
  const conflicts: any[] = risk.conflicts ?? []
  const aiMonitor: any = risk.ai_monitor
  const aiTs: string = risk.ai_monitor_ts

  const dangers = alerts.filter((a: any) => a.level === 'danger')
  const warnings = alerts.filter((a: any) => a.level === 'warning')

  return (
    <div className="space-y-3">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <PieChart className="w-4 h-4 text-blue-400" />
          <span className="text-sm font-semibold text-white">Portefeuille Simulé — Analyse de Risque</span>
          <span className="text-xs text-slate-500">{risk.open_count} positions ouvertes</span>
          {dangers.length > 0 && (
            <span className="inline-flex items-center gap-1 text-[10px] font-bold bg-red-900/30 border border-red-600/40 text-red-400 rounded px-1.5 py-0.5">
              <ShieldAlert className="w-3 h-3" /> {dangers.length} CONFLIT{dangers.length > 1 ? 'S' : ''}
            </span>
          )}
        </div>
        <button onClick={() => refetch()} className="text-slate-600 hover:text-slate-400 transition-colors">
          <RefreshCw className="w-3.5 h-3.5" />
        </button>
      </div>

      {/* Asset class concentration bars */}
      <div className="card">
        <div className="text-xs text-slate-500 mb-3 font-semibold uppercase tracking-wide">Répartition par classe d'actif</div>
        <div className="space-y-2">
          {Object.entries(concentration)
            .sort(([, a]: any, [, b]: any) => b.pct - a.pct)
            .map(([ac, data]: [string, any]) => {
              const color = ASSET_CLASS_COLORS[ac] ?? ASSET_CLASS_COLORS.unknown
              const exposure = risk.direction_exposure?.[ac] ?? {}
              return (
                <div key={ac}>
                  <div className="flex items-center justify-between mb-1">
                    <div className="flex items-center gap-2">
                      <span className="text-xs font-semibold w-20 capitalize" style={{ color }}>{ac}</span>
                      <span className="text-[10px] text-slate-500">{data.tickers?.slice(0, 3).join(', ')}{data.tickers?.length > 3 ? '…' : ''}</span>
                    </div>
                    <div className="flex items-center gap-2 text-[10px]">
                      {exposure.bullish > 0 && (
                        <span className="text-emerald-400 flex items-center gap-0.5">
                          <TrendingUp className="w-2.5 h-2.5" /> {exposure.bullish}
                        </span>
                      )}
                      {exposure.bearish > 0 && (
                        <span className="text-red-400 flex items-center gap-0.5">
                          <TrendingDown className="w-2.5 h-2.5" /> {exposure.bearish}
                        </span>
                      )}
                      <span className="text-slate-400 font-mono font-bold">{data.pct}%</span>
                      <span className="text-slate-600">({data.count})</span>
                    </div>
                  </div>
                  <div className="h-1.5 bg-dark-700 rounded-full overflow-hidden">
                    <div
                      className="h-full rounded-full transition-all"
                      style={{ width: `${data.pct}%`, background: `${color}cc` }}
                    />
                  </div>
                </div>
              )
            })}
        </div>
      </div>

      {/* Alerts */}
      {alerts.length > 0 && (
        <div className="space-y-2">
          {/* Conflicts */}
          {conflicts.map((c: any, i: number) => (
            <div key={i} className="card border-red-700/40 bg-red-900/10">
              <div className="flex items-start gap-2">
                <ShieldAlert className="w-4 h-4 text-red-400 shrink-0 mt-0.5" />
                <div className="flex-1 min-w-0">
                  <div className="text-xs font-semibold text-red-300 mb-1">
                    Conflit directionnel — {c.underlying}
                  </div>
                  <div className="space-y-0.5">
                    {c.trades.map((t: any) => (
                      <div key={t.id} className="flex items-center gap-2 text-[11px]">
                        <span className={clsx('font-bold font-mono',
                          t.direction === 'bullish' ? 'text-emerald-400' : 'text-red-400')}>
                          {t.direction === 'bullish' ? '▲' : '▼'} #{t.id}
                        </span>
                        <span className="text-slate-400">{t.strategy}</span>
                        <span className="text-slate-600">{t.entry_date}</span>
                        {t.pattern_name && (
                          <span className="text-slate-600 truncate max-w-[180px]">{t.pattern_name}</span>
                        )}
                      </div>
                    ))}
                  </div>
                </div>
              </div>
            </div>
          ))}

          {/* Concentration & overweight warnings */}
          {warnings.length > 0 && (
            <div className="card border-amber-700/30 bg-amber-900/10">
              <div className="text-xs font-semibold text-amber-300 mb-1.5 flex items-center gap-1">
                <AlertTriangle className="w-3.5 h-3.5" /> Alertes de concentration
              </div>
              <div className="space-y-1">
                {warnings.map((a: any, i: number) => (
                  <div key={i} className="text-[11px] text-amber-200/80 flex items-start gap-1.5">
                    <span className="text-amber-500 shrink-0">•</span>
                    {a.message}
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>
      )}

      {/* AI Monitor recommendations */}
      {aiMonitor && (
        <div className="card border-blue-700/30 bg-blue-900/10">
          <div className="flex items-center justify-between mb-2">
            <div className="text-xs font-semibold text-blue-300 flex items-center gap-1.5">
              <Brain className="w-3.5 h-3.5" /> Recommandations IA — Moniteur de portefeuille
            </div>
            {aiTs && (
              <span className="text-[10px] text-slate-600">{aiTs.slice(0, 16).replace('T', ' ')}</span>
            )}
          </div>
          {aiMonitor.assessment && (
            <p className="text-xs text-slate-300 mb-2">{aiMonitor.assessment}</p>
          )}
          {aiMonitor.actions?.length > 0 && (
            <div className="space-y-1 mb-2">
              {aiMonitor.actions.map((action: any, i: number) => (
                <div key={i} className={clsx(
                  'flex items-start gap-2 text-[11px] rounded px-2 py-1',
                  action.priority === 'high'
                    ? 'bg-red-900/20 border border-red-700/20 text-red-300'
                    : 'bg-slate-800/40 border border-slate-700/20 text-slate-300'
                )}>
                  <span className="shrink-0 font-bold">
                    {action.type === 'close_trade' ? '🔒' : action.type === 'rebalance' ? '⚖️' : '👁'}
                  </span>
                  <div>
                    {action.underlying && <span className="font-mono font-bold mr-1">{action.underlying}</span>}
                    {action.trade_id && <span className="text-slate-500 mr-1">#{action.trade_id}</span>}
                    {action.reason}
                  </div>
                </div>
              ))}
            </div>
          )}
          {aiMonitor.rebalance_suggestion && (
            <div className="text-[11px] text-blue-300/70 border-t border-blue-700/20 pt-2 mt-1">
              ⚖️ {aiMonitor.rebalance_suggestion}
            </div>
          )}
        </div>
      )}

      {alerts.length === 0 && (
        <div className="card border-emerald-700/30 bg-emerald-900/10 text-center py-3">
          <CheckCircle className="w-5 h-5 text-emerald-400 mx-auto mb-1" />
          <div className="text-xs text-emerald-300">Portefeuille équilibré — aucun conflit ni sur-concentration détectés</div>
        </div>
      )}
    </div>
  )
}

const TABS = [
  { key: 'cycles', label: 'Cycles IA', icon: Zap },
  { key: 'macro', label: 'Régimes Macro', icon: Activity },
  { key: 'ideas', label: 'Idées de trade', icon: Target },
  { key: 'mtm', label: 'Ouverts', icon: TrendingUp },
  { key: 'closed', label: 'Fermés', icon: Lock },
  { key: 'geo', label: 'Alertes Géo', icon: AlertTriangle },
  { key: 'skipped', label: 'Non loggés', icon: XCircle },
] as const

function SkippedTradesSection({ days }: { days: number }) {
  const { data, isLoading } = useSkippedTrades(days)
  const trades: any[] = (data as any)?.trades ?? []

  const ASSET_CLASS_COLORS: Record<string, string> = {
    energy: 'bg-orange-900/30 text-orange-300 border-orange-700/30',
    metals: 'bg-yellow-900/30 text-yellow-300 border-yellow-700/30',
    agriculture: 'bg-green-900/30 text-green-300 border-green-700/30',
    indices: 'bg-blue-900/30 text-blue-300 border-blue-700/30',
    forex: 'bg-purple-900/30 text-purple-300 border-purple-700/30',
    rates: 'bg-slate-800/60 text-slate-300 border-slate-600/30',
    equities: 'bg-cyan-900/30 text-cyan-300 border-cyan-700/30',
  }

  if (isLoading) return <div className="card animate-pulse h-24" />

  if (trades.length === 0) {
    return (
      <div className="card text-center py-8 text-slate-500 text-sm">
        <XCircle className="w-6 h-6 mx-auto mb-2 text-slate-600" />
        Aucune suggestion non loggée sur {days}j — tous les trades scorés passent au moins un profil de risque.
      </div>
    )
  }

  const byReason = trades.reduce((acc: Record<string, number>, t: any) => {
    acc[t.skip_reason] = (acc[t.skip_reason] ?? 0) + 1
    return acc
  }, {})

  return (
    <div className="space-y-4">
      <div className="card">
        <div className="section-title flex items-center gap-1 mb-3">
          <XCircle className="w-3 h-3 text-amber-400" />
          Trades suggérés non loggés — {trades.length} sur {days}j
          <span className="ml-2 text-slate-600 font-normal text-xs">
            (score ou gain insuffisant pour tout profil actif)
          </span>
        </div>
        <div className="flex gap-3 mb-4 flex-wrap">
          {Object.entries(byReason).map(([reason, count]) => (
            <div key={reason} className="badge badge-yellow text-[10px]">
              {reason}: {count}
            </div>
          ))}
        </div>
        <div className="overflow-x-auto rounded-lg border border-slate-700/40">
          <table className="w-full text-xs">
            <thead>
              <tr className="border-b border-slate-700/60 text-slate-600 text-[10px] uppercase tracking-wide">
                <th className="pl-3 py-2 text-left">Pattern</th>
                <th className="px-2 py-2 text-left">Ticker</th>
                <th className="px-2 py-2 text-left">Stratégie</th>
                <th className="px-2 py-2 text-right">Score</th>
                <th className="px-2 py-2 text-right">Gain attendu</th>
                <th className="px-2 py-2 text-left">Classe</th>
                <th className="pr-3 py-2 text-left">Raison du skip</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-800/40">
              {trades.map((t: any) => (
                <tr key={t.id} className="hover:bg-dark-700/30">
                  <td className="pl-3 py-2 text-slate-300 max-w-[140px] truncate">{t.pattern_name || '—'}</td>
                  <td className="px-2 py-2 font-mono text-slate-400">{t.underlying}</td>
                  <td className="px-2 py-2 text-slate-400">{t.strategy || '—'}</td>
                  <td className={clsx('px-2 py-2 text-right font-bold font-mono',
                    t.score >= 50 ? 'text-emerald-400' : t.score >= 25 ? 'text-yellow-400' : 'text-slate-600')}>
                    {t.score ?? '—'}
                  </td>
                  <td className="px-2 py-2 text-right text-slate-400">
                    {t.expected_move_pct != null ? `${t.expected_move_pct.toFixed(0)}%` : '—'}
                  </td>
                  <td className="px-2 py-2">
                    {t.asset_class ? (
                      <span className={clsx('badge text-[10px] border', ASSET_CLASS_COLORS[t.asset_class] ?? 'badge-blue')}>
                        {t.asset_class}
                      </span>
                    ) : <span className="text-slate-600">—</span>}
                  </td>
                  <td className="pr-3 py-2 text-slate-600 max-w-[200px] truncate" title={t.skip_detail}>
                    {t.skip_detail || t.skip_reason}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  )
}

export default function JournalDeBord() {
  const [tab, setTab] = useState<'cycles' | 'macro' | 'ideas' | 'mtm' | 'closed' | 'geo' | 'skipped'>('cycles')
  const [days, setDays] = useState(15)
  const [confirmReset, setConfirmReset] = useState(false)
  const [resetting, setResetting] = useState(false)
  const [resetMsg, setResetMsg] = useState('')
  const { data: summary, refetch: refetchSummary } = useJournalSummary()
  const { data: riskData } = useSimPortfolioRisk()
  const riskAlertCount = (riskData as any)?.alerts?.filter((a: any) => a.level === 'danger').length ?? 0
  const qc = useQueryClient()

  const s = summary as any

  const handleReset = async () => {
    if (!confirmReset) {
      setConfirmReset(true)
      return
    }
    setResetting(true)
    try {
      await api.delete('/journal/reset')
      setResetMsg('Journal réinitialisé')
      setConfirmReset(false)
      // Invalidate all journal queries
      await qc.invalidateQueries({ queryKey: ['journal-summary'] })
      await qc.invalidateQueries({ queryKey: ['macro-history'] })
      await qc.invalidateQueries({ queryKey: ['geo-history'] })
      await qc.invalidateQueries({ queryKey: ['trade-mtm'] })
      await qc.invalidateQueries({ queryKey: ['cycle-history'] })
      setTimeout(() => setResetMsg(''), 3000)
    } catch {
      setResetMsg('Erreur lors du reset')
      setTimeout(() => setResetMsg(''), 3000)
    } finally {
      setResetting(false)
    }
  }

  return (
    <div className="p-6 space-y-5">
      {/* Header */}
      <div className="flex items-start justify-between">
        <div>
          <h1 className="text-xl font-bold text-white flex items-center gap-2">
            <BookOpen className="w-5 h-5 text-blue-400" /> Journal de Bord
          </h1>
          <p className="text-xs text-slate-500 mt-0.5">
            Historique des régimes macro · Mark-to-market des trades · Évolution du risque géopolitique
          </p>
        </div>

        <div className="flex items-center gap-3">
          {/* Reset button */}
          <div className="flex items-center gap-2">
            {resetMsg && (
              <span className={clsx('text-xs', resetMsg.includes('Erreur') ? 'text-red-400' : 'text-emerald-400')}>
                {resetMsg}
              </span>
            )}
            {confirmReset && !resetting && (
              <span className="text-xs text-amber-400">Confirmer ?</span>
            )}
            <button
              onClick={confirmReset ? handleReset : () => setConfirmReset(true)}
              disabled={resetting}
              onBlur={() => setTimeout(() => setConfirmReset(false), 300)}
              className={clsx(
                'flex items-center gap-1.5 px-3 py-1.5 rounded text-xs font-semibold border transition-all disabled:opacity-40',
                confirmReset
                  ? 'bg-red-900/30 border-red-600/50 text-red-400 hover:bg-red-900/50'
                  : 'border-slate-700/40 text-slate-600 hover:text-slate-400 hover:border-slate-600'
              )}>
              <Trash2 className="w-3.5 h-3.5" />
              {resetting ? 'Réinit...' : confirmReset ? 'Effacer tout' : 'Reset journal'}
            </button>
          </div>

          {/* Period selector */}
          <div className="flex gap-1 bg-dark-700 p-1 rounded text-xs">
            {[15, 30, 60, 90].map(d => (
              <button key={d} onClick={() => setDays(d)}
                className={clsx('px-2.5 py-1 rounded transition-colors', {
                  'bg-blue-600 text-white': days === d,
                  'text-slate-400 hover:text-slate-200': days !== d,
                })}>
                {d}j
              </button>
            ))}
          </div>
        </div>
      </div>

      {/* Summary cards */}
      {s && (
        <div className="grid grid-cols-4 gap-3">
          <div className="card text-center">
            <div className="text-2xl font-bold text-white">{s.macro_snapshots ?? 0}</div>
            <div className="text-xs text-slate-600 mt-0.5">snapshots macro</div>
            {s.current_dominant && (
              <div className="mt-1"><ScenarioBadge dominant={s.current_dominant} /></div>
            )}
          </div>
          <div className="card text-center">
            <div className="text-2xl font-bold text-white">{s.regime_transitions?.length ?? 0}</div>
            <div className="text-xs text-slate-600 mt-0.5">transitions de régime</div>
            {s.regime_transitions?.length > 0 && (
              <div className="text-[10px] text-amber-400 mt-1">
                ↕ {s.regime_transitions[0].from} → {s.regime_transitions[0].to}
              </div>
            )}
          </div>
          <div className="card text-center">
            <div className={clsx('text-2xl font-bold',
              (s.avg_geo_score ?? 0) >= 70 ? 'text-red-400' : (s.avg_geo_score ?? 0) >= 40 ? 'text-orange-400' : 'text-emerald-400')}>
              {s.avg_geo_score != null ? s.avg_geo_score.toFixed(0) : '—'}
            </div>
            <div className="text-xs text-slate-600 mt-0.5">score géo moyen</div>
            {s.max_geo_score != null && (
              <div className="text-[10px] text-slate-600 mt-1">max {s.max_geo_score}</div>
            )}
          </div>
          <div className="card text-center">
            <div className="text-2xl font-bold text-white">{s.trade_entries_logged ?? 0}</div>
            <div className="text-xs text-slate-600 mt-0.5">trades logués</div>
          </div>
          {riskAlertCount > 0 && (
            <div className="card text-center border-red-700/40 bg-red-900/10 col-span-full">
              <div className="flex items-center justify-center gap-2">
                <ShieldAlert className="w-4 h-4 text-red-400" />
                <span className="text-sm font-semibold text-red-300">
                  {riskAlertCount} conflit{riskAlertCount > 1 ? 's' : ''} directionnel{riskAlertCount > 1 ? 's' : ''} détecté{riskAlertCount > 1 ? 's' : ''}
                </span>
                <span className="text-xs text-slate-500">— voir Risk Dashboard → Simulé</span>
              </div>
            </div>
          )}
        </div>
      )}

      {/* Tabs */}
      <div className="flex gap-1 bg-dark-700 p-1 rounded w-fit">
        {TABS.map(({ key, label, icon: Icon }) => (
          <button key={key} onClick={() => setTab(key as any)}
            className={clsx('flex items-center gap-1.5 px-3 py-1.5 rounded text-sm transition-colors', {
              'bg-blue-600 text-white': tab === key,
              'text-slate-400 hover:text-slate-200': tab !== key,
            })}>
            <Icon className="w-3.5 h-3.5" />
            {label}
          </button>
        ))}
      </div>

      {/* Content */}
      {tab === 'cycles' && <CyclesSection />}
      {tab === 'macro' && <MacroHistorySection days={days} />}
      {tab === 'ideas' && <TradeIdeasTab />}
      {tab === 'mtm' && <TradeMtmSection days={days} />}
      {tab === 'closed' && <ClosedTradesSection days={days} />}
      {tab === 'geo' && <GeoHistorySection days={days} />}
      {tab === 'skipped' && <SkippedTradesSection days={days} />}
    </div>
  )
}
