import { useEffect, useState, useCallback, useMemo } from 'react'
import { BarChart2, Cpu, MemoryStick, ArrowUp, ArrowDown, TrendingUp } from 'lucide-react'
import { fetchVpsStats } from '../api/client'
import Modal from './ui/Modal'
import { Skeleton } from './ui/controls'
import { formatBps, formatBytes, formatRam, formatClock } from '../lib/format'

function avg(arr) {
  if (!arr.length) return '—'
  return (arr.reduce((a, b) => a + b, 0) / arr.length).toFixed(1)
}

/** Calcule un min/max adapté à la série pour que les variations soient visibles. */
function autoRange(data, absMin = 0, absMax = 100, minRange = 8) {
  if (!data.length) return { min: absMin, max: absMax }
  const lo = Math.min(...data)
  const hi = Math.max(...data)
  const margin = Math.max((hi - lo) * 0.2, 1)
  let min = Math.max(absMin, lo - margin)
  let max = Math.min(absMax, hi + margin)
  if (max - min < minRange) {
    const mid = (min + max) / 2
    min = Math.max(absMin, mid - minRange / 2)
    max = Math.min(absMax, min + minRange)
  }
  return { min: +min.toFixed(1), max: +max.toFixed(1) }
}

// ─── SVG Sparkline ────────────────────────────────────────────────────────────

const W = 500
const P = 3

function Sparkline({ data, timestamps = [], min = 0, max = 100, color, fill, height = 60 }) {
  // Les hooks doivent précéder tout retour anticipé — sinon leur nombre change
  // entre deux rendus dès que la série passe de vide à non vide.
  const [tooltip, setTooltip] = useState(null)

  const H = height
  const range = (max - min) || 1

  const sx = (i) => P + (i / Math.max(data.length - 1, 1)) * (W - P * 2)
  const sy = (v) => H - P - (Math.max(0, Math.min(1, (v - min) / range)) * (H - P * 2))

  const handleMouseMove = (e) => {
    if (!data.length) return
    const rect = e.currentTarget.getBoundingClientRect()
    const xRatio = (e.clientX - rect.left) / rect.width
    const idx = Math.min(data.length - 1, Math.max(0, Math.round(xRatio * (data.length - 1))))
    setTooltip({ idx, value: data[idx] })
  }

  if (!data.length) {
    return (
      <div className="flex items-center justify-center text-gray-700 text-xs italic" style={{ height }}>
        En attente de données…
      </div>
    )
  }

  const linePts = data.map((v, i) => `${sx(i).toFixed(1)},${sy(v).toFixed(1)}`).join(' ')
  const areaPts = [
    `${sx(0).toFixed(1)},${(H - P).toFixed(1)}`,
    ...data.map((v, i) => `${sx(i).toFixed(1)},${sy(v).toFixed(1)}`),
    `${sx(data.length - 1).toFixed(1)},${(H - P).toFixed(1)}`,
  ].join(' ')

  return (
    <div className="relative" style={{ height }}>
      <svg
        viewBox={`0 0 ${W} ${H}`}
        preserveAspectRatio="none"
        className="w-full cursor-crosshair"
        style={{ height }}
        onMouseMove={handleMouseMove}
        onMouseLeave={() => setTooltip(null)}
        role="img"
        aria-label={`Série de ${data.length} points, de ${min}% à ${max}%`}
      >
        {[25, 50, 75].map(pct => {
          const y = sy(min + range * pct / 100)
          return (
            <line key={pct} x1={P} y1={y.toFixed(1)} x2={W - P} y2={y.toFixed(1)} stroke="#1f2937" strokeWidth="1" />
          )
        })}

        <polygon points={areaPts} fill={fill} opacity="0.2" />
        <polyline points={linePts} fill="none" stroke={color} strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round" />

        {tooltip && (
          <circle cx={sx(tooltip.idx).toFixed(1)} cy={sy(tooltip.value).toFixed(1)} r="3" fill={color} />
        )}
      </svg>

      {/* Labels min/max axe Y */}
      <div className="absolute inset-y-0 right-0 flex flex-col justify-between text-right pointer-events-none" style={{ width: 28 }}>
        <span className="text-gray-600" style={{ fontSize: 9, lineHeight: '1' }}>{max}%</span>
        <span className="text-gray-600" style={{ fontSize: 9, lineHeight: '1' }}>{min}%</span>
      </div>

      {tooltip && (
        <div
          className="absolute top-0 left-1/2 -translate-x-1/2 bg-gray-800 border border-gray-700 rounded px-2 py-0.5 text-xs text-white pointer-events-none whitespace-nowrap"
        >
          {typeof tooltip.value === 'number' ? tooltip.value.toFixed(1) : tooltip.value}%
          {timestamps[tooltip.idx] && (
            <span className="text-gray-400 ml-1.5">{formatClock(timestamps[tooltip.idx])}</span>
          )}
        </div>
      )}
    </div>
  )
}

// Dual sparkline (upload + download sur le même graphique)
function DualSparkline({ sentData, recvData, timestamps = [], height = 60 }) {
  const [tooltip, setTooltip] = useState(null)

  const H = height
  const maxVal = Math.max(...sentData, ...recvData, 1) * 1.15

  const sx = (i, len) => P + (i / Math.max(len - 1, 1)) * (W - P * 2)
  const sy = (v) => H - P - (Math.max(0, Math.min(1, v / maxVal)) * (H - P * 2))

  const mkLine = (data) => data.map((v, i) => `${sx(i, data.length).toFixed(1)},${sy(v).toFixed(1)}`).join(' ')
  const mkArea = (data) => [
    `${sx(0, data.length).toFixed(1)},${(H - P).toFixed(1)}`,
    ...data.map((v, i) => `${sx(i, data.length).toFixed(1)},${sy(v).toFixed(1)}`),
    `${sx(data.length - 1, data.length).toFixed(1)},${(H - P).toFixed(1)}`,
  ].join(' ')

  const handleMouseMove = (e) => {
    if (!sentData.length) return
    const rect = e.currentTarget.getBoundingClientRect()
    const xRatio = (e.clientX - rect.left) / rect.width
    const idx = Math.min(sentData.length - 1, Math.max(0, Math.round(xRatio * (sentData.length - 1))))
    setTooltip({ idx, sent: sentData[idx], recv: recvData[idx] })
  }

  if (!sentData.length) {
    return (
      <div className="flex items-center justify-center text-gray-700 text-xs italic" style={{ height }}>
        En attente de données…
      </div>
    )
  }

  return (
    <div className="relative" style={{ height }}>
      <svg
        viewBox={`0 0 ${W} ${H}`}
        preserveAspectRatio="none"
        className="w-full cursor-crosshair"
        style={{ height }}
        onMouseMove={handleMouseMove}
        onMouseLeave={() => setTooltip(null)}
        role="img"
        aria-label="Bande passante montante et descendante"
      >
        {[25, 50, 75].map(pct => (
          <line
            key={pct}
            x1={P} y1={sy(maxVal * pct / 100).toFixed(1)}
            x2={W - P} y2={sy(maxVal * pct / 100).toFixed(1)}
            stroke="#1f2937" strokeWidth="1"
          />
        ))}
        <polygon points={mkArea(sentData)} fill="#38bdf8" opacity="0.15" />
        <polyline points={mkLine(sentData)} fill="none" stroke="#38bdf8" strokeWidth="1.5" strokeLinejoin="round" />
        <polygon points={mkArea(recvData)} fill="#a78bfa" opacity="0.15" />
        <polyline points={mkLine(recvData)} fill="none" stroke="#a78bfa" strokeWidth="1.5" strokeLinejoin="round" />
        {tooltip && (
          <>
            <circle cx={sx(tooltip.idx, sentData.length).toFixed(1)} cy={sy(tooltip.sent).toFixed(1)} r="3" fill="#38bdf8" />
            <circle cx={sx(tooltip.idx, recvData.length).toFixed(1)} cy={sy(tooltip.recv).toFixed(1)} r="3" fill="#a78bfa" />
          </>
        )}
      </svg>
      {tooltip && (
        <div className="absolute top-0 left-1/2 -translate-x-1/2 bg-gray-800 border border-gray-700 rounded px-2 py-1 text-xs text-white pointer-events-none flex gap-3 whitespace-nowrap">
          <span className="text-sky-400">↑ {formatBps((tooltip.sent ?? 0) * 1024)}</span>
          <span className="text-violet-400">↓ {formatBps((tooltip.recv ?? 0) * 1024)}</span>
          {timestamps[tooltip.idx] && (
            <span className="text-gray-400">{formatClock(timestamps[tooltip.idx])}</span>
          )}
        </div>
      )}
    </div>
  )
}

/** Bornes temporelles sous un graphique. */
function TimeAxis({ timestamps }) {
  if (timestamps.length < 2) return null
  return (
    <div className="flex justify-between text-[10px] text-gray-600 -mt-1">
      <span>{formatClock(timestamps[0], false)}</span>
      <span>{formatClock(timestamps[timestamps.length - 1], false)}</span>
    </div>
  )
}

function StatCard({ title, icon, current, average, unit, children }) {
  return (
    <div className="bg-gray-900 border border-gray-800 rounded-xl p-4 flex flex-col gap-3">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2 text-gray-400 text-xs font-medium uppercase tracking-wide">
          {icon}
          {title}
        </div>
        {average !== undefined && (
          <span className="text-xs text-gray-600">moy. {average}{unit}</span>
        )}
      </div>
      <div className="text-2xl font-bold tabular-nums">
        {current}<span className="text-sm font-normal text-gray-500 ml-1">{unit}</span>
      </div>
      {children}
    </div>
  )
}

const DURATION_OPTIONS = [
  { label: '10 min', value: 600       },
  { label: '1 h',    value: 3_600     },
  { label: '6 h',    value: 21_600    },
  { label: '24 h',   value: 86_400    },
  { label: '7 j',    value: 604_800   },
  { label: '30 j',   value: 2_592_000 },
]

export default function StatsModal({ vpsId, vpsName, onClose }) {
  const [stats,    setStats]    = useState([])
  const [loading,  setLoading]  = useState(true)
  const [duration, setDuration] = useState(600)

  // Refresh adaptatif : 5 s pour la vue courte, 30 s pour les vues historiques
  const refreshMs = duration <= 600 ? 5_000 : 30_000

  const load = useCallback(async () => {
    try {
      const data = await fetchVpsStats(vpsId, duration)
      setStats(data)
    } catch { /* silencieux */ }
    setLoading(false)
  }, [vpsId, duration])

  // Réinit + recharge quand la durée change
  useEffect(() => {
    setLoading(true)
    setStats([])
    load()
    const id = setInterval(load, refreshMs)
    return () => clearInterval(id)
  }, [load, refreshMs])

  const last = stats[stats.length - 1]

  const series = useMemo(() => ({
    timestamps: stats.map(s => s.ts),
    cpu:        stats.map(s => s.cpu),
    ram:        stats.map(s => s.ram_percent),
    sentKB:     stats.map(s => s.net_sent_per_sec / 1024),
    recvKB:     stats.map(s => s.net_recv_per_sec / 1024),
  }), [stats])

  const cpuRange = autoRange(series.cpu, 0, 100)
  const ramRange = autoRange(series.ram, 0, 100)

  // Trafic cumulé (delta premier → dernier point)
  const sessionSent = stats.length > 1 ? Math.max(0, stats.at(-1).net_bytes_sent - stats[0].net_bytes_sent) : 0
  const sessionRecv = stats.length > 1 ? Math.max(0, stats.at(-1).net_bytes_recv - stats[0].net_bytes_recv) : 0

  const durationLabel = DURATION_OPTIONS.find(o => o.value === duration)?.label ?? ''

  return (
    <Modal
      size="lg"
      title={vpsName}
      subtitle={stats.length > 0
        ? `${stats.length} points · fenêtre ${durationLabel} · rafraîchissement ${refreshMs / 1000} s`
        : 'En attente de données…'}
      icon={<BarChart2 size={18} className="text-indigo-400 flex-shrink-0" />}
      onClose={onClose}
      bodyClassName="overflow-y-auto p-5"
    >
      {/* Sélecteur de durée */}
      <div className="flex gap-1 flex-wrap mb-5" role="group" aria-label="Fenêtre temporelle">
        {DURATION_OPTIONS.map(opt => (
          <button
            key={opt.value}
            onClick={() => setDuration(opt.value)}
            aria-pressed={duration === opt.value}
            className={`px-2.5 py-1 rounded-lg text-xs font-medium transition-colors ${
              duration === opt.value
                ? 'bg-indigo-600 text-white'
                : 'bg-gray-800 text-gray-400 hover:bg-gray-700 hover:text-gray-200'
            }`}
          >
            {opt.label}
          </button>
        ))}
      </div>

      {loading ? (
        <div className="flex flex-col gap-4" aria-busy="true">
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
            <Skeleton className="h-36" />
            <Skeleton className="h-36" />
          </div>
          <Skeleton className="h-40" />
        </div>
      ) : stats.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-16 gap-3 text-gray-600 text-sm text-center">
          <BarChart2 size={32} className="text-gray-700" />
          Aucune donnée disponible — le collecteur démarre dans quelques secondes.
        </div>
      ) : (
        <div className="flex flex-col gap-4">

          {/* CPU + RAM */}
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
            <StatCard
              title="CPU"
              icon={<Cpu size={12} />}
              current={last ? last.cpu.toFixed(1) : '—'}
              average={avg(series.cpu)}
              unit="%"
            >
              <Sparkline
                data={series.cpu}
                timestamps={series.timestamps}
                min={cpuRange.min}
                max={cpuRange.max}
                color="#818cf8"
                fill="#818cf8"
                height={56}
              />
              <TimeAxis timestamps={series.timestamps} />
            </StatCard>

            <StatCard
              title="RAM"
              icon={<MemoryStick size={12} />}
              current={last ? last.ram_percent.toFixed(1) : '—'}
              average={avg(series.ram)}
              unit="%"
            >
              <Sparkline
                data={series.ram}
                timestamps={series.timestamps}
                min={ramRange.min}
                max={ramRange.max}
                color="#34d399"
                fill="#34d399"
                height={56}
              />
              <TimeAxis timestamps={series.timestamps} />
              {last && (
                <p className="text-xs text-gray-600">
                  {formatRam(last.ram_used)} / {formatRam(last.ram_total)}
                </p>
              )}
            </StatCard>
          </div>

          {/* Bande passante */}
          <div className="bg-gray-900 border border-gray-800 rounded-xl p-4 flex flex-col gap-3">
            <div className="flex items-center justify-between flex-wrap gap-2">
              <div className="flex items-center gap-2 text-gray-400 text-xs font-medium uppercase tracking-wide">
                <TrendingUp size={12} />
                Bande passante
              </div>
              {last && (
                <div className="flex gap-4 text-xs">
                  <span className="flex items-center gap-1 text-sky-400">
                    <ArrowUp size={10} /> {formatBps(last.net_sent_per_sec)}
                  </span>
                  <span className="flex items-center gap-1 text-violet-400">
                    <ArrowDown size={10} /> {formatBps(last.net_recv_per_sec)}
                  </span>
                </div>
              )}
            </div>
            <DualSparkline
              sentData={series.sentKB}
              recvData={series.recvKB}
              timestamps={series.timestamps}
              height={64}
            />
            <TimeAxis timestamps={series.timestamps} />
            <div className="flex gap-4 text-xs text-gray-600">
              <span className="flex items-center gap-1.5">
                <span className="w-2 h-2 rounded-full bg-sky-400 inline-block" />
                Upload
              </span>
              <span className="flex items-center gap-1.5">
                <span className="w-2 h-2 rounded-full bg-violet-400 inline-block" />
                Download
              </span>
            </div>
          </div>

          {/* Trafic total session */}
          <div className="bg-gray-900 border border-gray-800 rounded-xl p-4">
            <p className="text-xs font-medium uppercase tracking-wide text-gray-500 mb-4">
              Trafic total sur la fenêtre {durationLabel}
            </p>
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
              <div className="flex items-center gap-3">
                <div className="p-2.5 rounded-xl bg-sky-500/10 flex-shrink-0">
                  <ArrowUp size={16} className="text-sky-400" />
                </div>
                <div>
                  <p className="text-lg font-bold tabular-nums">{formatBytes(sessionSent)}</p>
                  <p className="text-xs text-gray-600">Envoyés</p>
                </div>
              </div>
              <div className="flex items-center gap-3">
                <div className="p-2.5 rounded-xl bg-violet-500/10 flex-shrink-0">
                  <ArrowDown size={16} className="text-violet-400" />
                </div>
                <div>
                  <p className="text-lg font-bold tabular-nums">{formatBytes(sessionRecv)}</p>
                  <p className="text-xs text-gray-600">Reçus</p>
                </div>
              </div>
            </div>
          </div>

        </div>
      )}
    </Modal>
  )
}
