import { useEffect, useState, useCallback } from 'react'
import { X, BarChart2, Cpu, MemoryStick, ArrowUp, ArrowDown, TrendingUp } from 'lucide-react'
import { fetchVpsStats } from '../api/client'

// ─── Formatters ───────────────────────────────────────────────────────────────

function fmtBytes(bytes) {
  if (!bytes || bytes < 1) return '0 B'
  if (bytes < 1024)        return `${bytes.toFixed(0)} B`
  if (bytes < 1024 ** 2)   return `${(bytes / 1024).toFixed(1)} KB`
  if (bytes < 1024 ** 3)   return `${(bytes / 1024 ** 2).toFixed(1)} MB`
  return `${(bytes / 1024 ** 3).toFixed(2)} GB`
}

function fmtBps(bps) {
  if (bps === undefined || bps === null) return '—'
  if (bps < 1024)        return `${bps.toFixed(0)} B/s`
  if (bps < 1024 ** 2)   return `${(bps / 1024).toFixed(1)} KB/s`
  return `${(bps / 1024 ** 2).toFixed(2)} MB/s`
}

function fmtRam(bytes) {
  if (!bytes) return '—'
  if (bytes < 1024 ** 3) return `${(bytes / 1024 ** 2).toFixed(0)} MB`
  return `${(bytes / 1024 ** 3).toFixed(1)} GB`
}

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 ────────────────────────────────────────────────────────────

function Sparkline({ data, min = 0, max = 100, color, fill, height = 60 }) {
  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 W = 500
  const H = height
  const P = 3
  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 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(' ')

  // Hover tooltip state
  const [tooltip, setTooltip] = useState(null)

  const handleMouseMove = (e) => {
    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] })
  }

  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)}
      >
        {/* Grid lines */}
        {[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"
            />
          )
        })}

        {/* Area fill */}
        <polygon points={areaPts} fill={fill} opacity="0.2" />

        {/* Line */}
        <polyline
          points={linePts}
          fill="none"
          stroke={color}
          strokeWidth="1.5"
          strokeLinejoin="round"
          strokeLinecap="round"
        />

        {/* Hover dot */}
        {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 bubble */}
      {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"
          style={{ whiteSpace: 'nowrap' }}
        >
          {typeof tooltip.value === 'number' ? tooltip.value.toFixed(1) : tooltip.value}%
        </div>
      )}
    </div>
  )
}

// Dual sparkline (upload + download on same chart)
function DualSparkline({ sentData, recvData, height = 60 }) {
  const allValues = [...sentData, ...recvData]
  const maxVal = Math.max(...allValues, 1) * 1.15
  const W = 500, H = height, P = 3

  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 [tooltip, setTooltip] = useState(null)

  const handleMouseMove = (e) => {
    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] })
  }

  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)}
      >
        {[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 && sentData.length > 0 && (
          <>
            <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" style={{ whiteSpace: 'nowrap' }}>
          <span className="text-sky-400">↑ {fmtBps((tooltip.sent ?? 0) * 1024)}</span>
          <span className="text-violet-400">↓ {fmtBps((tooltip.recv ?? 0) * 1024)}</span>
        </div>
      )}
    </div>
  )
}

// ─── Carte de stat ────────────────────────────────────────────────────────────

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>
  )
}

// ─── Options de durée ─────────────────────────────────────────────────────────

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 },
]

// ─── Modal principal ──────────────────────────────────────────────────────────────

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]

  // Séries CPU / RAM
  const cpuData = stats.map(s => s.cpu)
  const ramData = stats.map(s => s.ram_percent)

  // Axes auto-scalés pour voir les variations même à faible charge
  const cpuRange = autoRange(cpuData, 0, 100)
  const ramRange = autoRange(ramData, 0, 100)

  // Réseau : KB/s pour l'affichage du graphique
  const sentKB = stats.map(s => s.net_sent_per_sec / 1024)
  const recvKB = stats.map(s => s.net_recv_per_sec / 1024)

  // Trafic cumulé (delta first → last)
  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 (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4">
      <div className="bg-gray-950 border border-gray-800 rounded-2xl w-full max-w-3xl max-h-[90vh] overflow-y-auto shadow-2xl">

        {/* En-tête */}
        <div className="px-5 py-3 border-b border-gray-800 sticky top-0 bg-gray-950 z-10">
          <div className="flex items-center justify-between mb-3">
            <div className="flex items-center gap-3">
              <BarChart2 size={18} className="text-indigo-400" />
              <div>
                <h2 className="font-semibold text-sm">{vpsName}</h2>
                <p className="text-xs text-gray-500">
                  {stats.length > 0
                    ? `${stats.length} points · fenêtre ${durationLabel} · rafraîchissement ${refreshMs / 1000} s`
                    : 'En attente de données…'}
                </p>
              </div>
            </div>
            <button
              onClick={onClose}
              className="p-1.5 rounded-lg hover:bg-gray-800 text-gray-500 hover:text-white transition-colors"
            >
              <X size={16} />
            </button>
          </div>

          {/* Sélecteur de durée */}
          <div className="flex gap-1 flex-wrap">
            {DURATION_OPTIONS.map(opt => (
              <button
                key={opt.value}
                onClick={() => setDuration(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>
        </div>

        {/* Contenu */}
        {loading ? (
          <div className="flex items-center justify-center py-16 text-gray-600 text-sm">
            Chargement…
          </div>
        ) : stats.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-16 gap-3 text-gray-600 text-sm">
            <BarChart2 size={32} className="text-gray-700" />
            Aucune donnée disponible — le collecteur démarre dans quelques secondes.
          </div>
        ) : (
          <div className="p-5 flex flex-col gap-4">

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

              <StatCard
                title="RAM"
                icon={<MemoryStick size={12} />}
                current={last ? last.ram_percent.toFixed(1) : '—'}
                average={avg(ramData)}
                unit="%"
              >
                <Sparkline data={ramData} min={ramRange.min} max={ramRange.max} color="#34d399" fill="#34d399" height={56} />
                {last && (
                  <p className="text-xs text-gray-600 -mt-1">
                    {fmtRam(last.ram_used)} / {fmtRam(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">
                <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} /> {fmtBps(last.net_sent_per_sec)}
                    </span>
                    <span className="flex items-center gap-1 text-violet-400">
                      <ArrowDown size={10} /> {fmtBps(last.net_recv_per_sec)}
                    </span>
                  </div>
                )}
              </div>
              <DualSparkline sentData={sentKB} recvData={recvKB} height={64} />
              <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 (depuis le début de la collecte)
              </p>
              <div className="grid 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">{fmtBytes(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">{fmtBytes(sessionRecv)}</p>
                    <p className="text-xs text-gray-600">Reçus</p>
                  </div>
                </div>
              </div>
            </div>

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