import { useState, useEffect } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { useSources, useUpdateSources, useUpdateApiKeys, useConfig, useAiStatus, useAnalysisConfig, useSaveAnalysisConfig, useCycleStatus, useUpdateCycleConfig, useTriggerCycle, useRiskProfiles, useUpsertProfile, useDeleteProfile, useExitDefaults, useSaveExitDefaults } from '../hooks/useApi'
import { Settings, Key, Globe, CheckCircle, XCircle, AlertCircle, Save, Eye, EyeOff, Brain, SlidersHorizontal, RefreshCw, Zap, Plus, Trash2, Pencil, X, Lock, Gauge, DollarSign } from 'lucide-react'
import clsx from 'clsx'

const API = ''

const SOURCE_CATEGORIES = {
  'Flux RSS actifs': ['reuters_world', 'reuters_business', 'reuters_energy', 'ap_top', 'aljazeera', 'ft', 'bloomberg'],
  'Données économiques': ['newsapi', 'gdelt', 'eia', 'fred', 'usda'],
  'Santé & Catastrophes': ['who', 'emdat'],
  'Réseaux sociaux': ['twitter_trump'],
}

const SOURCE_DOCS: Record<string, { description: string; link?: string; cost: string }> = {
  reuters_world: { description: 'Actualités mondiales Reuters', cost: 'Gratuit' },
  reuters_business: { description: 'Business et marchés Reuters', cost: 'Gratuit' },
  reuters_energy: { description: 'Énergie et commodités Reuters', cost: 'Gratuit' },
  ap_top: { description: 'Associated Press — Top Stories', cost: 'Gratuit' },
  aljazeera: { description: 'Al Jazeera — couverture Moyen-Orient/Monde', cost: 'Gratuit' },
  ft: { description: 'Financial Times — finance internationale', cost: 'Gratuit' },
  bloomberg: { description: 'Bloomberg Markets RSS', cost: 'Gratuit' },
  newsapi: { description: '100 req/jour gratuit — actualités mondiales multi-sources', link: 'https://newsapi.org', cost: '100 req/j gratuit' },
  gdelt: { description: 'Base de données géopolitique mondiale — 300K events/jour', link: 'https://gdeltproject.org', cost: 'Gratuit total' },
  eia: { description: 'US Energy Information Administration — données pétrole/gaz hebdo', link: 'https://www.eia.gov/opendata', cost: 'Gratuit avec clé' },
  fred: { description: 'Federal Reserve St. Louis — macro US (PIB, inflation, emploi)', link: 'https://fred.stlouisfed.org/docs/api/fred/', cost: 'Gratuit avec clé' },
  usda: { description: 'USDA — rapports agricoles officiels US', cost: 'Gratuit' },
  who: { description: 'OMS — alertes sanitaires mondiales RSS', cost: 'Gratuit' },
  emdat: { description: 'EM-DAT — base de données catastrophes naturelles', link: 'https://www.emdat.be', cost: 'Inscription gratuite' },
  twitter_trump: { description: 'Flux X/Twitter Trump — discours, annonces tarifs', cost: 'API payante ($100/mois+)' },
}

// ── Risk Profiles Component ───────────────────────────────────────────────────

const PROFILE_COLORS = [
  { value: '#22c55e', label: 'Vert' },
  { value: '#3b82f6', label: 'Bleu' },
  { value: '#f97316', label: 'Orange' },
  { value: '#ef4444', label: 'Rouge' },
  { value: '#8b5cf6', label: 'Violet' },
  { value: '#eab308', label: 'Jaune' },
]

function NextRunCountdown({ nextRunAt }: { nextRunAt: string }) {
  const [remaining, setRemaining] = useState('')

  useEffect(() => {
    function update() {
      const diff = new Date(nextRunAt + 'Z').getTime() - Date.now()
      if (diff <= 0) { setRemaining('Imminent…'); return }
      const h = Math.floor(diff / 3_600_000)
      const m = Math.floor((diff % 3_600_000) / 60_000)
      const s = Math.floor((diff % 60_000) / 1_000)
      setRemaining(h > 0 ? `${h}h ${m.toString().padStart(2,'0')}min` : `${m}min ${s.toString().padStart(2,'0')}s`)
    }
    update()
    const id = setInterval(update, 1_000)
    return () => clearInterval(id)
  }, [nextRunAt])

  const absTime = new Date(nextRunAt + 'Z').toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })

  return (
    <div className="flex items-center gap-2 text-emerald-400/80">
      <span className="inline-block w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse" />
      <span>Prochain cycle dans <span className="font-mono font-semibold text-emerald-300">{remaining}</span></span>
      <span className="text-slate-600">({absTime} heure locale)</span>
    </div>
  )
}

function evNetLabel(evNet: number): { text: string; cls: string } {
  if (evNet > 0.05) return { text: `EV nette +${(evNet * 100).toFixed(0)}%`, cls: 'text-emerald-400' }
  if (evNet >= -0.01) return { text: 'EV nette ≈ 0', cls: 'text-yellow-400' }
  return { text: `EV nette ${(evNet * 100).toFixed(0)}%`, cls: 'text-slate-600' }
}

function ProfileRow({
  profile,
  onSave,
  onDelete,
}: {
  profile: any
  onSave: (p: any) => void
  onDelete: (id: number) => void
}) {
  const [editing, setEditing] = useState(false)
  const [name, setName] = useState(profile.name)
  const [score, setScore] = useState(profile.min_score)
  const [gain, setGain] = useState(profile.min_gain_pct)
  const [color, setColor] = useState(profile.color ?? '#3b82f6')
  const [enabled, setEnabled] = useState(profile.enabled !== 0)

  // Live EV computation
  const p = score / 100
  const G = gain / 100
  const denom = p * G + (1 - p)
  const ev_net = p * G - (1 - p)
  const trade_score = denom > 0 ? (p * G / denom * 100) : 0
  const { text: evText, cls: evCls } = evNetLabel(ev_net)

  const save = () => {
    onSave({ id: profile.id, name, min_score: score, min_gain_pct: gain, color, enabled, sort_order: profile.sort_order ?? 0 })
    setEditing(false)
  }

  if (!editing) {
    const { text: fev, cls: fevc } = evNetLabel(profile.ev_net_at_frontier ?? 0)
    return (
      <div className="flex items-center gap-3 py-2 px-3 rounded hover:bg-dark-700/40 group">
        <div className="w-2.5 h-2.5 rounded-full shrink-0" style={{ background: profile.color ?? '#3b82f6' }} />
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 flex-wrap">
            <span className={clsx('text-sm font-semibold', enabled ? 'text-slate-200' : 'text-slate-600')}>{profile.name}</span>
            {!enabled && <span className="text-[10px] text-slate-700 italic">désactivé</span>}
            <span className="text-xs text-slate-500">Score ≥ <span className="text-slate-300 font-mono">{profile.min_score}</span></span>
            <span className="text-xs text-slate-500">Gain ≥ <span className="text-slate-300 font-mono">{profile.min_gain_pct}%</span></span>
            <span className={clsx('text-[11px] font-mono', fevc)}>{fev}</span>
            <span className="text-[11px] text-slate-600">Trade Score ≥ {(profile.trade_score_at_frontier ?? 0).toFixed(0)}</span>
          </div>
        </div>
        <div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0">
          <button onClick={() => setEditing(true)}
            className="text-slate-600 hover:text-slate-300 p-1 rounded">
            <Pencil className="w-3 h-3" />
          </button>
          <button onClick={() => onDelete(profile.id)}
            className="text-slate-600 hover:text-red-400 p-1 rounded">
            <Trash2 className="w-3 h-3" />
          </button>
        </div>
      </div>
    )
  }

  return (
    <div className="bg-dark-700/60 rounded-lg p-3 border border-slate-600/40 space-y-3">
      <div className="grid grid-cols-3 gap-3">
        <div>
          <label className="text-[10px] text-slate-500 mb-1 block">Nom du profil</label>
          <input value={name} onChange={e => setName(e.target.value)}
            className="w-full bg-dark-800 border border-slate-700 rounded px-2 py-1 text-sm text-white" />
        </div>
        <div>
          <label className="text-[10px] text-slate-500 mb-1 block">Score min = <span className="text-blue-400 font-mono">{score}</span>/100</label>
          <input type="range" min="0" max="90" step="5" value={score}
            onChange={e => setScore(parseInt(e.target.value))}
            className="w-full accent-blue-500" />
        </div>
        <div>
          <label className="text-[10px] text-slate-500 mb-1 block">Gain min = <span className="text-blue-400 font-mono">{gain}%</span></label>
          <input type="range" min="10" max="2000" step="10" value={gain}
            onChange={e => setGain(parseFloat(e.target.value))}
            className="w-full accent-blue-500" />
        </div>
      </div>

      {/* Live EV preview */}
      <div className="bg-dark-800 rounded px-3 py-2 text-xs flex items-center gap-4 flex-wrap">
        <span className="text-slate-500">À la frontière (score={score}, gain={gain}%)</span>
        <span className={clsx('font-mono font-bold', evCls)}>{evText}</span>
        <span className="text-slate-600">Trade Score = <span className="text-slate-400">{trade_score.toFixed(1)}</span>/100</span>
        <span className="text-slate-600">
          Score min EV=0 : <span className="text-slate-400 font-mono">{Math.ceil(100 / (G + 1))}</span>/100
        </span>
      </div>

      <div className="flex items-center gap-3">
        <div className="flex gap-1.5">
          {PROFILE_COLORS.map(c => (
            <button key={c.value} onClick={() => setColor(c.value)}
              title={c.label}
              className={clsx('w-5 h-5 rounded-full border-2 transition-all',
                color === c.value ? 'border-white scale-110' : 'border-transparent opacity-60 hover:opacity-100')}
              style={{ background: c.value }} />
          ))}
        </div>
        <button onClick={() => setEnabled(!enabled)}
          className={clsx('text-xs px-2 py-0.5 rounded border transition-all',
            enabled ? 'border-emerald-600/40 text-emerald-400 bg-emerald-900/20' : 'border-slate-700 text-slate-600')}>
          {enabled ? '✓ Activé' : '○ Désactivé'}
        </button>
        <div className="ml-auto flex gap-2">
          <button onClick={() => setEditing(false)}
            className="text-xs text-slate-500 hover:text-slate-300 px-2 py-1">Annuler</button>
          <button onClick={save}
            className="text-xs bg-blue-600 hover:bg-blue-500 text-white px-3 py-1 rounded font-semibold">
            Sauvegarder
          </button>
        </div>
      </div>
    </div>
  )
}

function RiskProfilesCard() {
  const { data: profileData, isLoading } = useRiskProfiles()
  const { mutate: upsert } = useUpsertProfile()
  const { mutate: del } = useDeleteProfile()
  const [showNew, setShowNew] = useState(false)
  const [newName, setNewName] = useState('')
  const [newScore, setNewScore] = useState(30)
  const [newGain, setNewGain] = useState(200)
  const [newColor, setNewColor] = useState('#3b82f6')

  const profiles: any[] = (profileData as any)?.profiles ?? []

  // Live preview for new profile
  const np = newScore / 100
  const nG = newGain / 100
  const nDenom = np * nG + (1 - np)
  const nEvNet = np * nG - (1 - np)
  const nTradeScore = nDenom > 0 ? (np * nG / nDenom * 100) : 0
  const nMinScore = Math.ceil(100 / (nG + 1))

  const saveNew = () => {
    if (!newName.trim()) return
    upsert({ name: newName, min_score: newScore, min_gain_pct: newGain, color: newColor, enabled: true, sort_order: profiles.length })
    setShowNew(false)
    setNewName('')
    setNewScore(30)
    setNewGain(200)
  }

  return (
    <div className="card bg-dark-700/20 mb-4">
      <div className="flex items-center justify-between mb-3">
        <div>
          <div className="text-sm font-semibold text-slate-300">Profils de risque</div>
          <div className="text-[10px] text-slate-600 mt-0.5">
            Un trade est loggé dans le journal s'il passe <span className="text-slate-500">au moins un</span> profil activé
            · Formule : EV nette = (score/100 × gain/100) − (1 − score/100)
          </div>
        </div>
        <button onClick={() => setShowNew(true)}
          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">
          <Plus className="w-3 h-3" /> Nouveau profil
        </button>
      </div>

      {isLoading ? (
        <div className="h-16 animate-pulse bg-dark-700 rounded" />
      ) : profiles.length === 0 ? (
        <div className="text-center py-6 text-slate-600 text-sm">Aucun profil — tous les trades seront ignorés</div>
      ) : (
        <div className="space-y-1">
          {profiles.map((p: any) => (
            <ProfileRow key={p.id} profile={p}
              onSave={data => upsert(data)}
              onDelete={id => del(id)} />
          ))}
        </div>
      )}

      {/* New profile form */}
      {showNew && (
        <div className="bg-dark-700/60 rounded-lg p-3 border border-blue-700/30 space-y-3 mt-3">
          <div className="flex items-center justify-between">
            <span className="text-xs font-semibold text-blue-400">Nouveau profil</span>
            <button onClick={() => setShowNew(false)} className="text-slate-600 hover:text-slate-400"><X className="w-3.5 h-3.5" /></button>
          </div>
          <div className="grid grid-cols-3 gap-3">
            <div>
              <label className="text-[10px] text-slate-500 mb-1 block">Nom</label>
              <input value={newName} onChange={e => setNewName(e.target.value)} placeholder="ex: Ultra-risqué"
                className="w-full bg-dark-800 border border-slate-700 rounded px-2 py-1 text-sm text-white placeholder:text-slate-700" />
            </div>
            <div>
              <label className="text-[10px] text-slate-500 mb-1 block">Score min = <span className="text-blue-400 font-mono">{newScore}</span></label>
              <input type="range" min="0" max="90" step="5" value={newScore}
                onChange={e => setNewScore(parseInt(e.target.value))} className="w-full accent-blue-500" />
            </div>
            <div>
              <label className="text-[10px] text-slate-500 mb-1 block">Gain min = <span className="text-blue-400 font-mono">{newGain}%</span></label>
              <input type="range" min="10" max="2000" step="10" value={newGain}
                onChange={e => setNewGain(parseFloat(e.target.value))} className="w-full accent-blue-500" />
            </div>
          </div>

          {/* Live math */}
          <div className="bg-dark-800 rounded px-3 py-2 text-xs flex items-center gap-4 flex-wrap">
            <span className={clsx('font-mono font-bold', evNetLabel(nEvNet).cls)}>{evNetLabel(nEvNet).text}</span>
            <span className="text-slate-600">Trade Score = <span className="text-slate-400">{nTradeScore.toFixed(1)}</span>/100</span>
            <span className="text-slate-700">Score min pour EV=0 avec gain {newGain}% : <span className="text-slate-500 font-mono">{nMinScore}</span>/100</span>
          </div>

          <div className="flex items-center gap-3">
            <div className="flex gap-1.5">
              {PROFILE_COLORS.map(c => (
                <button key={c.value} onClick={() => setNewColor(c.value)} title={c.label}
                  className={clsx('w-5 h-5 rounded-full border-2 transition-all',
                    newColor === c.value ? 'border-white scale-110' : 'border-transparent opacity-60 hover:opacity-100')}
                  style={{ background: c.value }} />
              ))}
            </div>
            <div className="ml-auto flex gap-2">
              <button onClick={() => setShowNew(false)} className="text-xs text-slate-500 hover:text-slate-300 px-2 py-1">Annuler</button>
              <button onClick={saveNew} disabled={!newName.trim()}
                className="text-xs bg-blue-600 hover:bg-blue-500 disabled:opacity-40 text-white px-3 py-1 rounded font-semibold">
                Créer
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Frontier visualization */}
      {profiles.length > 0 && (
        <div className="mt-3 pt-3 border-t border-slate-700/30">
          <div className="text-[10px] text-slate-600 mb-2">Frontière d'acceptation — chaque point représente le minimum requis par profil</div>
          <div className="flex flex-wrap gap-2">
            {profiles.filter((p: any) => p.enabled).map((p: any) => {
              const { text: ev, cls } = evNetLabel(p.ev_net_at_frontier ?? 0)
              return (
                <div key={p.id} className="flex items-center gap-2 bg-dark-700 rounded px-2.5 py-1.5 text-xs">
                  <div className="w-2 h-2 rounded-full" style={{ background: p.color }} />
                  <span className="text-slate-400 font-semibold">{p.name}</span>
                  <span className="font-mono text-slate-500">{p.min_score}pts</span>
                  <span className="text-slate-600">×</span>
                  <span className="font-mono text-slate-500">{p.min_gain_pct}%</span>
                  <span className={clsx('font-mono text-[10px]', cls)}>→ {ev}</span>
                </div>
              )
            })}
          </div>
        </div>
      )}
    </div>
  )
}

export default function Config() {
  const { data: sources, isLoading } = useSources()
  const { data: config } = useConfig()
  const { data: aiStatus } = useAiStatus()
  const { data: analysisCfg } = useAnalysisConfig()
  const { mutate: updateSources, isPending: savingSources } = useUpdateSources()
  const { mutate: updateApiKeys, isPending: savingKeys } = useUpdateApiKeys()
  const { mutate: saveAnalysis, isPending: savingAnalysis } = useSaveAnalysisConfig()
  const { data: cycleStatus, refetch: refetchCycle } = useCycleStatus()
  const { mutate: updateCycleConfig, isPending: savingCycle } = useUpdateCycleConfig()
  const { mutate: triggerCycle, isPending: triggeringCycle } = useTriggerCycle()
  const { data: exitDefaultsData } = useExitDefaults()
  const { mutate: saveExitDefaults, isPending: savingExitDefaults } = useSaveExitDefaults()

  const [localSources, setLocalSources] = useState<Record<string, any> | null>(null)
  const [openaiKey, setOpenaiKey] = useState('')
  const [newsapiKey, setNewsapiKey] = useState('')
  const [eiaKey, setEiaKey] = useState('')
  const [fredKey, setFredKey] = useState('')
  const [showKeys, setShowKeys] = useState(false)
  const [savedMsg, setSavedMsg] = useState('')
  const [configTab, setConfigTab] = useState<'ia' | 'cycle' | 'sources' | 'journal' | 'profiles'>('ia')

  // Analysis config local state
  const [analysisTopN, setAnalysisTopN] = useState(10)
  const [analysisCategoryDefault, setAnalysisCategoryDefault] = useState('all')
  const [analysisTemplate, setAnalysisTemplate] = useState('')

  // Exit defaults local state
  const [exitTarget, setExitTarget] = useState(30)
  const [exitStop, setExitStop] = useState(-50)
  const [exitSignalMode, setExitSignalMode] = useState('badge_only')
  const [exitSignalThreshold, setExitSignalThreshold] = useState(25)
  useEffect(() => {
    const ed = exitDefaultsData as any
    if (ed) {
      setExitTarget(ed.target_pct ?? 30)
      setExitStop(ed.stop_loss_pct ?? -50)
      setExitSignalMode(ed.signal_reversal_mode ?? 'badge_only')
      setExitSignalThreshold(ed.signal_reversal_threshold ?? 25)
    }
  }, [exitDefaultsData])

  // VaR + PnL scheduler state
  const qc = useQueryClient()
  const { data: schedStatus, refetch: refetchSched } = useQuery({
    queryKey: ['sched-status'],
    queryFn: () => fetch(`${API}/api/var/scheduler/status`).then(r => r.json()),
    staleTime: 30_000,
    retry: 1,
  })
  const [varSchedEnabled, setVarSchedEnabled] = useState(false)
  const [varSchedHours, setVarSchedHours] = useState(6)
  const [pnlSchedEnabled, setPnlSchedEnabled] = useState(false)
  const [pnlSchedHours, setPnlSchedHours] = useState(1)
  useEffect(() => {
    if (schedStatus) {
      setVarSchedEnabled(schedStatus.var?.enabled ?? false)
      setVarSchedHours(schedStatus.var?.hours ?? 6)
      setPnlSchedEnabled(schedStatus.pnl?.enabled ?? false)
      setPnlSchedHours(schedStatus.pnl?.hours ?? 1)
    }
  }, [schedStatus])
  const { mutate: saveSchedConfig, isPending: savingSched } = useMutation({
    mutationFn: (cfg: any) => fetch(`${API}/api/var/scheduler/config`, {
      method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(cfg),
    }).then(r => r.json()),
    onSuccess: () => { refetchSched(); setSavedMsg('Schedulers sauvegardés'); setTimeout(() => setSavedMsg(''), 2000) },
  })
  const { mutate: triggerVarNow, isPending: triggeringVar } = useMutation({
    mutationFn: () => fetch(`${API}/api/var/run-now`, { method: 'POST' }).then(r => r.json()),
    onSuccess: () => { setSavedMsg('Snapshot VaR sauvegardé'); setTimeout(() => setSavedMsg(''), 2000) },
  })
  const { mutate: triggerPnlNow, isPending: triggeringPnl } = useMutation({
    mutationFn: () => fetch(`${API}/api/var/pnl/run-now`, { method: 'POST' }).then(r => r.json()),
    onSuccess: () => { setSavedMsg('Snapshot PnL sauvegardé'); setTimeout(() => setSavedMsg(''), 2000) },
  })

  // Auto-cycle local state
  const cs = cycleStatus as any
  const [cycleEnabled, setCycleEnabled] = useState(false)
  const [cycleHours, setCycleHours] = useState(3)
  const [cycleSimilarity, setCycleSimilarity] = useState(0.30)
  const [minEv, setMinEv] = useState(0.0)
  const [minScore, setMinScore] = useState(0)
  const [retentionDays, setRetentionDays] = useState(90)
  const [maturityThreshold, setMaturityThreshold] = useState(35)
  useEffect(() => {
    if (cs) {
      setCycleEnabled(cs.enabled ?? false)
      setCycleHours(cs.interval_hours ?? 3)
      setCycleSimilarity(cs.similarity_threshold ?? 0.30)
      setMinEv(cs.min_ev_threshold ?? 0.0)
      setMinScore(cs.min_score_threshold ?? 0)
      setRetentionDays(cs.journal_retention_days ?? 90)
      setMaturityThreshold(cs.maturity_threshold_pct ?? 35)
    }
  }, [cs])

  useEffect(() => {
    if (analysisCfg) {
      setAnalysisTopN(analysisCfg.top_n ?? 10)
      setAnalysisCategoryDefault(analysisCfg.category_filter ?? 'all')
      setAnalysisTemplate(analysisCfg.template ?? '')
    }
  }, [analysisCfg])

  const displaySources = localSources ?? sources ?? {}

  const toggleSource = (key: string) => {
    setLocalSources(prev => {
      const base = prev ?? sources ?? {}
      return { ...base, [key]: { ...base[key], enabled: !base[key]?.enabled } }
    })
  }

  const saveSources = () => {
    updateSources(displaySources, {
      onSuccess: () => { setSavedMsg('Sources sauvegardées'); setTimeout(() => setSavedMsg(''), 2000) }
    })
  }

  const saveKeys = () => {
    const keys: Record<string, string> = {}
    if (openaiKey) keys.openai_api_key = openaiKey
    if (newsapiKey) keys.newsapi_key = newsapiKey
    if (eiaKey) keys.eia_api_key = eiaKey
    if (fredKey) keys.fred_api_key = fredKey
    updateApiKeys(keys, {
      onSuccess: () => {
        setSavedMsg('Clés API sauvegardées')
        setTimeout(() => setSavedMsg(''), 2000)
        setOpenaiKey(''); setNewsapiKey(''); setEiaKey(''); setFredKey('')
      }
    })
  }

  const CONFIG_TABS = [
    { key: 'ia',       label: 'IA & Analyse',           icon: Brain },
    { key: 'cycle',    label: 'Auto-Cycle & Logging',   icon: Zap },
    { key: 'sources',  label: 'Sources',                icon: Globe },
    { key: 'journal',  label: 'Journal & Sortie',       icon: Lock },
    { key: 'profiles', label: 'Profils de risque',      icon: SlidersHorizontal },
  ] as const

  return (
    <div className="p-6 space-y-5">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-xl font-bold text-white flex items-center gap-2">
            <Settings className="w-5 h-5 text-blue-400" /> Configuration
          </h1>
          <p className="text-xs text-slate-500 mt-0.5">Clés API, sources, paramètres IA &amp; cycle</p>
        </div>
        {savedMsg && (
          <div className="flex items-center gap-2 text-emerald-400 text-sm bg-emerald-900/10 border border-emerald-700/30 rounded px-3 py-1.5">
            <CheckCircle className="w-4 h-4" /> {savedMsg}
          </div>
        )}
      </div>

      {/* Tab navigation */}
      <div className="flex gap-1 bg-dark-700 p-1 rounded w-fit">
        {CONFIG_TABS.map(({ key, label, icon: Icon }) => (
          <button key={key} onClick={() => setConfigTab(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': configTab === key,
              'text-slate-400 hover:text-slate-200': configTab !== key,
            })}>
            <Icon className="w-3.5 h-3.5" />
            {label}
          </button>
        ))}
      </div>

      {/* ── IA & Analyse ── */}
      {configTab === 'ia' && (
        <div className="grid grid-cols-2 gap-6">
          <div className="space-y-4">
          {/* AI Status */}
          <div className={clsx('card', aiStatus?.enabled ? 'border-emerald-700/40' : 'border-slate-700/40')}>
            <div className="section-title flex items-center gap-1"><Key className="w-3 h-3" /> Statut IA</div>
            <div className="flex items-center gap-3 mb-3">
              {aiStatus?.enabled ? (
                <><CheckCircle className="w-5 h-5 text-emerald-400" />
                <div><div className="text-sm text-emerald-400 font-semibold">OpenAI Connecté</div>
                <div className="text-xs text-slate-500">GPT-4o + GPT-4o-mini</div></div></>
              ) : (
                <><XCircle className="w-5 h-5 text-red-400" />
                <div><div className="text-sm text-red-400 font-semibold">OpenAI Non configuré</div>
                <div className="text-xs text-slate-500">Entrer la clé ci-dessous</div></div></>
              )}
            </div>
            <div className="text-xs text-slate-600 space-y-1">
              <div>• Analyse de discours (Trump, Powell...)</div>
              <div>• Classification IA des actualités</div>
              <div>• Évaluation de patterns</div>
              <div>• Top 10 idées contextualisées</div>
            </div>
          </div>

          {/* OpenAI API Key */}
          <div className="card">
            <div className="flex items-center justify-between mb-3">
              <div className="section-title mb-0 flex items-center gap-1"><Key className="w-3 h-3" /> Clé OpenAI</div>
              <button onClick={() => setShowKeys(!showKeys)} className="text-slate-500 hover:text-slate-300">
                {showKeys ? <EyeOff className="w-3.5 h-3.5" /> : <Eye className="w-3.5 h-3.5" />}
              </button>
            </div>
            <div className="space-y-3">
              <div>
                <div className="flex items-center justify-between mb-1">
                  <label className="text-xs text-slate-500">OpenAI API Key</label>
                  <span className={clsx('text-xs', aiStatus?.enabled ? 'text-emerald-400' : 'text-slate-600')}>
                    {aiStatus?.enabled ? '✓ Actif' : '○ Inactif'}
                  </span>
                </div>
                <input
                  type={showKeys ? 'text' : 'password'}
                  value={openaiKey}
                  onChange={e => setOpenaiKey(e.target.value)}
                  placeholder="sk-proj-..."
                  className="w-full bg-dark-700 border border-slate-700 rounded px-2 py-1.5 text-xs text-white focus:outline-none focus:border-blue-500 font-mono"
                />
              </div>
              <button
                onClick={saveKeys}
                disabled={savingKeys || !openaiKey}
                className="w-full bg-blue-600 hover:bg-blue-500 disabled:opacity-40 text-white rounded py-1.5 text-xs font-semibold flex items-center justify-center gap-1.5"
              >
                <Save className="w-3.5 h-3.5" />
                {savingKeys ? 'Sauvegarde...' : 'Sauvegarder la clé'}
              </button>
            </div>
          </div>
          </div>

          {/* Right: Analysis params */}
          <div className="card">
            <h2 className="text-base font-bold text-white flex items-center gap-2 mb-4">
              <SlidersHorizontal className="w-4 h-4 text-blue-400" /> Paramètres d'analyse IA
            </h2>
            <div className="grid grid-cols-2 gap-4 mb-4">
              <div>
                <label className="text-xs text-slate-500 mb-1 block">Top N résultats par défaut</label>
                <div className="flex gap-1">
                  {[5, 10, 15, 20].map(n => (
                    <button key={n} onClick={() => setAnalysisTopN(n)}
                      className={clsx('flex-1 py-1.5 rounded text-sm transition-colors', {
                        'bg-blue-600 text-white': analysisTopN === n,
                        'bg-dark-700 text-slate-400 hover:text-slate-200': analysisTopN !== n,
                      })}>
                      Top {n}
                    </button>
                  ))}
                </div>
              </div>
              <div>
                <label className="text-xs text-slate-500 mb-1 block">Catégorie par défaut</label>
                <select value={analysisCategoryDefault} onChange={e => setAnalysisCategoryDefault(e.target.value)}
                  className="w-full bg-dark-700 border border-slate-700 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:border-blue-500">
                  <option value="all">Toutes les catégories</option>
                  <option value="energy">Énergie</option>
                  <option value="metals">Métaux</option>
                  <option value="agriculture">Agriculture</option>
                  <option value="indices">Indices</option>
                  <option value="equities">Actions</option>
                  <option value="forex">Forex</option>
                </select>
              </div>
            </div>
            <div className="mb-4">
              <div className="flex items-center justify-between mb-1">
                <label className="text-xs text-slate-500">Template d'analyse (prompt GPT-4o)</label>
                <button onClick={() => setAnalysisTemplate('')} className="text-xs text-slate-600 hover:text-slate-400">
                  Par défaut
                </button>
              </div>
              <textarea
                value={analysisTemplate}
                onChange={e => setAnalysisTemplate(e.target.value)}
                rows={8}
                placeholder="Laisser vide pour utiliser le template par défaut..."
                className="w-full bg-dark-700 border border-slate-700 rounded px-3 py-2 text-sm text-white font-mono focus:outline-none focus:border-blue-500 resize-y"
              />
              <div className="text-xs text-slate-600 mt-1">
                Contexte marché (prix, IV, variation 1j) et news filtrées sont injectés automatiquement.
              </div>
            </div>
            <button
              onClick={() => saveAnalysis(
                { top_n: analysisTopN, category_filter: analysisCategoryDefault, template: analysisTemplate || undefined },
                { onSuccess: () => { setSavedMsg('Paramètres d\'analyse sauvegardés'); setTimeout(() => setSavedMsg(''), 2000) } }
              )}
              disabled={savingAnalysis}
              className="flex items-center gap-1.5 bg-blue-600 hover:bg-blue-500 disabled:opacity-40 text-white px-4 py-2 rounded text-sm font-semibold">
              <Save className="w-4 h-4" />
              {savingAnalysis ? 'Sauvegarde...' : 'Sauvegarder'}
            </button>
          </div>
        </div>
      )}

      {/* ── Auto-Cycle & Logging ── */}
      {configTab === 'cycle' && (
        <div className="space-y-5">
          {/* Score min threshold — prominent */}
          <div className="card border-blue-700/40 bg-blue-900/5">
            <h2 className="text-base font-bold text-white flex items-center gap-2 mb-1">
              <SlidersHorizontal className="w-4 h-4 text-blue-400" /> Score minimum pour le cycle
            </h2>
            <p className="text-xs text-slate-500 mb-4">
              Pré-filtre du cycle — les patterns avec un score inférieur ne sont pas soumis à l'analyse.
              Les profils de risque déterminent ensuite quels trades sont loggés.
            </p>
            <div className="grid grid-cols-2 gap-6">
              <div>
                <label className="text-xs text-slate-500 mb-2 block">
                  Score minimum pre-cycle : <span className="text-blue-300 font-mono font-bold text-lg">{minScore}</span>
                  <span className="text-slate-600 ml-1">/100</span>
                </label>
                <input type="range" min="0" max="80" step="5"
                  value={minScore}
                  onChange={e => setMinScore(parseInt(e.target.value))}
                  className="w-full accent-blue-500" />
                <div className="flex justify-between text-[10px] text-slate-600 mt-1">
                  <span>0 (tous)</span><span>80 (très sélectif)</span>
                </div>
                <div className="text-xs text-slate-500 mt-2">
                  {minScore === 0
                    ? 'Tous les patterns analysés par le cycle'
                    : `Seuls les patterns avec score ≥ ${minScore} sont soumis au cycle`}
                </div>
              </div>
              <div>
                <label className="text-xs text-slate-500 mb-2 block">
                  EV minimum : <span className="text-blue-300 font-mono font-bold">{minEv >= 0 ? '+' : ''}{(minEv * 100).toFixed(0)}%</span>
                  <span className="text-slate-600 ml-1">net attendu</span>
                </label>
                <input type="range" min="-0.5" max="0.5" step="0.05"
                  value={minEv}
                  onChange={e => setMinEv(parseFloat(e.target.value))}
                  className="w-full accent-blue-500" />
                <div className="flex justify-between text-[10px] text-slate-600 mt-1">
                  <span>-50%</span><span>+50%</span>
                </div>
                <div className="text-xs text-slate-500 mt-2">
                  {minEv === 0
                    ? 'Toute EV nette acceptée'
                    : minEv > 0
                    ? `EV nette ≥ +${(minEv * 100).toFixed(0)}% requise`
                    : `Filtre désactivé (EV < ${(minEv * 100).toFixed(0)}%)`}
                </div>
              </div>
            </div>
          </div>

          {/* Auto-Cycle settings */}
          <div className="card">
            <div className="flex items-center justify-between mb-4">
              <h2 className="text-base font-bold text-white flex items-center gap-2">
                <Zap className="w-4 h-4 text-blue-400" /> Auto-Cycle Intelligence
              </h2>
              {cs && (
                <div className="flex items-center gap-2 text-xs">
                  {cs.running ? (
                    <span className="flex items-center gap-1 text-blue-400 bg-blue-900/30 border border-blue-700/30 px-2 py-0.5 rounded animate-pulse">
                      <RefreshCw className="w-3 h-3 animate-spin" /> En cours...
                    </span>
                  ) : cs.scheduler_alive ? (
                    <span className="text-emerald-400 bg-emerald-900/30 border border-emerald-700/30 px-2 py-0.5 rounded">
                      ● Scheduler actif
                    </span>
                  ) : (
                    <span className="text-slate-600 bg-dark-700 border border-slate-700/30 px-2 py-0.5 rounded">
                      ○ Scheduler inactif
                    </span>
                  )}
                </div>
              )}
            </div>
            <p className="text-xs text-slate-500 mb-4">
              Toutes les N heures : suggère de nouveaux patterns, filtre les doublons, score tout, log les prix et génère un commentaire IA.
            </p>

            <div className="grid grid-cols-3 gap-4 mb-4">
              <div>
                <label className="text-xs text-slate-500 mb-2 block">Activer l'auto-cycle</label>
                <button
                  onClick={() => setCycleEnabled(!cycleEnabled)}
                  className={clsx('w-full py-2 rounded border text-sm font-semibold transition-all', {
                    'bg-blue-600 border-blue-500 text-white': cycleEnabled,
                    'bg-dark-700 border-slate-700 text-slate-400 hover:border-slate-500': !cycleEnabled,
                  })}>
                  {cycleEnabled ? '✓ Activé' : '○ Désactivé'}
                </button>
              </div>
              <div>
                <label className="text-xs text-slate-500 mb-2 block">Intervalle (heures)</label>
                <div className="flex gap-1">
                  {[1, 3, 6, 12].map(h => (
                    <button key={h} onClick={() => setCycleHours(h)}
                      className={clsx('flex-1 py-2 rounded text-sm transition-colors', {
                        'bg-blue-600 text-white': cycleHours === h,
                        'bg-dark-700 text-slate-400 hover:text-slate-200': cycleHours !== h,
                      })}>
                      {h}h
                    </button>
                  ))}
                </div>
              </div>
              <div>
                <label className="text-xs text-slate-500 mb-2 block">
                  Similarité max ({Math.round(cycleSimilarity * 100)}%)
                </label>
                <input type="range" min="0.1" max="0.8" step="0.05"
                  value={cycleSimilarity}
                  onChange={e => setCycleSimilarity(parseFloat(e.target.value))}
                  className="w-full accent-blue-500" />
                <div className="flex justify-between text-[10px] text-slate-600 mt-1">
                  <span>10% (strict)</span><span>80% (permissif)</span>
                </div>
              </div>
            </div>

            <div className="grid grid-cols-2 gap-4 mb-4">
              <div>
                <label className="text-xs text-slate-500 mb-2 block">
                  Rétention Journal ({retentionDays}j)
                </label>
                <div className="flex gap-1">
                  {[30, 60, 90, 180].map(d => (
                    <button key={d} onClick={() => setRetentionDays(d)}
                      className={clsx('flex-1 py-2 rounded text-sm transition-colors', {
                        'bg-blue-600 text-white': retentionDays === d,
                        'bg-dark-700 text-slate-400 hover:text-slate-200': retentionDays !== d,
                      })}>
                      {d}j
                    </button>
                  ))}
                </div>
              </div>
              <div>
                <label className="text-xs text-slate-500 mb-2 block">
                  Seuil maturité ({maturityThreshold}%)
                </label>
                <div className="flex gap-1">
                  {[20, 30, 35, 50].map(p => (
                    <button key={p} onClick={() => setMaturityThreshold(p)}
                      className={clsx('flex-1 py-2 rounded text-sm transition-colors', {
                        'bg-blue-600 text-white': maturityThreshold === p,
                        'bg-dark-700 text-slate-400 hover:text-slate-200': maturityThreshold !== p,
                      })}>
                      {p}%
                    </button>
                  ))}
                </div>
              </div>
            </div>

            {cs?.last_cycle && (
              <div className="card bg-dark-700/50 mb-2 text-xs space-y-2">
                <div className="flex items-center gap-4 flex-wrap">
                  <span className="text-slate-500">Dernier cycle :</span>
                  <span className="text-slate-300">{cs.last_cycle.started_at?.slice(0, 16)} UTC</span>
                  <span className={clsx('badge', cs.last_cycle.status === 'completed' ? 'badge-green' : 'badge-red')}>
                    {cs.last_cycle.status}
                  </span>
                  <span className="text-slate-500">+{cs.last_cycle.patterns_added} patterns</span>
                  <span className="text-slate-500">{cs.last_cycle.patterns_scored} scorés</span>
                  <span className="text-slate-500">Géo: {cs.last_cycle.geo_score}</span>
                  <span className="text-slate-500 capitalize">{cs.last_cycle.dominant_regime}</span>
                </div>
              </div>
            )}
            {cs?.enabled && cs?.next_run_at && !cs?.running && (
              <div className="card bg-dark-700/50 mb-4 text-xs">
                <NextRunCountdown nextRunAt={cs.next_run_at} />
              </div>
            )}

            <div className="flex items-center gap-3">
              <button
                onClick={() => updateCycleConfig(
                  { enabled: cycleEnabled, interval_hours: cycleHours, similarity_threshold: cycleSimilarity, min_ev_threshold: minEv, min_score_threshold: minScore, journal_retention_days: retentionDays, maturity_threshold_pct: maturityThreshold },
                  { onSuccess: () => { refetchCycle(); setSavedMsg('Auto-cycle configuré'); setTimeout(() => setSavedMsg(''), 2000) } }
                )}
                disabled={savingCycle}
                className="flex items-center gap-1.5 bg-blue-600 hover:bg-blue-500 disabled:opacity-40 text-white px-4 py-2 rounded text-sm font-semibold">
                <Save className="w-4 h-4" />
                {savingCycle ? 'Sauvegarde...' : 'Appliquer'}
              </button>
              <button
                onClick={() => triggerCycle(undefined, { onSuccess: () => { refetchCycle(); setSavedMsg('Cycle lancé !'); setTimeout(() => setSavedMsg(''), 3000) } })}
                disabled={triggeringCycle || !aiStatus?.enabled}
                className="flex items-center gap-1.5 border border-blue-500/50 text-blue-400 hover:bg-blue-900/20 disabled:opacity-40 px-4 py-2 rounded text-sm font-semibold">
                <RefreshCw className={clsx('w-4 h-4', triggeringCycle && 'animate-spin')} />
                Lancer maintenant
              </button>
            </div>
          </div>

          {/* ── VaR & PnL Schedulers ── */}
          <div className="card">
            <h2 className="text-base font-bold text-white flex items-center gap-2 mb-4">
              <Gauge className="w-4 h-4 text-red-400" /> Schedulers VaR &amp; PnL
            </h2>
            <p className="text-xs text-slate-500 mb-4">
              Calcule et sauvegarde automatiquement les snapshots VaR (Black-Scholes delta) et PnL à intervalles définis.
              Les données sont accessibles depuis la page VaR Analyse avec un historique complet.
            </p>
            <div className="grid grid-cols-2 gap-6 mb-4">
              {/* VaR scheduler */}
              <div className="space-y-3">
                <div className="flex items-center gap-2">
                  <Gauge className="w-3.5 h-3.5 text-red-400" />
                  <span className="text-sm font-semibold text-slate-300">Scheduler VaR</span>
                  {schedStatus?.var?.alive
                    ? <span className="text-[10px] bg-emerald-900/30 text-emerald-400 border border-emerald-700/30 px-1.5 py-0.5 rounded ml-auto">● Actif</span>
                    : <span className="text-[10px] bg-dark-700 text-slate-600 border border-slate-700/30 px-1.5 py-0.5 rounded ml-auto">○ Inactif</span>}
                </div>
                <div>
                  <label className="text-xs text-slate-500 mb-1 block">Activer</label>
                  <button onClick={() => setVarSchedEnabled(!varSchedEnabled)}
                    className={clsx('w-full py-2 rounded border text-sm font-semibold transition-all', {
                      'bg-red-700 border-red-600 text-white': varSchedEnabled,
                      'bg-dark-700 border-slate-700 text-slate-400': !varSchedEnabled,
                    })}>
                    {varSchedEnabled ? '✓ Activé' : '○ Désactivé'}
                  </button>
                </div>
                <div>
                  <label className="text-xs text-slate-500 mb-1 block">Intervalle</label>
                  <div className="flex gap-1">
                    {[1, 3, 6, 12, 24].map(h => (
                      <button key={h} onClick={() => setVarSchedHours(h)}
                        className={clsx('flex-1 py-1.5 rounded text-xs transition-colors', {
                          'bg-red-700 text-white': varSchedHours === h,
                          'bg-dark-700 text-slate-400 hover:text-slate-200': varSchedHours !== h,
                        })}>
                        {h}h
                      </button>
                    ))}
                  </div>
                </div>
              </div>

              {/* PnL scheduler */}
              <div className="space-y-3">
                <div className="flex items-center gap-2">
                  <DollarSign className="w-3.5 h-3.5 text-emerald-400" />
                  <span className="text-sm font-semibold text-slate-300">Scheduler PnL</span>
                  {schedStatus?.pnl?.alive
                    ? <span className="text-[10px] bg-emerald-900/30 text-emerald-400 border border-emerald-700/30 px-1.5 py-0.5 rounded ml-auto">● Actif</span>
                    : <span className="text-[10px] bg-dark-700 text-slate-600 border border-slate-700/30 px-1.5 py-0.5 rounded ml-auto">○ Inactif</span>}
                </div>
                <div>
                  <label className="text-xs text-slate-500 mb-1 block">Activer</label>
                  <button onClick={() => setPnlSchedEnabled(!pnlSchedEnabled)}
                    className={clsx('w-full py-2 rounded border text-sm font-semibold transition-all', {
                      'bg-emerald-700 border-emerald-600 text-white': pnlSchedEnabled,
                      'bg-dark-700 border-slate-700 text-slate-400': !pnlSchedEnabled,
                    })}>
                    {pnlSchedEnabled ? '✓ Activé' : '○ Désactivé'}
                  </button>
                </div>
                <div>
                  <label className="text-xs text-slate-500 mb-1 block">Intervalle</label>
                  <div className="flex gap-1">
                    {[1, 2, 4, 8, 24].map(h => (
                      <button key={h} onClick={() => setPnlSchedHours(h)}
                        className={clsx('flex-1 py-1.5 rounded text-xs transition-colors', {
                          'bg-emerald-700 text-white': pnlSchedHours === h,
                          'bg-dark-700 text-slate-400 hover:text-slate-200': pnlSchedHours !== h,
                        })}>
                        {h}h
                      </button>
                    ))}
                  </div>
                </div>
              </div>
            </div>

            <div className="flex items-center gap-3 flex-wrap">
              <button
                onClick={() => saveSchedConfig({ var_enabled: varSchedEnabled, var_hours: varSchedHours, pnl_enabled: pnlSchedEnabled, pnl_hours: pnlSchedHours })}
                disabled={savingSched}
                className="flex items-center gap-1.5 bg-blue-600 hover:bg-blue-500 disabled:opacity-40 text-white px-4 py-2 rounded text-sm font-semibold">
                <Save className="w-4 h-4" />
                {savingSched ? 'Sauvegarde…' : 'Appliquer'}
              </button>
              <button
                onClick={() => triggerVarNow()}
                disabled={triggeringVar}
                className="flex items-center gap-1.5 border border-red-500/50 text-red-400 hover:bg-red-900/20 disabled:opacity-40 px-4 py-2 rounded text-sm font-semibold">
                <Gauge className={clsx('w-4 h-4', triggeringVar && 'animate-spin')} />
                Snapshot VaR maintenant
              </button>
              <button
                onClick={() => triggerPnlNow()}
                disabled={triggeringPnl}
                className="flex items-center gap-1.5 border border-emerald-500/50 text-emerald-400 hover:bg-emerald-900/20 disabled:opacity-40 px-4 py-2 rounded text-sm font-semibold">
                <DollarSign className={clsx('w-4 h-4', triggeringPnl && 'animate-spin')} />
                Snapshot PnL maintenant
              </button>
            </div>
          </div>
        </div>
      )}

      {/* ── Sources ── */}
      {configTab === 'sources' && (
        <div className="space-y-5">
          {/* Data API Keys */}
          <div className="card">
            <div className="flex items-center justify-between mb-3">
              <div className="section-title mb-0 flex items-center gap-1"><Key className="w-3 h-3" /> Clés API données</div>
              <button onClick={() => setShowKeys(!showKeys)} className="text-slate-500 hover:text-slate-300">
                {showKeys ? <EyeOff className="w-3.5 h-3.5" /> : <Eye className="w-3.5 h-3.5" />}
              </button>
            </div>
            <div className="grid grid-cols-3 gap-4">
              {[
                { label: 'NewsAPI Key', value: newsapiKey, setter: setNewsapiKey, placeholder: 'Obtenir sur newsapi.org' },
                { label: 'EIA API Key', value: eiaKey, setter: setEiaKey, placeholder: 'Obtenir sur eia.gov' },
                { label: 'FRED API Key', value: fredKey, setter: setFredKey, placeholder: 'Obtenir sur fred.stlouisfed.org' },
              ].map(({ label, value, setter, placeholder }) => (
                <div key={label}>
                  <label className="text-xs text-slate-500 mb-1 block">{label}</label>
                  <input
                    type={showKeys ? 'text' : 'password'}
                    value={value}
                    onChange={e => setter(e.target.value)}
                    placeholder={placeholder}
                    className="w-full bg-dark-700 border border-slate-700 rounded px-2 py-1.5 text-xs text-white focus:outline-none focus:border-blue-500 font-mono"
                  />
                </div>
              ))}
            </div>
            <button
              onClick={saveKeys}
              disabled={savingKeys || (!newsapiKey && !eiaKey && !fredKey)}
              className="mt-3 flex items-center gap-1.5 bg-blue-600 hover:bg-blue-500 disabled:opacity-40 text-white px-4 py-2 rounded text-sm font-semibold">
              <Save className="w-4 h-4" />
              {savingKeys ? 'Sauvegarde...' : 'Sauvegarder les clés'}
            </button>
          </div>

          {/* RSS / data sources */}
          {isLoading ? (
            <div className="card animate-pulse h-40 bg-dark-700" />
          ) : (
            <>
              {Object.entries(SOURCE_CATEGORIES).map(([catName, keys]) => (
                <div key={catName} className="card">
                  <div className="section-title flex items-center gap-1">
                    <Globe className="w-3 h-3" /> {catName}
                  </div>
                  <div className="space-y-2">
                    {keys.map(key => {
                      const src = displaySources[key] ?? {}
                      const enabled = src.enabled ?? false
                      const requiresKey = src.requires_key
                      const doc = SOURCE_DOCS[key]
                      const keySet = requiresKey ? !!config?.[requiresKey + '_set'] : true
                      return (
                        <div key={key} className={clsx('flex items-start justify-between p-3 rounded border transition-all',
                          enabled ? 'border-blue-500/40 bg-blue-900/5' : 'border-slate-700/30 bg-dark-700/30')}>
                          <div className="flex-1 min-w-0 mr-3">
                            <div className="flex items-center gap-2">
                              <span className="text-xs text-white font-semibold">{src.name || key}</span>
                              <span className={clsx('badge text-xs', {
                                'badge-green': doc?.cost === 'Gratuit' || doc?.cost === 'Gratuit total',
                                'badge-blue': doc?.cost?.includes('gratuit') || doc?.cost?.includes('Inscription'),
                                'badge-yellow': doc?.cost?.includes('clé'),
                                'badge-red': doc?.cost?.includes('payante'),
                              })}>
                                {doc?.cost}
                              </span>
                              {requiresKey && !keySet && <span className="badge badge-orange text-xs">Clé requise</span>}
                            </div>
                            <div className="text-xs text-slate-500 mt-0.5">{doc?.description}</div>
                          </div>
                          <button onClick={() => toggleSource(key)} disabled={requiresKey && !keySet}
                            className={clsx('shrink-0 w-10 h-5 rounded-full border transition-all relative',
                              enabled ? 'bg-blue-600 border-blue-500' : 'bg-dark-600 border-slate-600',
                              requiresKey && !keySet && 'opacity-40 cursor-not-allowed')}>
                            <div className={clsx('absolute top-0.5 w-4 h-4 rounded-full bg-white transition-all',
                              enabled ? 'left-5' : 'left-0.5')} />
                          </button>
                        </div>
                      )
                    })}
                  </div>
                </div>
              ))}
              <div className="flex justify-end">
                <button onClick={saveSources} disabled={savingSources || !localSources}
                  className="flex items-center gap-2 bg-blue-600 hover:bg-blue-500 disabled:opacity-40 text-white px-4 py-2 rounded text-sm font-semibold">
                  <Save className="w-4 h-4" />
                  {savingSources ? 'Sauvegarde...' : 'Appliquer les changements'}
                </button>
              </div>
            </>
          )}
        </div>
      )}

      {/* ── Journal & Sortie ── */}
      {configTab === 'journal' && (
        <div className="card">
          <h2 className="text-base font-bold text-white flex items-center gap-2 mb-4">
            <Lock className="w-4 h-4 text-amber-400" /> Paramètres de sortie des trades
          </h2>
          <p className="text-xs text-slate-500 mb-4">
            Valeurs par défaut pour les objectifs et stop-loss. Chaque trade peut avoir ses propres seuils (Journal → Ouverts).
          </p>
          <div className="grid grid-cols-2 gap-6 mb-4">
            <div>
              <label className="text-xs text-slate-500 mb-2 block">
                Objectif de gain : <span className="text-emerald-400 font-mono font-bold">+{exitTarget}%</span>
                <span className="text-slate-600 ml-1">(P&L sous-jacent)</span>
              </label>
              <input type="range" min="5" max="150" step="5"
                value={exitTarget}
                onChange={e => setExitTarget(parseFloat(e.target.value))}
                className="w-full accent-emerald-500" />
              <div className="flex justify-between text-[10px] text-slate-600 mt-1">
                <span>+5%</span><span>+150%</span>
              </div>
            </div>
            <div>
              <label className="text-xs text-slate-500 mb-2 block">
                Stop-loss : <span className="text-red-400 font-mono font-bold">{exitStop}%</span>
                <span className="text-slate-600 ml-1">(P&L sous-jacent)</span>
              </label>
              <input type="range" min="-90" max="-5" step="5"
                value={exitStop}
                onChange={e => setExitStop(parseFloat(e.target.value))}
                className="w-full accent-red-500" />
              <div className="flex justify-between text-[10px] text-slate-600 mt-1">
                <span>-90%</span><span>-5%</span>
              </div>
            </div>
          </div>
          <div className="grid grid-cols-2 gap-6 mb-4">
            <div>
              <label className="text-xs text-slate-500 mb-2 block">Mode signal IA de retournement</label>
              <div className="flex gap-2">
                {[
                  { value: 'badge_only', label: '🔔 Badge uniquement' },
                  { value: 'auto', label: '⚡ Auto (futur)' },
                ].map(opt => (
                  <button key={opt.value} onClick={() => setExitSignalMode(opt.value)}
                    className={clsx('flex-1 py-2 rounded text-xs border transition-all', {
                      'bg-blue-600 border-blue-500 text-white': exitSignalMode === opt.value,
                      'bg-dark-700 border-slate-700 text-slate-400 hover:text-slate-200': exitSignalMode !== opt.value,
                    })}>
                    {opt.label}
                  </button>
                ))}
              </div>
              <div className="text-[10px] text-slate-600 mt-1">
                Badge only : alerte visible, vous confirmez manuellement. Auto : fermeture proposée.
              </div>
            </div>
            <div>
              <label className="text-xs text-slate-500 mb-2 block">
                Seuil retournement signal : <span className="text-blue-400 font-mono font-bold">{exitSignalThreshold}pts</span>
              </label>
              <input type="range" min="10" max="60" step="5"
                value={exitSignalThreshold}
                onChange={e => setExitSignalThreshold(parseFloat(e.target.value))}
                className="w-full accent-blue-500" />
              <div className="flex justify-between text-[10px] text-slate-600 mt-1">
                <span>10pts (sensible)</span><span>60pts (tolérant)</span>
              </div>
            </div>
          </div>
          <button
            onClick={() => saveExitDefaults(
              { target_pct: exitTarget, stop_loss_pct: exitStop,
                signal_reversal_mode: exitSignalMode, signal_reversal_threshold: exitSignalThreshold },
              { onSuccess: () => { setSavedMsg('Paramètres de sortie sauvegardés'); setTimeout(() => setSavedMsg(''), 2000) } }
            )}
            disabled={savingExitDefaults}
            className="flex items-center gap-1.5 bg-amber-600 hover:bg-amber-500 disabled:opacity-40 text-white px-4 py-2 rounded text-sm font-semibold">
            <Save className="w-4 h-4" />
            {savingExitDefaults ? 'Sauvegarde...' : 'Sauvegarder les seuils'}
          </button>
        </div>
      )}

      {/* ── Profils de risque ── */}
      {configTab === 'profiles' && <RiskProfilesCard />}

    </div>
  )
}
