'use client'

import { useState, useEffect, useCallback, useRef, useMemo } from 'react'
import type { CSSProperties } from 'react'
import dynamic from 'next/dynamic'
import type { PresentationSpec, SlideSpec, Palette } from '@/lib/types/presentation'
import { resolvePalette, resolveRadius } from '@/lib/ai/tools/slides-palettes'
import {
  BarChart, Bar, LineChart, Line, AreaChart, Area,
  PieChart, Pie, Cell, RadarChart, Radar, PolarGrid, PolarAngleAxis,
  XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer,
  FunnelChart, Funnel, LabelList,
} from 'recharts'

const MermaidDiagram = dynamic(
  () => import('./mermaid-diagram').then(m => ({ default: m.MermaidDiagram })),
  { ssr: false, loading: () => <div style={{ color: 'rgba(255,255,255,0.3)', padding: 24 }}>Chargement…</div> }
)

// ── Constants ──────────────────────────────────────────────────────────────────
const CHART_COLORS = ['#6366f1', '#22d3ee', '#f59e0b', '#ef4444', '#10b981', '#a78bfa', '#fb923c', '#14b8a6']
const TT_STYLE: CSSProperties = { background: '#1C1C1C', border: '1px solid rgba(255,255,255,0.08)', borderRadius: 8, fontSize: 12 }
const TICK = { fill: 'rgba(255,255,255,0.55)', fontSize: 11 }
const GRID_STROKE = 'rgba(255,255,255,0.07)'

// ── Chart ──────────────────────────────────────────────────────────────────────
function SlideChart({ slide }: { slide: SlideSpec }) {
  const chart = slide.chart
  if (!chart?.data?.length) return null

  const colors = (chart as any).colors ?? CHART_COLORS
  const xKey   = chart.xKey ?? 'name'
  const yKeys  = chart.yKeys ?? Object.keys(chart.data[0]).filter(k => k !== xKey)
  const legend = chart.showLegend !== false && yKeys.length > 1
  const legSt  = { fontSize: 12, color: 'rgba(255,255,255,0.6)' }

  switch (chart.type) {
    case 'bar':
      return (
        <ResponsiveContainer width="100%" height="100%">
          <BarChart data={chart.data} margin={{ top: 8, right: 24, left: 0, bottom: 4 }}>
            {chart.showGrid !== false && <CartesianGrid strokeDasharray="3 3" stroke={GRID_STROKE} />}
            <XAxis dataKey={xKey} tick={TICK} axisLine={false} tickLine={false} />
            <YAxis tick={TICK} axisLine={false} tickLine={false} width={40} />
            <Tooltip contentStyle={TT_STYLE} cursor={{ fill: 'rgba(255,255,255,0.04)' }} />
            {legend && <Legend wrapperStyle={legSt} />}
            {yKeys.map((k, i) => <Bar key={k} dataKey={k} fill={colors[i % colors.length]} radius={[4, 4, 0, 0]} maxBarSize={56} />)}
          </BarChart>
        </ResponsiveContainer>
      )
    case 'line':
      return (
        <ResponsiveContainer width="100%" height="100%">
          <LineChart data={chart.data} margin={{ top: 8, right: 24, left: 0, bottom: 4 }}>
            {chart.showGrid !== false && <CartesianGrid strokeDasharray="3 3" stroke={GRID_STROKE} />}
            <XAxis dataKey={xKey} tick={TICK} axisLine={false} tickLine={false} />
            <YAxis tick={TICK} axisLine={false} tickLine={false} width={40} />
            <Tooltip contentStyle={TT_STYLE} />
            {legend && <Legend wrapperStyle={legSt} />}
            {yKeys.map((k, i) => <Line key={k} type="monotone" dataKey={k} stroke={colors[i % colors.length]} strokeWidth={2.5} dot={{ r: 4, strokeWidth: 0 }} activeDot={{ r: 6 }} />)}
          </LineChart>
        </ResponsiveContainer>
      )
    case 'area':
      return (
        <ResponsiveContainer width="100%" height="100%">
          <AreaChart data={chart.data} margin={{ top: 8, right: 24, left: 0, bottom: 4 }}>
            {chart.showGrid !== false && <CartesianGrid strokeDasharray="3 3" stroke={GRID_STROKE} />}
            <XAxis dataKey={xKey} tick={TICK} axisLine={false} tickLine={false} />
            <YAxis tick={TICK} axisLine={false} tickLine={false} width={40} />
            <Tooltip contentStyle={TT_STYLE} />
            {legend && <Legend wrapperStyle={legSt} />}
            {yKeys.map((k, i) => <Area key={k} type="monotone" dataKey={k} stroke={colors[i % colors.length]} fill={`${colors[i % colors.length]}28`} strokeWidth={2.5} />)}
          </AreaChart>
        </ResponsiveContainer>
      )
    case 'pie':
      return (
        <ResponsiveContainer width="100%" height="100%">
          <PieChart>
            <Pie data={chart.data} dataKey={yKeys[0] ?? 'value'} nameKey={xKey} cx="50%" cy="50%" outerRadius="70%" innerRadius="35%" paddingAngle={2}>
              {chart.data.map((_, i) => <Cell key={i} fill={colors[i % colors.length]} stroke="transparent" />)}
            </Pie>
            <Tooltip contentStyle={TT_STYLE} />
            {chart.showLegend !== false && <Legend wrapperStyle={legSt} />}
          </PieChart>
        </ResponsiveContainer>
      )
    case 'radar':
      return (
        <ResponsiveContainer width="100%" height="100%">
          <RadarChart data={chart.data} cx="50%" cy="50%">
            <PolarGrid stroke="rgba(255,255,255,0.1)" />
            <PolarAngleAxis dataKey={xKey} tick={{ fill: 'rgba(255,255,255,0.65)', fontSize: 11 }} />
            {yKeys.map((k, i) => <Radar key={k} name={k} dataKey={k} stroke={colors[i % colors.length]} fill={colors[i % colors.length]} fillOpacity={0.15} />)}
            <Tooltip contentStyle={TT_STYLE} />
            {legend && <Legend wrapperStyle={legSt} />}
          </RadarChart>
        </ResponsiveContainer>
      )
    case 'stacked-bar':
      return (
        <ResponsiveContainer width="100%" height="100%">
          <BarChart data={chart.data} margin={{ top: 8, right: 24, left: 0, bottom: 4 }}>
            {chart.showGrid !== false && <CartesianGrid strokeDasharray="3 3" stroke={GRID_STROKE} />}
            <XAxis dataKey={xKey} tick={TICK} axisLine={false} tickLine={false} />
            <YAxis tick={TICK} axisLine={false} tickLine={false} width={40} />
            <Tooltip contentStyle={TT_STYLE} cursor={{ fill: 'rgba(255,255,255,0.04)' }} />
            <Legend wrapperStyle={legSt} />
            {yKeys.map((k, i) => <Bar key={k} dataKey={k} stackId="a" fill={colors[i % colors.length]} radius={i === yKeys.length - 1 ? [4, 4, 0, 0] : [0, 0, 0, 0]} />)}
          </BarChart>
        </ResponsiveContainer>
      )
    case 'combo': {
      const lineKeys = chart.lineKeys ?? (yKeys.length > 1 ? [yKeys[yKeys.length - 1]] : [])
      const barKeys = yKeys.filter(k => !lineKeys.includes(k))
      return (
        <ResponsiveContainer width="100%" height="100%">
          <BarChart data={chart.data} margin={{ top: 8, right: 24, left: 0, bottom: 4 }}>
            {chart.showGrid !== false && <CartesianGrid strokeDasharray="3 3" stroke={GRID_STROKE} />}
            <XAxis dataKey={xKey} tick={TICK} axisLine={false} tickLine={false} />
            <YAxis tick={TICK} axisLine={false} tickLine={false} width={40} />
            <Tooltip contentStyle={TT_STYLE} cursor={{ fill: 'rgba(255,255,255,0.04)' }} />
            <Legend wrapperStyle={legSt} />
            {barKeys.map((k, i) => <Bar key={k} dataKey={k} fill={colors[i % colors.length]} radius={[4, 4, 0, 0]} maxBarSize={56} />)}
            {lineKeys.map((k, i) => <Line key={k} type="monotone" dataKey={k} stroke={colors[(barKeys.length + i) % colors.length]} strokeWidth={2.5} dot={{ r: 4, strokeWidth: 0 }} />)}
          </BarChart>
        </ResponsiveContainer>
      )
    }
    case 'funnel':
      return (
        <ResponsiveContainer width="100%" height="100%">
          <FunnelChart>
            <Tooltip contentStyle={TT_STYLE} />
            <Funnel dataKey={yKeys[0] ?? 'value'} data={chart.data.map((d, i) => ({ ...d, fill: colors[i % colors.length] }))} isAnimationActive>
              <LabelList position="center" fill="#fff" fontSize={12} fontWeight={700} dataKey={xKey} />
            </Funnel>
          </FunnelChart>
        </ResponsiveContainer>
      )
    case 'gauge': {
      const value = chart.gaugeValue ?? (chart.data[0]?.[yKeys[0]] as number) ?? 0
      const label = chart.gaugeLabel ?? yKeys[0] ?? ''
      const max = 100
      const pct = Math.min(Math.max(value / max, 0), 1)
      const color = pct > 0.7 ? '#10b981' : pct > 0.4 ? '#f59e0b' : '#ef4444'
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
          <svg viewBox="0 0 200 120" style={{ width: '60%', maxHeight: '70%' }}>
            <path d="M 20 100 A 80 80 0 0 1 180 100" fill="none" stroke="rgba(255,255,255,0.1)" strokeWidth="16" strokeLinecap="round" />
            <path d="M 20 100 A 80 80 0 0 1 180 100" fill="none" stroke={color} strokeWidth="16" strokeLinecap="round"
              strokeDasharray={`${pct * 251.2} 251.2`} />
            <text x="100" y="90" textAnchor="middle" fill="#fff" fontSize="28" fontWeight="800">{value}%</text>
            <text x="100" y="112" textAnchor="middle" fill="rgba(255,255,255,0.5)" fontSize="11">{label}</text>
          </svg>
        </div>
      )
    }
    case 'waterfall': {
      // Render waterfall as bar chart with cumulative values + special coloring
      let cumulative = 0
      const waterfallData = chart.data.map((d, i) => {
        const val = (d[yKeys[0]] as number) ?? 0
        const start = cumulative
        cumulative += val
        return { ...d, __start: start, __end: cumulative, __delta: val, __isPositive: val >= 0, __isTotal: i === chart.data.length - 1 }
      })
      return (
        <ResponsiveContainer width="100%" height="100%">
          <BarChart data={waterfallData} margin={{ top: 8, right: 24, left: 0, bottom: 4 }}>
            {chart.showGrid !== false && <CartesianGrid strokeDasharray="3 3" stroke={GRID_STROKE} />}
            <XAxis dataKey={xKey} tick={TICK} axisLine={false} tickLine={false} />
            <YAxis tick={TICK} axisLine={false} tickLine={false} width={40} />
            <Tooltip contentStyle={TT_STYLE} />
            <Bar dataKey="__start" stackId="w" fill="transparent" />
            <Bar dataKey="__delta" stackId="w" radius={[4, 4, 0, 0]} maxBarSize={56}>
              {waterfallData.map((d, i) => <Cell key={i} fill={d.__isTotal ? colors[2] : d.__isPositive ? colors[4] : colors[3]} />)}
            </Bar>
          </BarChart>
        </ResponsiveContainer>
      )
    }
    case 'treemap': {
      // Render treemap as proportional boxes
      const total = chart.data.reduce((s, d) => s + ((d[yKeys[0]] as number) ?? 0), 0)
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexWrap: 'wrap', gap: 4, padding: 8, alignContent: 'flex-start' }}>
          {chart.data.map((d, i) => {
            const val = (d[yKeys[0]] as number) ?? 0
            const pct = total > 0 ? (val / total) * 100 : 10
            return (
              <div key={i} style={{ width: `${Math.max(pct * 2.5, 12)}%`, height: `${Math.max(pct * 1.5, 20)}%`, minWidth: 60, minHeight: 40, background: colors[i % colors.length], borderRadius: 8, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 8 }}>
                <span style={{ color: '#fff', fontSize: 11, fontWeight: 700, textAlign: 'center' }}>{d[xKey] as string}</span>
                <span style={{ color: 'rgba(255,255,255,0.7)', fontSize: 10 }}>{val}</span>
              </div>
            )
          })}
        </div>
      )
    }
    default: return null
  }
}

// ── Slide content renderer (per layout) ───────────────────────────────────────
function SlideContent({ slide, index, palette, radius }: { slide: SlideSpec; index: number; palette: Palette; radius: string }) {
  const layout = slide.layout ?? (index === 0 ? 'title' : 'content')
  const isDark = palette.isDark
  const text = isDark ? '#f1f5f9' : '#1a1a1a'
  const muted = isDark ? 'rgba(241,245,249,0.55)' : 'rgba(0,0,0,0.55)'
  const cardBg = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.04)'
  const cardBorder = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.08)'
  const accentBar: CSSProperties = { width: 48, height: 4, background: palette.accent, borderRadius: 2, marginBottom: 24, flexShrink: 0 }

  const content = slide.content ?? []

  switch (layout) {
    // ── TITLE ────────────────────────────────────────────────────────────
    case 'title':
      return (
        <div style={{ width: '100%', height: '100%', background: `linear-gradient(140deg, ${palette.primary} 0%, ${isDark ? palette.bg : palette.secondary} 100%)`, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', padding: '72px 80px', position: 'relative', overflow: 'hidden' }}>
          <div style={{ position: 'absolute', top: -100, right: -80, width: 500, height: 500, borderRadius: '50%', background: 'rgba(255,255,255,0.05)', pointerEvents: 'none' }} />
          <div style={{ position: 'absolute', bottom: -120, right: -20, width: 320, height: 320, borderRadius: '50%', border: '2px solid rgba(255,255,255,0.06)', pointerEvents: 'none' }} />
          <div style={{ position: 'absolute', top: 56, left: 80, fontSize: 11, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase' as const, color: 'rgba(255,255,255,0.4)' }}>Présentation</div>
          <div style={{ position: 'relative', zIndex: 1 }}>
            <div style={{ width: 52, height: 5, background: palette.accent, borderRadius: 3, marginBottom: 20, opacity: 0.9 }} />
            <h1 style={{ color: '#fff', fontSize: 56, fontWeight: 800, lineHeight: 1.05, letterSpacing: '-0.04em', margin: 0, maxWidth: 900 }}>{slide.title}</h1>
            {slide.subtitle && <p style={{ color: 'rgba(255,255,255,0.6)', fontSize: 20, fontWeight: 300, marginTop: 16, maxWidth: 640, lineHeight: 1.5 }}>{slide.subtitle}</p>}
          </div>
        </div>
      )

    // ── SECTION DIVIDER ─────────────────────────────────────────────────
    case 'section':
      return (
        <div style={{ width: '100%', height: '100%', background: isDark ? palette.primary : palette.primary, display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: '52px 80px', position: 'relative', overflow: 'hidden' }}>
          <div style={{ position: 'absolute', right: 40, bottom: -30, fontSize: 200, fontWeight: 900, color: 'rgba(255,255,255,0.05)', lineHeight: 1, letterSpacing: '-0.06em', userSelect: 'none' as const, pointerEvents: 'none' as const }}>
            {content[0] ?? String(index).padStart(2, '0')}
          </div>
          <span style={{ display: 'inline-block', background: 'rgba(255,255,255,0.12)', color: 'rgba(255,255,255,0.7)', fontSize: 12, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase' as const, padding: '6px 16px', borderRadius: 100, marginBottom: 20, alignSelf: 'flex-start' }}>
            Section {content[0] ?? String(index).padStart(2, '0')}
          </span>
          <h2 style={{ color: '#fff', fontSize: 44, fontWeight: 800, letterSpacing: '-0.04em', lineHeight: 1.05, margin: 0, maxWidth: 780 }}>{slide.title}</h2>
          {slide.subtitle && <p style={{ color: 'rgba(255,255,255,0.55)', fontSize: 18, marginTop: 12 }}>{slide.subtitle}</p>}
        </div>
      )

    // ── QUOTE ─────────────────────────────────────────────────────────────
    case 'quote':
      return (
        <div style={{ width: '100%', height: '100%', background: isDark ? '#0d1117' : '#1a1a2e', display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: '52px 80px', position: 'relative', overflow: 'hidden' }}>
          <div style={{ position: 'absolute', right: -10, top: -40, fontSize: 400, fontWeight: 900, color: 'rgba(255,255,255,0.03)', lineHeight: 0.7, fontFamily: 'Georgia, serif', userSelect: 'none' as const, pointerEvents: 'none' as const }}>"</div>
          <div style={{ fontSize: 80, color: palette.accent, lineHeight: 0.6, fontFamily: 'Georgia, serif', marginBottom: 16, opacity: 0.7 }}>"</div>
          <blockquote style={{ color: '#fff', fontSize: 28, fontWeight: 600, lineHeight: 1.4, letterSpacing: '-0.02em', margin: 0, maxWidth: 860, fontStyle: 'italic' }}>{slide.title}</blockquote>
          {slide.subtitle && <cite style={{ display: 'block', color: 'rgba(255,255,255,0.45)', fontSize: 14, fontStyle: 'normal', fontWeight: 600, letterSpacing: '0.1em', textTransform: 'uppercase' as const, marginTop: 28 }}>— {slide.subtitle}</cite>}
        </div>
      )

    // ── TOC ──────────────────────────────────────────────────────────────
    case 'toc':
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '56px 72px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 38, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title || 'Sommaire'}</h2>
          <div style={accentBar} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            {content.map((item, i) => (
              <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '12px 18px', borderRadius: radius, background: cardBg, border: `1px solid ${cardBorder}` }}>
                <span style={{ fontWeight: 700, fontSize: 14, letterSpacing: '0.08em', color: palette.accent, minWidth: 28 }}>{String(i + 1).padStart(2, '0')}</span>
                <span style={{ fontSize: 16, fontWeight: 500, color: text }}>{item}</span>
              </div>
            ))}
          </div>
        </div>
      )

    // ── CONTENT (bullets) ────────────────────────────────────────────────
    case 'content':
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '56px 72px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 38, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title}</h2>
          <div style={accentBar} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14, flex: 1, justifyContent: 'center' }}>
            {content.map((item, i) => (
              <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 16, padding: '4px 0' }}>
                <span style={{ width: 8, height: 8, borderRadius: '50%', background: palette.accent, marginTop: 8, flexShrink: 0 }} />
                <span style={{ fontSize: 18, lineHeight: 1.6, color: text }}>{item}</span>
              </div>
            ))}
          </div>
        </div>
      )

    // ── TWO COLUMN ──────────────────────────────────────────────────────
    case 'two-column': {
      const mid = Math.ceil(content.length / 2)
      const left = content.slice(0, mid)
      const right = content.slice(mid)
      const heads = (slide.subtitle ?? '/').split('/')
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '56px 72px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 38, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title}</h2>
          <div style={accentBar} />
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 28, flex: 1, alignContent: 'start' }}>
            {[{ items: left, head: heads[0]?.trim() || '' }, { items: right, head: heads[1]?.trim() || '' }].map(({ items, head }, col) => (
              <div key={col} style={{ display: 'flex', flexDirection: 'column', gap: 4, padding: '20px 24px', borderRadius: radius, background: cardBg, border: `1px solid ${cardBorder}` }}>
                {head && <span style={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.15em', textTransform: 'uppercase' as const, color: palette.accent, marginBottom: 12 }}>{head}</span>}
                {items.map((item, i) => (
                  <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: '6px 0' }}>
                    <span style={{ width: 6, height: 6, borderRadius: '50%', background: palette.accent, marginTop: 7, flexShrink: 0, opacity: 0.7 }} />
                    <span style={{ fontSize: 15, lineHeight: 1.55, color: text }}>{item}</span>
                  </div>
                ))}
              </div>
            ))}
          </div>
        </div>
      )
    }

    // ── CARDS ────────────────────────────────────────────────────────────
    case 'cards': {
      const items = content.slice(0, 6)
      const cols = items.length <= 2 ? 2 : items.length <= 3 ? 3 : items.length === 4 ? 2 : 3
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '56px 72px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 38, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title}</h2>
          <div style={accentBar} />
          <div style={{ display: 'grid', gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: 16, flex: 1, alignContent: 'center' }}>
            {items.map((item, i) => {
              const sep = item.search(/[:\u2014\u2013\-]/)
              const head = sep > 0 ? item.slice(0, sep).trim() : ''
              const body = sep > 0 ? item.slice(sep + 1).trim() : item
              return (
                <div key={i} style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: '20px', borderRadius: radius, background: cardBg, border: `1px solid ${cardBorder}`, position: 'relative', overflow: 'hidden' }}>
                  <span style={{ position: 'absolute', top: 10, right: 14, fontWeight: 900, fontSize: 28, color: isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.04)', lineHeight: 1 }}>{String(i + 1).padStart(2, '0')}</span>
                  <div style={{ width: 24, height: 3, background: palette.accent, borderRadius: 2 }} />
                  {head && <p style={{ margin: 0, fontSize: 15, fontWeight: 700, letterSpacing: '0.02em', color: text }}>{head}</p>}
                  <p style={{ margin: 0, fontSize: 14, lineHeight: 1.55, color: muted }}>{body}</p>
                </div>
              )
            })}
          </div>
        </div>
      )
    }

    // ── STATS ────────────────────────────────────────────────────────────
    case 'stats': {
      const items = content.slice(0, 4)
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '56px 72px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 38, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title}</h2>
          <div style={accentBar} />
          <div style={{ display: 'grid', gridTemplateColumns: `repeat(${items.length}, 1fr)`, gap: 20, flex: 1, alignContent: 'center' }}>
            {items.map((item, i) => {
              const parts = item.split(/[-–—:]/)
              const val = parts[0]?.trim() ?? item
              const lbl = parts.slice(1).join(' ').trim()
              return (
                <div key={i} style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'flex-start', padding: '28px 24px', borderRadius: radius, background: cardBg, border: `1px solid ${cardBorder}` }}>
                  <span style={{ fontSize: 42, fontWeight: 900, letterSpacing: '-0.04em', color: palette.accent, lineHeight: 1 }}>{val}</span>
                  <div style={{ width: 32, height: 3, background: palette.accent, borderRadius: 2, margin: '12px 0 10px', opacity: 0.6 }} />
                  {lbl && <span style={{ fontSize: 13, fontWeight: 600, letterSpacing: '0.1em', textTransform: 'uppercase' as const, color: muted }}>{lbl}</span>}
                </div>
              )
            })}
          </div>
        </div>
      )
    }

    // ── SUMMARY ──────────────────────────────────────────────────────────
    case 'summary':
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '56px 72px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 38, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title || 'En résumé'}</h2>
          <div style={accentBar} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12, flex: 1, justifyContent: 'center' }}>
            {content.slice(0, 6).map((item, i) => (
              <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '14px 20px', borderRadius: radius, background: cardBg, border: `1px solid ${cardBorder}` }}>
                <div style={{ width: 26, height: 26, minWidth: 26, background: palette.accent, borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 13, color: '#fff', fontWeight: 900 }}>✓</div>
                <span style={{ fontSize: 16, lineHeight: 1.45, color: text }}>{item}</span>
              </div>
            ))}
          </div>
        </div>
      )

    // ── CHART ────────────────────────────────────────────────────────────
    case 'chart':
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '48px 60px', background: isDark ? palette.bg : '#111827', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 30, fontWeight: 800, letterSpacing: '-0.04em', color: '#fff' }}>{slide.title}</h2>
          {slide.subtitle && <p style={{ margin: '6px 0 0', fontSize: 15, color: 'rgba(255,255,255,0.5)' }}>{slide.subtitle}</p>}
          <div style={{ flex: 1, marginTop: 24 }}>
            <SlideChart slide={slide} />
          </div>
        </div>
      )

    // ── DIAGRAM ──────────────────────────────────────────────────────────
    case 'diagram':
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '48px 60px', background: isDark ? palette.bg : '#111827', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 30, fontWeight: 800, letterSpacing: '-0.04em', color: '#fff' }}>{slide.title}</h2>
          {slide.subtitle && <p style={{ margin: '6px 0 0', fontSize: 15, color: 'rgba(255,255,255,0.5)' }}>{slide.subtitle}</p>}
          <div style={{ flex: 1, marginTop: 20, overflow: 'hidden', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            {slide.mermaid ? <MermaidDiagram chart={slide.mermaid} isDark={true} /> : <p style={{ color: 'rgba(255,255,255,0.3)' }}>No diagram</p>}
          </div>
        </div>
      )

    // ── IMAGE ────────────────────────────────────────────────────────────
    case 'image':
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '56px 72px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 38, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title}</h2>
          <div style={accentBar} />
          <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            {slide.imageUrl
              ? <img src={slide.imageUrl} alt={slide.title} style={{ maxHeight: '70%', maxWidth: '90%', borderRadius: radius, objectFit: 'contain' }} />
              : <div style={{ color: muted, fontSize: 14 }}>No image</div>
            }
          </div>
          {content[0] && <p style={{ margin: '12px 0 0', fontSize: 13, textAlign: 'center', color: muted }}>{content[0]}</p>}
        </div>
      )

    // ── TIMELINE ────────────────────────────────────────────────────────
    case 'timeline': {
      const items = content.slice(0, 8)
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '48px 60px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 34, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title}</h2>
          <div style={accentBar} />
          <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', position: 'relative', paddingLeft: 28 }}>
            <div style={{ position: 'absolute', left: 11, top: 0, bottom: 0, width: 2, background: `linear-gradient(to bottom, ${palette.accent}, transparent)` }} />
            {items.map((item, i) => {
              const sep = item.search(/[:\u2014\u2013]/)
              const date = sep > 0 ? item.slice(0, sep).trim() : ''
              const desc = sep > 0 ? item.slice(sep + 1).trim() : item
              return (
                <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 16, marginBottom: 16, position: 'relative' }}>
                  <div style={{ position: 'absolute', left: -22, top: 6, width: 12, height: 12, borderRadius: '50%', background: palette.accent, border: `3px solid ${isDark ? palette.bg : '#fff'}`, zIndex: 1 }} />
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 2, paddingLeft: 8 }}>
                    {date && <span style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase' as const, color: palette.accent }}>{date}</span>}
                    <span style={{ fontSize: 15, lineHeight: 1.5, color: text }}>{desc}</span>
                  </div>
                </div>
              )
            })}
          </div>
        </div>
      )
    }

    // ── KPI DASHBOARD ───────────────────────────────────────────────────
    case 'kpi-dashboard': {
      const items = content.slice(0, 6)
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '48px 60px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 34, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title}</h2>
          <div style={accentBar} />
          <div style={{ display: 'grid', gridTemplateColumns: `repeat(${items.length <= 3 ? items.length : 3}, 1fr)`, gap: 14, flex: 1, alignContent: 'center' }}>
            {items.map((item, i) => {
              // Format: "value | label | trend" or "value — label (trend)"
              const parts = item.split(/[|]/).map(s => s.trim())
              const val = parts[0] ?? item
              const lbl = parts[1] ?? ''
              const trend = parts[2] ?? ''
              const isUp = trend.includes('↑') || trend.includes('+')
              const isDown = trend.includes('↓') || trend.includes('-')
              return (
                <div key={i} style={{ display: 'flex', flexDirection: 'column', gap: 6, padding: '20px 18px', borderRadius: radius, background: cardBg, border: `1px solid ${cardBorder}` }}>
                  <span style={{ fontSize: 32, fontWeight: 900, letterSpacing: '-0.03em', color: palette.accent, lineHeight: 1 }}>{val}</span>
                  {lbl && <span style={{ fontSize: 12, fontWeight: 600, color: muted, letterSpacing: '0.05em', textTransform: 'uppercase' as const }}>{lbl}</span>}
                  {trend && <span style={{ fontSize: 12, fontWeight: 700, color: isUp ? '#10b981' : isDown ? '#ef4444' : muted }}>{trend}</span>}
                </div>
              )
            })}
          </div>
        </div>
      )
    }

    // ── DATA TABLE ──────────────────────────────────────────────────────
    case 'data-table': {
      const headers = slide.tableHeaders ?? (content[0]?.split('|').map(s => s.trim()) ?? [])
      const rows = slide.tableRows ?? content.slice(headers === slide.tableHeaders ? 0 : 1).map(row => row.split('|').map(s => s.trim()))
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '48px 60px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 34, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title}</h2>
          <div style={accentBar} />
          <div style={{ flex: 1, overflow: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
              {headers.length > 0 && (
                <thead>
                  <tr>
                    {headers.map((h, i) => (
                      <th key={i} style={{ padding: '10px 14px', borderBottom: `2px solid ${palette.accent}`, textAlign: 'left', fontWeight: 700, fontSize: 11, letterSpacing: '0.1em', textTransform: 'uppercase' as const, color: palette.accent }}>{h}</th>
                    ))}
                  </tr>
                </thead>
              )}
              <tbody>
                {rows.map((row, ri) => (
                  <tr key={ri} style={{ background: ri % 2 === 0 ? 'transparent' : cardBg }}>
                    {row.map((cell, ci) => (
                      <td key={ci} style={{ padding: '10px 14px', borderBottom: `1px solid ${cardBorder}`, color: text, lineHeight: 1.4 }}>{cell}</td>
                    ))}
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )
    }

    // ── DEFAULT ──────────────────────────────────────────────────────────
    default:
      return (
        <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', padding: '56px 72px', textAlign: 'left' }}>
          <h2 style={{ margin: 0, fontSize: 38, fontWeight: 800, letterSpacing: '-0.04em', color: text }}>{slide.title}</h2>
          <div style={accentBar} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14, flex: 1, justifyContent: 'center' }}>
            {content.map((item, i) => (
              <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 16, padding: '4px 0' }}>
                <span style={{ width: 8, height: 8, borderRadius: '50%', background: palette.accent, marginTop: 8, flexShrink: 0 }} />
                <span style={{ fontSize: 18, lineHeight: 1.6, color: text }}>{item}</span>
              </div>
            ))}
          </div>
        </div>
      )
  }
}

// ── Normalize slide formats (adapter) ──────────────────────────────────────────
function normalizeSlide(slide: any, index: number): SlideSpec {
  if (!slide) return { title: '', content: [], layout: 'content' }
  if (Array.isArray(slide.content) && slide.layout !== undefined) {
    return slide as SlideSpec
  }

  const type = slide.type ?? (index === 0 ? 'title' : 'content')
  switch (type) {
    case 'title':
      return {
        title: slide.title ?? '',
        subtitle: slide.subtitle,
        content: [],
        layout: 'title',
        notes: slide.notes
      }
    case 'bullets':
      return {
        title: slide.title ?? '',
        content: slide.items ?? [],
        layout: 'content',
        notes: slide.notes
      }
    case 'chart':
      return {
        title: slide.title ?? '',
        subtitle: slide.subtitle,
        content: [],
        layout: 'chart',
        chart: {
          type: slide.chartType ?? 'bar',
          // Normalize {label,value} → {name,value} so recharts xKey='name' works
          data: (slide.data ?? []).map((d: any) => ({
            name: d.label ?? d.name ?? '',
            value: typeof d.value === 'number' ? d.value : Number(d.value) || 0,
          })),
          xKey: 'name',
          yKeys: ['value'],
        },
        notes: slide.notes
      }
    case 'stats':
      return {
        title: slide.title ?? '',
        content: (slide.stats ?? []).map((s: any) => `${s.value} - ${s.label}`),
        layout: 'stats',
        notes: slide.notes
      }
    case 'table':
      return {
        title: slide.title ?? '',
        content: [],
        tableHeaders: slide.headers ?? [],
        tableRows: slide.rows ?? [],
        layout: 'data-table',
        notes: slide.notes
      }
    case 'cards':
      return {
        title: slide.title ?? '',
        content: (slide.cards ?? []).map((c: any) => `${c.title} : ${c.description}`),
        layout: 'cards',
        notes: slide.notes
      }
    case 'timeline':
      return {
        title: slide.title ?? '',
        content: (slide.events ?? []).map((e: any) => `${e.date} : ${e.title}${e.description ? ' — ' + e.description : ''}`),
        layout: 'timeline',
        notes: slide.notes
      }
    case 'quote':
      return {
        title: slide.quote ?? '',
        subtitle: slide.author ? `— ${slide.author}${slide.context ? ' (' + slide.context + ')' : ''}` : '',
        content: [],
        layout: 'quote',
        notes: slide.notes
      }
    case 'comparison':
      return {
        title: slide.title ?? '',
        subtitle: `${slide.left?.title ?? ''} / ${slide.right?.title ?? ''}`,
        content: [...(slide.left?.points ?? []), ...(slide.right?.points ?? [])],
        layout: 'two-column',
        notes: slide.notes
      }
    case 'equation':
      return {
        title: slide.title ?? '',
        subtitle: slide.explanation,
        content: (slide.equations ?? []).map((eq: any) => `${eq.latex}${eq.label ? ' — ' + eq.label : ''}`),
        layout: 'content',
        notes: slide.notes
      }
    case 'image':
      return {
        title: slide.title ?? '',
        imageUrl: slide.url,
        content: slide.caption ? [slide.caption] : [],
        layout: 'image',
        notes: slide.notes
      }
    case 'summary':
      return {
        title: slide.title ?? '',
        content: slide.items ?? [],
        layout: 'summary',
        notes: slide.notes
      }
    default:
      return {
        title: slide.title ?? '',
        content: slide.content ?? [],
        layout: 'content',
        subtitle: slide.subtitle,
        imageUrl: slide.imageUrl,
        notes: slide.notes,
        chart: slide.chart,
        mermaid: slide.mermaid,
        tableHeaders: slide.tableHeaders,
        tableRows: slide.tableRows
      }
  }
}

// ══════════════════════════════════════════════════════════════════════════════
// MAIN RENDERER — Pure React + CSS transitions (no Reveal.js dependency)
// ══════════════════════════════════════════════════════════════════════════════
export interface SlidesRendererProps {
  spec: PresentationSpec
}

export function SlidesRenderer({ spec }: SlidesRendererProps) {
  const [current, setCurrent] = useState(0)
  const [showNotes, setShowNotes] = useState(false)
  const containerRef = useRef<HTMLDivElement>(null)

  const normalizedSlides = useMemo(() => {
    return (spec.slides ?? []).map((slide, i) => normalizeSlide(slide, i))
  }, [spec.slides])

  const total = normalizedSlides.length
  const { palette } = resolvePalette(spec)
  const radius = resolveRadius(spec.style)
  const isDark = palette.isDark

  const next = useCallback(() => setCurrent(c => Math.min(c + 1, total - 1)), [total])
  const prev = useCallback(() => setCurrent(c => Math.max(c - 1, 0)), [])

  // Keyboard + touch navigation
  useEffect(() => {
    const el = containerRef.current
    if (!el) return

    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'ArrowRight' || e.key === ' ' || e.key === 'Enter') { e.preventDefault(); next() }
      if (e.key === 'ArrowLeft' || e.key === 'Backspace') { e.preventDefault(); prev() }
      if (e.key === 'n' || e.key === 'N') { e.preventDefault(); setShowNotes(n => !n) }
    }

    let startX = 0
    const onTouchStart = (e: TouchEvent) => { startX = e.touches[0].clientX }
    const onTouchEnd = (e: TouchEvent) => {
      const diff = e.changedTouches[0].clientX - startX
      if (Math.abs(diff) > 50) { diff < 0 ? next() : prev() }
    }

    el.addEventListener('keydown', onKey)
    el.addEventListener('touchstart', onTouchStart, { passive: true })
    el.addEventListener('touchend', onTouchEnd, { passive: true })
    el.focus()
    return () => {
      el.removeEventListener('keydown', onKey)
      el.removeEventListener('touchstart', onTouchStart)
      el.removeEventListener('touchend', onTouchEnd)
    }
  }, [next, prev])

  // Nav button style
  const navBtn = (isLeft: boolean): CSSProperties => ({
    position: 'absolute',
    top: '50%',
    transform: 'translateY(-50%)',
    ...(isLeft ? { left: 16 } : { right: 16 }),
    zIndex: 50,
    width: 44,
    height: 44,
    borderRadius: '50%',
    border: `1px solid ${isDark ? 'rgba(255,255,255,0.15)' : 'rgba(0,0,0,0.12)'}`,
    background: isDark ? 'rgba(255,255,255,0.08)' : 'rgba(255,255,255,0.85)',
    color: isDark ? 'rgba(255,255,255,0.85)' : 'rgba(0,0,0,0.6)',
    fontSize: 20,
    cursor: 'pointer',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    backdropFilter: 'blur(8px)',
    transition: 'all 0.15s',
    userSelect: 'none' as const,
    padding: 0,
    boxShadow: isDark ? 'none' : '0 2px 8px rgba(0,0,0,0.1)',
  })

  const currentSlideNotes = normalizedSlides[current]?.notes

  return (
    <div
      ref={containerRef}
      tabIndex={0}
      style={{
        position: 'absolute', inset: 0,
        background: palette.bg,
        fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif',
        overflow: 'hidden',
        outline: 'none',
      }}
    >
      {/* Slides */}
      <div style={{ position: 'absolute', inset: 0 }}>
        {normalizedSlides.map((slide, i) => {
          const offset = i - current
          return (
            <div
              key={i}
              style={{
                position: 'absolute',
                inset: 0,
                transform: `translateX(${offset * 100}%)`,
                transition: 'transform 0.45s cubic-bezier(0.4, 0, 0.2, 1)',
                willChange: 'transform',
              }}
            >
              <SlideContent slide={slide} index={i} palette={palette} radius={radius} />
            </div>
          )
        })}
      </div>

      {/* Navigation buttons */}
      {current > 0 && (
        <button style={navBtn(true)} onClick={prev} aria-label="Précédent">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="15 18 9 12 15 6" /></svg>
        </button>
      )}
      {current < total - 1 && (
        <button style={navBtn(false)} onClick={next} aria-label="Suivant">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 6 15 12 9 18" /></svg>
        </button>
      )}

      {/* Progress bar */}
      <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 3, background: isDark ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.06)', zIndex: 40 }}>
        <div style={{ height: '100%', width: `${((current + 1) / total) * 100}%`, background: palette.accent, transition: 'width 0.4s ease', borderRadius: '0 2px 2px 0' }} />
      </div>

      {/* Presenter Speaker Notes Overlay */}
      {showNotes && currentSlideNotes && (
        <div
          style={{
            position: 'absolute',
            bottom: 24,
            left: 24,
            right: 24,
            padding: '16px 20px',
            borderRadius: radius || '12px',
            background: isDark ? 'rgba(15, 23, 42, 0.85)' : 'rgba(255, 255, 255, 0.9)',
            border: `1px solid ${isDark ? 'rgba(255, 255, 255, 0.12)' : 'rgba(0, 0, 0, 0.1)'}`,
            backdropFilter: 'blur(16px)',
            color: isDark ? '#f8fafc' : '#0f172a',
            zIndex: 100,
            boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.25), 0 8px 10px -6px rgba(0, 0, 0, 0.25)',
          }}
        >
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
            <span style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.12em', textTransform: 'uppercase', color: palette.accent }}>
              Notes de présentation
            </span>
            <button
              onClick={() => setShowNotes(false)}
              style={{ background: 'none', border: 'none', color: isDark ? '#94a3b8' : '#64748b', cursor: 'pointer', fontSize: 13, padding: 4 }}
              title="Masquer les notes"
            >
              ✕
            </button>
          </div>
          <p style={{ margin: 0, fontSize: 14, lineHeight: 1.6, fontWeight: 500 }}>
            {currentSlideNotes}
          </p>
        </div>
      )}

      {/* Controls: Slide counter & Speaker notes toggle */}
      <div style={{ position: 'absolute', bottom: 12, right: 16, zIndex: 40, display: 'flex', gap: 8 }}>
        {currentSlideNotes && (
          <button
            onClick={() => setShowNotes(!showNotes)}
            style={{
              fontSize: 11, fontWeight: 700,
              color: showNotes ? '#fff' : (isDark ? 'rgba(255,255,255,0.75)' : 'rgba(0,0,0,0.65)'),
              background: showNotes ? palette.accent : (isDark ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.05)'),
              border: `1px solid ${showNotes ? 'transparent' : (isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.08)')}`,
              padding: '4px 12px', borderRadius: 100, cursor: 'pointer',
              display: 'flex', alignItems: 'center', gap: 6, transition: 'all 0.2s',
              backdropFilter: 'blur(4px)',
            }}
            title="Bascule des notes de présentation (Raccourci: N)"
          >
            <span>📝</span>
            <span>Notes</span>
          </button>
        )}
        <div style={{ fontSize: 12, fontWeight: 600, color: isDark ? 'rgba(255,255,255,0.4)' : 'rgba(0,0,0,0.35)', background: isDark ? 'rgba(0,0,0,0.4)' : 'rgba(255,255,255,0.8)', padding: '3px 10px', borderRadius: 100, backdropFilter: 'blur(4px)', border: `1px solid ${isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.04)'}` }}>
          {current + 1} / {total}
        </div>
      </div>
    </div>
  )
}
