import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import {
  BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ReferenceLine,
  LineChart, Line, ResponsiveContainer, Cell,
} from 'recharts'
import { ShieldAlert, TrendingDown, Activity, AlertTriangle, Info, Play, Clock, Database } from 'lucide-react'
import clsx from 'clsx'

// ─── API calls ───────────────────────────────────────────────────────────────

async function fetchLatest() {
  const r = await fetch('/api/var/latest')
  if (!r.ok) throw new Error(`Backend unreachable (${r.status})`)
  return r.json()
}

async function runNow(params: { confidence: number; horizon_days: number; lookback_days: number; default_iv: number }) {
  const qs = new URLSearchParams(Object.entries(params).map(([k, v]) => [k, String(v)])).toString()
  const r = await fetch(`/api/var/run-now?${qs}`, { method: 'POST' })
  if (!r.ok) {
    const txt = await r.text()
    throw new Error(txt)
  }
  return r.json()
}

async function fetchSnapshots() {
  const r = await fetch('/api/var/snapshots?limit=10')
  if (!r.ok) return { snapshots: [] }
  return r.json()
}

// ─── Sub-components ───────────────────────────────────────────────────────────

function MetricCard({
  label, method, var1d, varNd, cvar, varEur, cvarEur, horizon, stressed = false, colorClass,
}: {
  label: string; method: string; var1d: number; varNd: number; cvar: number
  varEur: number; cvarEur: number; horizon: number; stressed?: boolean; colorClass: string
}) {
  const pct = (v: number) => `${v > 0 ? '+' : ''}${v.toFixed(3)}%`
  const eur = (v: number) => `${v < 0 ? '' : '+'}${v.toLocaleString('fr-FR', { maximumFractionDigits: 0 })} €`
  const displayed = horizon === 1 ? var1d : varNd
  const displayedEur = horizon === 1 ? varEur : varEur * Math.sqrt(horizon)
  return (
    <div className={clsx('bg-dark-800 rounded-xl border p-4', colorClass)}>
      <div className="flex items-center justify-between mb-2">
        <span className="text-xs font-bold uppercase tracking-wider text-slate-300">{label}</span>
        {stressed && <span className="text-[10px] bg-orange-900/30 text-orange-400 border border-orange-700/40 px-1.5 py-0.5 rounded">Stressed ×1.5</span>}
      </div>
      <div className="text-[11px] text-slate-500 mb-3">{method}</div>
      <div className="space-y-2">
        <div>
          <div className="text-[10px] text-slate-500 mb-0.5">VaR {horizon}d</div>
          <div className={clsx('text-2xl font-bold', displayed < 0 ? 'text-red-400' : 'text-emerald-400')}>
            {pct(displayed)}
          </div>
          <div className={clsx('text-xs', displayedEur < 0 ? 'text-red-400/70' : 'text-emerald-400/70')}>
            {eur(displayedEur)}
          </div>
        </div>
        <div className="border-t border-slate-700/40 pt-2">
          <div className="text-[10px] text-slate-500 mb-0.5">CVaR (Expected Shortfall)</div>
          <div className={clsx('text-base font-semibold', cvar < 0 ? 'text-orange-400' : 'text-slate-300')}>
            {pct(cvar)}
          </div>
          <div className={clsx('text-xs', cvarEur < 0 ? 'text-orange-400/70' : 'text-slate-500')}>
            {eur(cvarEur)}
          </div>
        </div>
      </div>
    </div>
  )
}

function HistoTooltip({ active, payload }: any) {
  if (!active || !payload?.length) return null
  return (
    <div className="bg-dark-800 border border-slate-700 rounded px-2.5 py-1.5 text-xs">
      <div className="text-slate-300">Ret: <span className="font-bold">{payload[0].payload.x.toFixed(3)}%</span></div>
      <div className="text-slate-400">Obs: {payload[0].payload.count}</div>
    </div>
  )
}

function RollingTooltip({ active, payload, label }: any) {
  if (!active || !payload?.length) return null
  return (
    <div className="bg-dark-800 border border-slate-700 rounded px-2.5 py-1.5 text-xs">
      <div className="text-slate-500 mb-0.5">{label}</div>
      <div className="text-red-400 font-semibold">VaR: {payload[0]?.value?.toFixed(3)}%</div>
    </div>
  )
}

// ─── Empty state ──────────────────────────────────────────────────────────────

function IdleState({ onCompute, computing }: { onCompute: () => void; computing: boolean }) {
  return (
    <div className="flex flex-col items-center justify-center py-24 gap-6">
      <ShieldAlert className="w-16 h-16 text-slate-700" />
      <div className="text-center">
        <h2 className="text-lg font-semibold text-slate-400 mb-2">No VaR snapshot available</h2>
        <p className="text-slate-600 text-sm max-w-md">
          The VaR calculation does not run automatically to avoid unnecessary network calls.
          Click "Compute now" or configure the scheduler in Settings.
        </p>
      </div>
      <button
        onClick={onCompute}
        disabled={computing}
        className="flex items-center gap-2 bg-blue-600 hover:bg-blue-500 disabled:opacity-50 text-white px-6 py-3 rounded-lg font-semibold text-sm"
      >
        <Play className={clsx('w-4 h-4', computing && 'animate-pulse')} />
        {computing ? 'Computing…' : 'Compute now'}
      </button>
    </div>
  )
}

// ─── Main page ────────────────────────────────────────────────────────────────

export default function VaRAnalysis() {
  const qc = useQueryClient()
  const [confidence, setConfidence] = useState(0.95)
  const [horizon, setHorizon] = useState(1)
  const [lookback, setLookback] = useState(252)
  const [iv, setIv] = useState(0.20)
  const [activeSnap, setActiveSnap] = useState<any>(null)   // override from history

  // Load last snapshot from DB on mount (no heavy compute)
  const { data: latestData, isLoading: loadingLatest, error: latestError } = useQuery({
    queryKey: ['var-latest'],
    queryFn: fetchLatest,
    staleTime: 30_000,
    retry: 1,
  })

  const { data: snapshotsData } = useQuery({
    queryKey: ['var-snapshots'],
    queryFn: fetchSnapshots,
    staleTime: 60_000,
    retry: 1,
  })

  // Button-triggered compute + save
  const { mutate: compute, isPending: computing, error: computeError } = useMutation({
    mutationFn: () => runNow({ confidence, horizon_days: horizon, lookback_days: lookback, default_iv: iv }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['var-latest'] })
      qc.invalidateQueries({ queryKey: ['var-snapshots'] })
      setActiveSnap(null)
    },
  })

  // The displayed result: manual history pick OR latest from DB
  const displayedResult = activeSnap ?? latestData?.snapshot?.full_result
  const displayedMeta = activeSnap
    ? null
    : latestData?.snapshot

  const varData = displayedResult?.var
  const portfolio = displayedResult?.portfolio
  const histogram: any[] = displayedResult?.histogram ?? []
  const rolling: any[] = displayedResult?.rolling_var ?? []
  const positions: any[] = displayedResult?.positions ?? []
  const backtest = displayedResult?.backtest
  const histVarThreshold = varData?.historical?.var_1d_pct ?? 0

  const snapshots: any[] = snapshotsData?.snapshots ?? []

  const backendDown = latestError && String(latestError).includes('Backend')

  return (
    <div className="p-6 space-y-5 max-w-screen-xl mx-auto">

      {/* Header bar */}
      <div className="flex items-start justify-between flex-wrap gap-4">
        <div>
          <div className="flex items-center gap-3 mb-1">
            <ShieldAlert className="w-6 h-6 text-red-400" />
            <h1 className="text-xl font-bold text-white">VaR Analysis — Value at Risk</h1>
          </div>
          <p className="text-slate-400 text-sm">
            Delta Black-Scholes approach
            {displayedMeta && (
              <span className="ml-2 text-slate-500">
                · snapshot from {displayedMeta.computed_at?.slice(0, 16).replace('T', ' ')} UTC
                {displayedMeta.data_source === 'simulated' && (
                  <span className="ml-2 text-amber-400">⚠ simulated data</span>
                )}
              </span>
            )}
          </p>
        </div>

        {/* Controls */}
        <div className="flex flex-wrap gap-3 items-end">
          {/* Confidence */}
          <div>
            <div className="text-[10px] text-slate-500 mb-1 uppercase tracking-wider">Confidence</div>
            <div className="flex gap-1">
              {[0.90, 0.95, 0.99].map(c => (
                <button key={c} onClick={() => setConfidence(c)}
                  className={clsx('px-2.5 py-1.5 rounded text-xs font-semibold',
                    confidence === c ? 'bg-blue-600 text-white' : 'bg-dark-700 text-slate-400 hover:text-white')}>
                  {(c * 100).toFixed(0)}%
                </button>
              ))}
            </div>
          </div>
          {/* Horizon */}
          <div>
            <div className="text-[10px] text-slate-500 mb-1 uppercase tracking-wider">Horizon</div>
            <div className="flex gap-1">
              {[1, 5, 10, 21].map(h => (
                <button key={h} onClick={() => setHorizon(h)}
                  className={clsx('px-2.5 py-1.5 rounded text-xs font-semibold',
                    horizon === h ? 'bg-violet-600 text-white' : 'bg-dark-700 text-slate-400 hover:text-white')}>
                  {h}d
                </button>
              ))}
            </div>
          </div>
          {/* Lookback */}
          <div>
            <div className="text-[10px] text-slate-500 mb-1 uppercase tracking-wider">Lookback</div>
            <div className="flex gap-1">
              {[63, 126, 252].map(l => (
                <button key={l} onClick={() => setLookback(l)}
                  className={clsx('px-2.5 py-1.5 rounded text-xs font-semibold',
                    lookback === l ? 'bg-emerald-700 text-white' : 'bg-dark-700 text-slate-400 hover:text-white')}>
                  {l === 63 ? '3M' : l === 126 ? '6M' : '1A'}
                </button>
              ))}
            </div>
          </div>
          {/* IV */}
          <div>
            <div className="text-[10px] text-slate-500 mb-1 uppercase tracking-wider">Default IV</div>
            <div className="flex gap-1">
              {[0.15, 0.20, 0.30, 0.40].map(v => (
                <button key={v} onClick={() => setIv(v)}
                  className={clsx('px-2.5 py-1.5 rounded text-xs font-semibold',
                    iv === v ? 'bg-amber-600 text-white' : 'bg-dark-700 text-slate-400 hover:text-white')}>
                  {(v * 100).toFixed(0)}%
                </button>
              ))}
            </div>
          </div>
          {/* Compute button */}
          <button
            onClick={() => compute()}
            disabled={computing}
            className="flex items-center gap-1.5 bg-blue-600 hover:bg-blue-500 disabled:opacity-50 text-white px-4 py-2 rounded text-sm font-semibold"
          >
            <Play className={clsx('w-3.5 h-3.5', computing && 'animate-pulse')} />
            {computing ? 'Computing…' : 'Compute'}
          </button>
        </div>
      </div>

      {/* Backend down notice */}
      {backendDown && (
        <div className="bg-red-900/20 border border-red-700/40 rounded-xl p-4 text-red-400 flex items-center gap-2 text-sm">
          <AlertTriangle className="w-4 h-4 shrink-0" />
          Backend unreachable — check that the FastAPI server is running on port 8000.
        </div>
      )}

      {/* Compute error */}
      {computeError && (
        <div className="bg-red-900/20 border border-red-700/40 rounded-xl p-3 text-red-400 text-sm flex items-center gap-2">
          <AlertTriangle className="w-4 h-4 shrink-0" />
          {String(computeError)}
        </div>
      )}

      {/* History picker */}
      {snapshots.length > 1 && (
        <div className="flex items-center gap-2 flex-wrap">
          <Database className="w-3.5 h-3.5 text-slate-500" />
          <span className="text-xs text-slate-500">History:</span>
          <button
            onClick={() => setActiveSnap(null)}
            className={clsx('text-xs px-2 py-1 rounded', !activeSnap ? 'bg-blue-900/40 text-blue-400 border border-blue-700/40' : 'bg-dark-700 text-slate-500 hover:text-slate-300')}
          >
            Latest
          </button>
          {snapshots.slice(1).map((s: any) => (
            <button
              key={s.id}
              onClick={() => {
                fetch(`/api/var/snapshots/${s.id}`).then(r => r.json()).then(d => setActiveSnap(d.full_result))
              }}
              className={clsx('text-xs px-2 py-1 rounded',
                activeSnap?.snapshot_id === s.id
                  ? 'bg-violet-900/40 text-violet-400 border border-violet-700/40'
                  : 'bg-dark-700 text-slate-500 hover:text-slate-300')}
            >
              {s.computed_at?.slice(5, 16).replace('T', ' ')}
            </button>
          ))}
        </div>
      )}

      {/* Empty / loading state */}
      {loadingLatest && !displayedResult && (
        <div className="text-center py-16 text-slate-600">Loading latest snapshot…</div>
      )}

      {!loadingLatest && !displayedResult && !backendDown && (
        <IdleState onCompute={() => compute()} computing={computing} />
      )}

      {/* ── Results ── */}
      {varData && portfolio && (
        <>
          {/* Portfolio summary strip */}
          <div className="flex gap-4 flex-wrap text-xs">
            {[
              { label: 'Positions', val: String(portfolio.n_positions) },
              { label: 'Notionnel', val: `${portfolio.total_notional_eur.toLocaleString('fr-FR', { maximumFractionDigits: 0 })} €` },
              { label: 'Confidence', val: `${portfolio.confidence_pct}%` },
              { label: 'Lookback', val: `${portfolio.lookback_days}d` },
              { label: 'Source', val: portfolio.data_source === 'simulated' ? '⚠ Simulated' : '✓ Live' },
            ].map(({ label, val }) => (
              <div key={label} className="bg-dark-800 border border-slate-700/30 rounded-lg px-3 py-2">
                <div className="text-slate-500">{label}</div>
                <div className="text-white font-semibold">{val}</div>
              </div>
            ))}
          </div>

          {/* 3 VaR method cards */}
          <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
            <MetricCard
              label="Historical" method="Empirical percentile"
              var1d={varData.historical.var_1d_pct} varNd={varData.historical.var_nd_pct}
              cvar={varData.historical.cvar_pct}
              varEur={varData.historical.var_1d_eur} cvarEur={varData.historical.cvar_eur}
              horizon={horizon} colorClass="border-blue-700/40"
            />
            <MetricCard
              label="Parametric" method="Normal distribution"
              var1d={varData.parametric.var_1d_pct} varNd={varData.parametric.var_nd_pct}
              cvar={varData.parametric.cvar_pct}
              varEur={varData.parametric.var_1d_eur} cvarEur={varData.parametric.cvar_eur}
              horizon={horizon} colorClass="border-violet-700/40"
            />
            <MetricCard
              label="Monte Carlo" method="Stressed vol ×1.5"
              var1d={varData.monte_carlo.var_1d_pct} varNd={varData.monte_carlo.var_nd_pct}
              cvar={varData.monte_carlo.cvar_pct}
              varEur={varData.monte_carlo.var_1d_eur} cvarEur={varData.monte_carlo.cvar_eur}
              horizon={horizon} colorClass="border-orange-700/40" stressed
            />
          </div>

          {/* Charts */}
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
            {/* Histogram */}
            <div className="bg-dark-800 border border-slate-700/40 rounded-xl p-4">
              <div className="flex items-center gap-2 mb-3">
                <Activity className="w-4 h-4 text-slate-400" />
                <h3 className="text-sm font-semibold text-white">Return Distribution</h3>
                <span className="text-[10px] text-slate-600 ml-auto">red line = hist. VaR</span>
              </div>
              {histogram.length > 0 ? (
                <ResponsiveContainer width="100%" height={210}>
                  <BarChart data={histogram} margin={{ top: 2, right: 4, left: -22, bottom: 0 }}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                    <XAxis dataKey="x" tick={{ fontSize: 9, fill: '#64748b' }} />
                    <YAxis tick={{ fontSize: 9, fill: '#64748b' }} />
                    <Tooltip content={<HistoTooltip />} />
                    <ReferenceLine x={histVarThreshold} stroke="#f87171" strokeDasharray="4 2" strokeWidth={1.5} />
                    <Bar dataKey="count" radius={[2, 2, 0, 0]}>
                      {histogram.map((e: any, i: number) => (
                        <Cell key={i} fill={e.x < histVarThreshold ? '#ef4444' : '#3b82f6'} fillOpacity={0.7} />
                      ))}
                    </Bar>
                  </BarChart>
                </ResponsiveContainer>
              ) : (
                <div className="h-[210px] flex items-center justify-center text-slate-600 text-sm">No data</div>
              )}
            </div>

            {/* Rolling VaR */}
            <div className="bg-dark-800 border border-slate-700/40 rounded-xl p-4">
              <div className="flex items-center gap-2 mb-3">
                <TrendingDown className="w-4 h-4 text-red-400" />
                <h3 className="text-sm font-semibold text-white">Rolling VaR 95% (30d window)</h3>
              </div>
              {rolling.length > 0 ? (
                <ResponsiveContainer width="100%" height={210}>
                  <LineChart data={rolling} margin={{ top: 2, right: 4, left: -22, bottom: 0 }}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                    <XAxis dataKey="date" tick={{ fontSize: 8, fill: '#64748b' }}
                      tickFormatter={d => d.slice(5)} interval={Math.floor(rolling.length / 5)} />
                    <YAxis tick={{ fontSize: 9, fill: '#64748b' }} unit="%" />
                    <Tooltip content={<RollingTooltip />} />
                    <ReferenceLine y={0} stroke="#475569" />
                    <Line type="monotone" dataKey="var_95" stroke="#f87171" dot={false} strokeWidth={2} />
                  </LineChart>
                </ResponsiveContainer>
              ) : (
                <div className="h-[210px] flex items-center justify-center text-slate-600 text-sm">Insufficient history</div>
              )}
            </div>
          </div>

          {/* Positions + Kupiec */}
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
            {/* Positions */}
            <div className="bg-dark-800 border border-slate-700/40 rounded-xl p-4">
              <h3 className="text-sm font-semibold text-white mb-3">Positions &amp; Deltas</h3>
              <div className="space-y-1.5">
                {positions.map((p: any, i: number) => (
                  <div key={i} className="flex items-center justify-between text-xs py-1 border-b border-slate-700/20 last:border-0">
                    <div className="min-w-0 flex-1">
                      <span className="text-white font-semibold">{p.ticker}</span>
                      <span className="text-slate-400 ml-2">{p.strategy}</span>
                      {p.pattern && <div className="text-slate-600 truncate text-[11px]">{p.pattern}</div>}
                    </div>
                    <div className="flex items-center gap-3 ml-4 shrink-0">
                      <span className={clsx('font-mono font-semibold',
                        Math.abs(p.delta) < 0.05 ? 'text-slate-500'
                          : p.delta > 0 ? 'text-emerald-400' : 'text-red-400')}>
                        Δ {p.delta > 0 ? '+' : ''}{p.delta.toFixed(3)}
                      </span>
                      <span className="text-slate-500 font-mono">
                        {p.notional.toLocaleString('fr-FR', { maximumFractionDigits: 0 })} €
                      </span>
                    </div>
                  </div>
                ))}
              </div>
            </div>

            {/* Kupiec backtest */}
            {backtest && (
              <div className="bg-dark-800 border border-slate-700/40 rounded-xl p-4">
                <h3 className="text-sm font-semibold text-white mb-3">Backtest — Kupiec Test</h3>
                <div className="space-y-2.5">
                  {[
                    { label: 'Observations', val: String(backtest.n_observations) },
                    { label: 'VaR Violations', val: String(backtest.n_breaches) },
                    { label: 'Actual rate', val: `${backtest.breach_rate_pct}%`, color: backtest.kupiec_ok ? 'text-emerald-400' : 'text-red-400' },
                    { label: 'Expected rate', val: `${backtest.expected_breach_rate_pct}%`, color: 'text-slate-300' },
                  ].map(({ label, val, color }) => (
                    <div key={label} className="flex justify-between text-sm">
                      <span className="text-slate-400">{label}</span>
                      <span className={clsx('font-semibold', color ?? 'text-white')}>{val}</span>
                    </div>
                  ))}
                  <div className={clsx('flex items-center gap-2 p-2.5 rounded-lg text-xs mt-2',
                    backtest.kupiec_ok
                      ? 'bg-emerald-900/20 border border-emerald-700/40 text-emerald-400'
                      : 'bg-red-900/20 border border-red-700/40 text-red-400')}>
                    {backtest.kupiec_ok
                      ? '✓ Model validated — violations within tolerance'
                      : '✗ Excess violations — model underestimates risk'}
                  </div>
                  <div className="text-[10px] text-slate-600">
                    Kupiec rule: actual rate ≤ {(backtest.expected_breach_rate_pct * 2).toFixed(1)}%
                  </div>
                </div>
              </div>
            )}
          </div>
        </>
      )}
    </div>
  )
}
