import { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import axios from 'axios'
import clsx from 'clsx'
import {
  Globe, BarChart2, Activity, Calendar,
  ArrowRight, Clock, TrendingUp, TrendingDown, Minus,
} from 'lucide-react'

const api = axios.create({ baseURL: '/api' })

function todayStr() { return new Date().toISOString().split('T')[0] }
function fmtShort(d: string) {
  return new Date(d).toLocaleDateString('fr-FR', { day: '2-digit', month: 'short' })
}
function daysSince(ref: string, start: string) {
  return Math.floor((new Date(ref).getTime() - new Date(start).getTime()) / 86_400_000)
}
function offsetDate(d: string, days: number) {
  const dt = new Date(d); dt.setDate(dt.getDate() + days)
  return dt.toISOString().split('T')[0]
}

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

interface MarketEvent {
  id: number; name: string; start_date: string; end_date: string | null
  level: string; category: string; description: string; market_impact: string
  affected_assets: string; impact_score: number
}

interface DayContext {
  ref_date: string
  events: { long: MarketEvent | null; medium: MarketEvent | null; short: MarketEvent | null }
  has_commentary: boolean
  long_commentary: string; medium_commentary: string; short_commentary: string
}

interface Quote { symbol: string; price: number; change_pct: number; name?: string }

interface MacroRegime {
  scenarios: { dominant: string; scores: Record<string, number> }
  gauges: Record<string, { value: number | null; label: string; change_pct?: number | null }>
}

interface CalEvent { title: string; date: string; importance: number; currency?: string }

// ── Config ─────────────────────────────────────────────────────────────────────

const LEVEL = {
  long: {
    label: 'Long Terme', badge: 'L',
    ring: 'border-violet-700/50', bg: 'bg-violet-950/20',
    header: 'bg-violet-950/40 border-violet-700/40',
    accent: 'text-violet-400', dot: 'bg-violet-500',
    badgeCls: 'bg-violet-800 text-violet-200',
  },
  medium: {
    label: 'Moyen Terme', badge: 'M',
    ring: 'border-blue-700/50', bg: 'bg-blue-950/20',
    header: 'bg-blue-950/40 border-blue-700/40',
    accent: 'text-blue-400', dot: 'bg-blue-500',
    badgeCls: 'bg-blue-800 text-blue-200',
  },
  short: {
    label: 'Court Terme', badge: 'C',
    ring: 'border-emerald-700/50', bg: 'bg-emerald-950/20',
    header: 'bg-emerald-950/40 border-emerald-700/40',
    accent: 'text-emerald-400', dot: 'bg-emerald-500',
    badgeCls: 'bg-emerald-800 text-emerald-200',
  },
} as const

const REGIME_LABELS: Record<string, string> = {
  risk_on: 'Risk On', risk_off: 'Risk Off', stagflation: 'Stagflation',
  goldilocks: 'Goldilocks', recession: 'Récession', reflation: 'Reflation',
  soft_landing: 'Soft Landing', desinflation: 'Désinflation', incertain: 'Incertain',
}

// Assets relevant to each temporal level — fallback to standard set
const LEVEL_ASSETS: Record<string, string[]> = {
  long:   ['SPY', 'GLD', 'USO', 'TLT'],
  medium: ['SPY', 'USO', 'GLD', 'UUP'],
  short:  ['QQQ', 'TLT', 'UUP', 'GLD'],
}

// Try to map affected_assets field to quote symbols we have
function relevantAssets(ev: MarketEvent | null, level: string): string[] {
  if (!ev) return LEVEL_ASSETS[level] ?? []
  try {
    const raw: string[] = JSON.parse(ev.affected_assets || '[]')
    const MAP: Record<string, string> = {
      SPX: 'SPY', SPY: 'SPY', QQQ: 'QQQ', NVDA: 'NVDA',
      GC: 'GLD', Gold: 'GLD', GLD: 'GLD',
      CL: 'USO', Oil: 'USO', USO: 'USO',
      NG: 'USO', TLT: 'TLT', USD: 'UUP', UUP: 'UUP',
      VIX: 'VIX', HYG: 'HYG',
    }
    const mapped = raw.map(a => MAP[a]).filter(Boolean) as string[]
    const unique = [...new Set(mapped)].slice(0, 4)
    return unique.length >= 2 ? unique : LEVEL_ASSETS[level] ?? []
  } catch { return LEVEL_ASSETS[level] ?? [] }
}

// ── Cells ──────────────────────────────────────────────────────────────────────

function AbsorptionBar({ pct }: { pct: number | null | undefined }) {
  if (pct === null || pct === undefined) return null
  const color = pct >= 80 ? 'bg-red-500' : pct >= 40 ? 'bg-yellow-500' : 'bg-emerald-500'
  const label = pct >= 80 ? 'Fully priced' : pct >= 40 ? 'Partial' : 'Not priced'
  return (
    <div className="mt-2">
      <div className="flex items-center justify-between text-xs mb-0.5">
        <span className="text-slate-600">Absorption marché</span>
        <span className={clsx('font-medium', pct >= 80 ? 'text-red-400' : pct >= 40 ? 'text-yellow-400' : 'text-emerald-400')}>
          {pct.toFixed(0)}% — {label}
        </span>
      </div>
      <div className="h-1 bg-dark-700 rounded-full overflow-hidden">
        <div className={clsx('h-1 rounded-full transition-all', color)} style={{ width: `${Math.min(100, pct)}%` }} />
      </div>
    </div>
  )
}

function CellGeo({
  ev, level, refDate,
}: {
  ev: MarketEvent | null; level: keyof typeof LEVEL; refDate: string
}) {
  const cfg = LEVEL[level]
  if (!ev) return (
    <div className="flex items-center justify-center h-full text-xs text-slate-600 italic p-3">
      Aucun événement {cfg.label.toLowerCase()} actif
    </div>
  )
  const days = daysSince(refDate, ev.start_date)
  const absorption = (ev as any).absorption_pct as number | null
  return (
    <div className="p-3 space-y-2 h-full">
      <div className={clsx('text-sm font-bold leading-tight', cfg.accent)}>{ev.name}</div>
      <div className="flex items-center gap-2 text-xs text-slate-500">
        <Clock className="w-3 h-3 shrink-0" />
        <span>{ev.start_date}</span>
        <span className={clsx('font-semibold', cfg.accent)}>J+{days}</span>
        {!ev.end_date && <span className="text-amber-500/70">en cours</span>}
      </div>
      <p className="text-xs text-slate-400 leading-relaxed line-clamp-3">{ev.description}</p>
      {ev.market_impact && (
        <p className="text-xs text-slate-600 italic line-clamp-2">{ev.market_impact}</p>
      )}
      <AbsorptionBar pct={absorption} />
    </div>
  )
}

// MA period per temporal level
const MA_PERIOD: Record<string, number> = { long: 100, medium: 20, short: 10 }

function CellMarkets({
  ev, level, quotes, maData,
}: {
  ev: MarketEvent | null; level: string; quotes: Record<string, Quote> | null
  maData: Record<string, number | null>
}) {
  // Use event's relevant_indicators if configured
  let configuredInds: { symbol: string; indicator: string; label: string }[] = []
  if (ev) {
    try { configuredInds = JSON.parse((ev as any).relevant_indicators || '[]') } catch { /**/ }
  }

  const assets = configuredInds.length >= 2
    ? configuredInds.map(i => i.symbol).slice(0, 4)
    : relevantAssets(ev, level)

  const maPeriod = MA_PERIOD[level] ?? 20
  const maLabel = `MA${maPeriod}`

  return (
    <div className="p-3 space-y-1.5 h-full">
      {/* MA context label */}
      <div className="text-xs text-slate-600 mb-1">
        {configuredInds.length >= 2 ? 'Indicateurs configurés' : `Prix spot + ${maLabel}`}
      </div>
      {assets.map(sym => {
        const q = quotes?.[sym]
        if (!q) return (
          <div key={sym} className="flex items-center justify-between py-0.5">
            <span className="text-xs text-slate-600">{sym}</span>
            <span className="text-xs text-slate-700">—</span>
          </div>
        )
        const up = q.change_pct > 0.1
        const dn = q.change_pct < -0.1
        const ma = maData[sym]
        const maVsPct = ma && q.price ? ((q.price - ma) / ma * 100) : null
        const maUp = (maVsPct ?? 0) > 0
        return (
          <div key={sym} className="py-0.5">
            <div className="flex items-center justify-between">
              <span className="text-xs text-slate-400 truncate max-w-[7rem]">{q.name || sym}</span>
              <div className="flex items-center gap-1.5 shrink-0">
                <span className="text-xs text-slate-300 tabular-nums">{q.price?.toFixed(q.price > 100 ? 1 : 2)}</span>
                <span className={clsx(
                  'text-xs flex items-center gap-0.5 tabular-nums',
                  up ? 'text-emerald-400' : dn ? 'text-red-400' : 'text-slate-500'
                )}>
                  {up ? <TrendingUp className="w-2.5 h-2.5" /> : dn ? <TrendingDown className="w-2.5 h-2.5" /> : <Minus className="w-2.5 h-2.5" />}
                  {q.change_pct > 0 ? '+' : ''}{q.change_pct?.toFixed(2)}%
                </span>
              </div>
            </div>
            {ma !== undefined && ma !== null && (
              <div className="flex items-center justify-between mt-0.5">
                <span className="text-xs text-slate-600">{maLabel} {ma.toFixed(ma > 100 ? 1 : 2)}</span>
                <span className={clsx('text-xs tabular-nums', maUp ? 'text-emerald-500/70' : 'text-red-500/70')}>
                  {maVsPct !== null ? `${maUp ? '+' : ''}${maVsPct.toFixed(1)}%` : ''}
                </span>
              </div>
            )}
          </div>
        )
      })}
    </div>
  )
}

function CellMacro({
  level, macro,
}: {
  level: keyof typeof LEVEL; macro: MacroRegime | null
}) {
  const cfg = LEVEL[level]
  const dominant = macro?.scenarios?.dominant ?? 'incertain'
  const dominantLabel = REGIME_LABELS[dominant] ?? dominant

  const scores = macro?.scenarios?.scores ?? {}
  const maxScore = Math.max(...Object.values(scores).map(Number), 1)
  const top3 = Object.entries(scores)
    .sort((a, b) => Number(b[1]) - Number(a[1]))
    .slice(0, 3)

  // Key gauge per level
  const gaugeKeys = {
    long:   ['vix', 'us10y'],
    medium: ['dxy', 'credit_spread'],
    short:  ['vix', 'dxy'],
  }[level] ?? ['vix', 'dxy']

  return (
    <div className="p-3 space-y-2.5 h-full">
      <div className={clsx('text-sm font-bold', cfg.accent)}>{dominantLabel}</div>
      <div className="space-y-1.5">
        {top3.map(([name, score]) => {
          const pct = Math.min(100, Math.round((Number(score) / maxScore) * 100))
          const label = REGIME_LABELS[name] ?? name
          return (
            <div key={name} className="flex items-center gap-2">
              <span className="text-xs text-slate-500 w-20 truncate">{label}</span>
              <div className="flex-1 bg-dark-700 rounded-full h-1.5 overflow-hidden">
                <div
                  className={clsx('h-1.5 rounded-full transition-all', cfg.dot)}
                  style={{ width: `${pct}%` }}
                />
              </div>
              <span className="text-xs text-slate-600 w-7 text-right tabular-nums">{pct}%</span>
            </div>
          )
        })}
      </div>
      <div className="flex gap-2 flex-wrap pt-1 border-t border-slate-700/20">
        {gaugeKeys.map(k => {
          const g = macro?.gauges?.[k]
          if (!g?.value) return null
          const up = (g.change_pct ?? 0) > 0
          return (
            <div key={k} className="flex items-center gap-1 bg-dark-900/40 rounded px-2 py-1">
              <span className="text-xs text-slate-500">{g.label}</span>
              <span className={clsx('text-xs font-medium tabular-nums', up ? 'text-emerald-400' : 'text-red-400')}>
                {g.value?.toFixed(g.value > 10 ? 1 : 2)}
              </span>
            </div>
          )
        })}
      </div>
    </div>
  )
}

// Calendar events filtered by EXCLUSIVE temporal horizon ranges
function calForLevel(events: CalEvent[], level: string, refDate: string): CalEvent[] {
  // Exclusive ranges so each level shows different events:
  // short  = 0-7 days ahead
  // medium = 8-30 days ahead
  // long   = 31-90 days ahead
  const ranges: Record<string, [number, number]> = {
    short:  [0,  7],
    medium: [8,  30],
    long:   [31, 90],
  }
  const [from, to] = ranges[level] ?? [0, 30]
  return events
    .filter(e => {
      const d = e.date
      return d >= offsetDate(refDate, from) && d <= offsetDate(refDate, to)
    })
    .sort((a, b) => a.date.localeCompare(b.date))
    .slice(0, 4)
}

function CellCalendar({
  level, events, refDate,
}: {
  level: keyof typeof LEVEL; events: CalEvent[] | null; refDate: string
}) {
  const cfg = LEVEL[level]
  const horizon = { long: '3 mois', medium: '1 mois', short: '7 jours' }[level]
  const items = calForLevel(events ?? [], level, refDate)

  return (
    <div className="p-3 space-y-1.5 h-full">
      <div className="text-xs text-slate-600 mb-2">Horizon {horizon}</div>
      {items.length === 0 && (
        <div className="text-xs text-slate-700 italic">Aucun événement</div>
      )}
      {items.map((ev, i) => {
        const imp = ev.importance ?? 1
        const impColor = imp >= 3 ? 'text-red-400' : imp >= 2 ? 'text-yellow-400' : 'text-slate-500'
        return (
          <div key={i} className="flex items-start gap-2">
            <span className="text-xs text-slate-600 shrink-0 w-14">{fmtShort(ev.date)}</span>
            <span className={clsx('text-xs truncate flex-1', impColor)}>
              {ev.currency && <span className="text-slate-600 mr-1">[{ev.currency}]</span>}
              {ev.title}
            </span>
            <div className="flex gap-0.5 shrink-0 mt-0.5">
              {[1, 2, 3].map(n => (
                <div key={n} className={clsx(
                  'w-1 h-1 rounded-full',
                  n <= imp
                    ? (imp >= 3 ? 'bg-red-500' : imp >= 2 ? 'bg-yellow-500' : 'bg-slate-500')
                    : 'bg-slate-700'
                )} />
              ))}
            </div>
          </div>
        )
      })}
    </div>
  )
}

// ── Temporal Row ───────────────────────────────────────────────────────────────

function TemporalRow({
  level, ev, quotes, macro, calEvents, refDate, maData,
}: {
  level: keyof typeof LEVEL
  ev: MarketEvent | null
  quotes: Record<string, Quote> | null
  macro: MacroRegime | null
  calEvents: CalEvent[] | null
  refDate: string
  maData: Record<string, number | null>
}) {
  const cfg = LEVEL[level]

  return (
    <div className={clsx('rounded-xl border overflow-hidden', cfg.ring)}>
      {/* Row header */}
      <div className={clsx('flex items-center gap-3 px-4 py-2.5 border-b', cfg.header)}>
        <span className={clsx('text-xs font-bold px-2 py-0.5 rounded', cfg.badgeCls)}>
          {cfg.badge}
        </span>
        <span className={clsx('text-sm font-semibold', cfg.accent)}>{cfg.label}</span>
        {ev && (
          <>
            <span className="text-slate-600">·</span>
            <span className="text-sm text-slate-300 font-medium">{ev.name}</span>
            <span className="text-xs text-slate-500 ml-auto flex items-center gap-1">
              <Clock className="w-3 h-3" />
              J+{daysSince(refDate, ev.start_date)} depuis {ev.start_date}
            </span>
          </>
        )}
        {!ev && (
          <span className="text-xs text-slate-600 italic ml-2">Aucun événement actif</span>
        )}
      </div>

      {/* Row body: 4 columns */}
      <div className={clsx('grid grid-cols-4 divide-x divide-slate-700/30', cfg.bg)}>
        {/* Pilier 1: Géopolitique */}
        <div className="flex flex-col">
          <div className="flex items-center gap-1.5 px-3 py-1.5 border-b border-slate-700/20">
            <Globe className="w-3 h-3 text-slate-500" />
            <span className="text-xs text-slate-500 font-medium">Géopolitique</span>
            <Link to={`/timeline?date=${refDate}`} className={clsx('ml-auto text-xs flex items-center gap-0.5 hover:opacity-100 opacity-50', cfg.accent)}>
              <ArrowRight className="w-3 h-3" />
            </Link>
          </div>
          <CellGeo ev={ev} level={level} refDate={refDate} />
        </div>

        {/* Pilier 2: Prix & Marchés */}
        <div className="flex flex-col">
          <div className="flex items-center gap-1.5 px-3 py-1.5 border-b border-slate-700/20">
            <BarChart2 className="w-3 h-3 text-slate-500" />
            <span className="text-xs text-slate-500 font-medium">Prix & Marchés</span>
            <Link to="/markets" className="ml-auto text-xs text-slate-600 hover:text-slate-400 flex items-center gap-0.5">
              <ArrowRight className="w-3 h-3" />
            </Link>
          </div>
          <CellMarkets ev={ev} level={level} quotes={quotes} maData={maData} />
        </div>

        {/* Pilier 3: Régimes Macro */}
        <div className="flex flex-col">
          <div className="flex items-center gap-1.5 px-3 py-1.5 border-b border-slate-700/20">
            <Activity className="w-3 h-3 text-slate-500" />
            <span className="text-xs text-slate-500 font-medium">Régimes Macro</span>
            <Link to="/macro" className="ml-auto text-xs text-slate-600 hover:text-slate-400 flex items-center gap-0.5">
              <ArrowRight className="w-3 h-3" />
            </Link>
          </div>
          <CellMacro level={level} macro={macro} />
        </div>

        {/* Pilier 4: Calendrier */}
        <div className="flex flex-col">
          <div className="flex items-center gap-1.5 px-3 py-1.5 border-b border-slate-700/20">
            <Calendar className="w-3 h-3 text-slate-500" />
            <span className="text-xs text-slate-500 font-medium">Calendrier</span>
            <Link to="/calendar" className="ml-auto text-xs text-slate-600 hover:text-slate-400 flex items-center gap-0.5">
              <ArrowRight className="w-3 h-3" />
            </Link>
          </div>
          <CellCalendar level={level} events={calEvents} refDate={refDate} />
        </div>
      </div>
    </div>
  )
}

// ── Main ───────────────────────────────────────────────────────────────────────

// Compute simple moving average from array of closes (most recent last)
function computeMA(closes: number[], period: number): number | null {
  if (closes.length < period) return null
  const slice = closes.slice(-period)
  return slice.reduce((a, b) => a + b, 0) / period
}

export default function ExternalSnapshot() {
  const [refDate, setRefDate] = useState(todayStr())
  const [ctx, setCtx] = useState<DayContext | null>(null)
  const [quotes, setQuotes] = useState<Record<string, Quote> | null>(null)
  const [macro, setMacro] = useState<MacroRegime | null>(null)
  const [calEvents, setCalEvents] = useState<CalEvent[] | null>(null)
  // maData[level][symbol] = MA value
  const [maData, setMaData] = useState<Record<string, Record<string, number | null>>>({
    long: {}, medium: {}, short: {},
  })

  useEffect(() => {
    api.get(`/timeline/day/${refDate}`)
      .then(r => setCtx(r.data))
      .catch(() => setCtx(null))
  }, [refDate])

  useEffect(() => {
    api.get('/market/quotes').then(r => {
      const flat: Record<string, Quote> = {}
      for (const arr of Object.values(r.data as Record<string, Quote[]>))
        for (const q of arr) flat[q.symbol] = q
      setQuotes(flat)
    }).catch(() => {})

    api.get('/market/macro-regime').then(r => setMacro(r.data)).catch(() => {})
    api.get('/geo/calendar').then(r => setCalEvents(r.data)).catch(() => {})

    // Fetch MA data for key symbols (200 days history)
    const KEY_SYMS = ['SPY', 'GLD', 'USO', 'TLT', 'UUP', 'QQQ']
    const MA_PERIODS = { long: 100, medium: 20, short: 10 }
    Promise.allSettled(
      KEY_SYMS.map(sym =>
        api.get(`/market/history/${sym}`, { params: { days: 200 } })
          .then(r => {
            const candles: { close: number }[] = Array.isArray(r.data) ? r.data : []
            const closes = candles.map(c => c.close).filter(Boolean)
            const result: Record<string, Record<string, number | null>> = {
              long: {}, medium: {}, short: {},
            }
            for (const [level, period] of Object.entries(MA_PERIODS)) {
              result[level][sym] = computeMA(closes, period as number)
            }
            return result
          })
      )
    ).then(results => {
      const merged: Record<string, Record<string, number | null>> = { long: {}, medium: {}, short: {} }
      for (const res of results) {
        if (res.status === 'fulfilled') {
          for (const level of ['long', 'medium', 'short']) {
            Object.assign(merged[level], res.value[level])
          }
        }
      }
      setMaData(merged)
    })
  }, [])

  const navigate = (days: number) => {
    const next = offsetDate(refDate, days)
    if (next <= todayStr()) setRefDate(next)
  }

  const evLong   = ctx?.events?.long   ?? null
  const evMedium = ctx?.events?.medium ?? null
  const evShort  = ctx?.events?.short  ?? null

  return (
    <div className="p-6 space-y-4 max-w-7xl mx-auto">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-xl font-bold text-white flex items-center gap-2">
            <Globe className="w-5 h-5 text-slate-400" />
            Snapshot Externe
          </h1>
          <p className="text-sm text-slate-500 mt-0.5">
            3 temporalités × 4 piliers — vision situationnelle complète
          </p>
        </div>
        <div className="flex items-center gap-2">
          <button onClick={() => navigate(-30)} className="px-2 py-1.5 text-xs text-slate-400 hover:text-white hover:bg-dark-700 rounded">-1M</button>
          <button onClick={() => navigate(-7)}  className="px-2 py-1.5 text-xs text-slate-400 hover:text-white hover:bg-dark-700 rounded">-7J</button>
          <button onClick={() => navigate(-1)}  className="px-2 py-1.5 text-xs text-slate-400 hover:text-white hover:bg-dark-700 rounded">-1J</button>
          <input
            type="date"
            value={refDate}
            min="2020-01-01"
            max={todayStr()}
            onChange={e => setRefDate(e.target.value)}
            className="bg-dark-800 border border-slate-700/40 rounded-lg px-3 py-1.5 text-sm text-white focus:outline-none focus:border-slate-500"
          />
          <button onClick={() => setRefDate(todayStr())} className="px-2 py-1.5 text-xs text-slate-400 hover:text-white hover:bg-dark-700 rounded">
            Aujourd'hui
          </button>
          <button onClick={() => navigate(1)} disabled={refDate >= todayStr()} className="px-2 py-1.5 text-xs text-slate-400 hover:text-white hover:bg-dark-700 rounded disabled:opacity-20">+1J</button>
        </div>
      </div>

      {/* Column headers */}
      <div className="grid grid-cols-4 gap-0 text-xs text-slate-600 uppercase tracking-wider px-1">
        <div className="flex items-center gap-1.5"><Globe className="w-3 h-3" /> Géopolitique</div>
        <div className="flex items-center gap-1.5"><BarChart2 className="w-3 h-3" /> Prix & Marchés</div>
        <div className="flex items-center gap-1.5"><Activity className="w-3 h-3" /> Régimes Macro</div>
        <div className="flex items-center gap-1.5"><Calendar className="w-3 h-3" /> Calendrier</div>
      </div>

      {/* 3 temporal rows */}
      <TemporalRow level="long"   ev={evLong}   quotes={quotes} macro={macro} calEvents={calEvents} refDate={refDate} maData={maData.long} />
      <TemporalRow level="medium" ev={evMedium} quotes={quotes} macro={macro} calEvents={calEvents} refDate={refDate} maData={maData.medium} />
      <TemporalRow level="short"  ev={evShort}  quotes={quotes} macro={macro} calEvents={calEvents} refDate={refDate} maData={maData.short} />

      {/* Footer links */}
      <div className="flex items-center gap-4 text-xs text-slate-600 pt-2">
        <span>Voir aussi :</span>
        {[
          ['/timeline',        'Timeline'],
          ['/specialist-desks','COT & Curves'],
          ['/geo',             'Geo Radar'],
          ['/institutional',   'Rapports'],
        ].map(([to, label]) => (
          <Link key={to} to={to} className="hover:text-slate-300 flex items-center gap-1">
            {label} <ArrowRight className="w-3 h-3" />
          </Link>
        ))}
      </div>
    </div>
  )
}
