import { useState, useEffect } from 'react';

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

interface HourlyEntry {
  hour: number;
  hits: number;
  unique_ips: number;
  max_rps: number;
}

interface TopHost {
  host: string;
  total_hits: number;
  unique_ips: number;
  unique_ja4s: number;
  hourly_hits: number[];
}

interface HeatmapMatrix {
  hosts: string[];
  matrix: number[][];
}

// ─── Helpers ──────────────────────────────────────────────────────────────────

function formatNumber(n: number): string {
  return n.toLocaleString('fr-FR');
}

function heatmapCellStyle(value: number, maxValue: number): React.CSSProperties {
  if (maxValue === 0 || value === 0) return { backgroundColor: 'transparent' };
  const ratio = value / maxValue;
  if (ratio >= 0.75) return { backgroundColor: 'rgba(239, 68, 68, 0.85)' };
  if (ratio >= 0.5) return { backgroundColor: 'rgba(168, 85, 247, 0.7)' };
  if (ratio >= 0.25) return { backgroundColor: 'rgba(59, 130, 246, 0.6)' };
  if (ratio >= 0.05) return { backgroundColor: 'rgba(96, 165, 250, 0.35)' };
  return { backgroundColor: 'rgba(147, 197, 253, 0.15)' };
}

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

function StatCard({ label, value, accent }: { label: string; value: string | number; accent?: string }) {
  return (
    <div className="bg-background-secondary rounded-lg p-4 flex flex-col gap-1 border border-border">
      <span className="text-text-secondary text-sm">{label}</span>
      <span className={`text-2xl font-bold ${accent ?? 'text-text-primary'}`}>{value}</span>
    </div>
  );
}

function LoadingSpinner() {
  return (
    <div className="flex items-center justify-center py-12">
      <div className="w-8 h-8 border-2 border-accent-primary border-t-transparent rounded-full animate-spin" />
    </div>
  );
}

function ErrorMessage({ message }: { message: string }) {
  return (
    <div className="bg-threat-critical/10 border border-threat-critical/30 rounded-lg p-4 text-threat-critical">
      ⚠️ {message}
    </div>
  );
}

// Mini sparkline for a host row
function Sparkline({ data }: { data: number[] }) {
  const max = Math.max(...data, 1);
  return (
    <div className="flex items-end gap-px" style={{ height: '24px', width: '96px' }}>
      {data.map((v, i) => {
        const pct = (v / max) * 100;
        return (
          <div
            key={i}
            style={{ height: `${Math.max(pct, 5)}%`, width: '4px' }}
            className={`rounded-sm ${pct >= 70 ? 'bg-threat-critical' : pct >= 30 ? 'bg-threat-medium' : 'bg-accent-primary/50'}`}
          />
        );
      })}
    </div>
  );
}

// ─── Main Component ───────────────────────────────────────────────────────────

export function HeatmapView() {
  const [hourly, setHourly] = useState<HourlyEntry[]>([]);
  const [hourlyLoading, setHourlyLoading] = useState(true);
  const [hourlyError, setHourlyError] = useState<string | null>(null);

  const [topHosts, setTopHosts] = useState<TopHost[]>([]);
  const [topHostsLoading, setTopHostsLoading] = useState(true);
  const [topHostsError, setTopHostsError] = useState<string | null>(null);

  const [matrixData, setMatrixData] = useState<HeatmapMatrix | null>(null);
  const [matrixLoading, setMatrixLoading] = useState(true);
  const [matrixError, setMatrixError] = useState<string | null>(null);

  useEffect(() => {
    const fetchHourly = async () => {
      try {
        const res = await fetch('/api/heatmap/hourly');
        if (!res.ok) throw new Error('Erreur chargement courbe horaire');
        const data: { hours: HourlyEntry[] } = await res.json();
        setHourly(data.hours ?? []);
      } catch (err) {
        setHourlyError(err instanceof Error ? err.message : 'Erreur inconnue');
      } finally {
        setHourlyLoading(false);
      }
    };
    const fetchTopHosts = async () => {
      try {
        const res = await fetch('/api/heatmap/top-hosts?limit=20');
        if (!res.ok) throw new Error('Erreur chargement top hosts');
        const data: { items: TopHost[] } = await res.json();
        setTopHosts(data.items ?? []);
      } catch (err) {
        setTopHostsError(err instanceof Error ? err.message : 'Erreur inconnue');
      } finally {
        setTopHostsLoading(false);
      }
    };
    const fetchMatrix = async () => {
      try {
        const res = await fetch('/api/heatmap/matrix');
        if (!res.ok) throw new Error('Erreur chargement heatmap matrix');
        const data: HeatmapMatrix = await res.json();
        setMatrixData(data);
      } catch (err) {
        setMatrixError(err instanceof Error ? err.message : 'Erreur inconnue');
      } finally {
        setMatrixLoading(false);
      }
    };
    fetchHourly();
    fetchTopHosts();
    fetchMatrix();
  }, []);

  const peakHour = hourly.reduce((best, h) => (h.hits > best.hits ? h : best), { hour: 0, hits: 0, unique_ips: 0, max_rps: 0 });
  const totalHits = hourly.reduce((s, h) => s + h.hits, 0);
  const maxHits = hourly.length > 0 ? Math.max(...hourly.map((h) => h.hits)) : 1;

  const matrixMax = matrixData
    ? Math.max(...matrixData.matrix.flatMap((row) => row), 1)
    : 1;

  const displayHosts = matrixData ? matrixData.hosts.slice(0, 15) : [];

  return (
    <div className="p-6 space-y-8 animate-fade-in">
      {/* Header */}
      <div>
        <h1 className="text-2xl font-bold text-text-primary">⏱️ Heatmap Temporelle d'Attaques</h1>
        <p className="text-text-secondary mt-1">
          Distribution horaire de l'activité malveillante par host cible.
        </p>
      </div>

      {/* Stat cards */}
      <div className="grid grid-cols-3 gap-4">
        <StatCard
          label="Heure de pic"
          value={peakHour.hits > 0 ? `${peakHour.hour}h (${formatNumber(peakHour.hits)} hits)` : '—'}
          accent="text-threat-critical"
        />
        <StatCard label="Total hits (24h)" value={formatNumber(totalHits)} accent="text-text-primary" />
        <StatCard label="Hosts ciblés" value={formatNumber(matrixData?.hosts.length ?? 0)} accent="text-threat-high" />
      </div>

      {/* Section 1: Courbe horaire */}
      <div className="bg-background-secondary rounded-lg border border-border p-6">
        <h2 className="text-text-primary font-semibold mb-4">Activité horaire — 24h</h2>
        {hourlyLoading ? (
          <LoadingSpinner />
        ) : hourlyError ? (
          <ErrorMessage message={hourlyError} />
        ) : (
          <>
            <div className="flex items-end gap-1" style={{ height: '160px' }}>
              {Array.from({ length: 24 }, (_, i) => {
                const entry = hourly.find((h) => h.hour === i) ?? { hour: i, hits: 0, unique_ips: 0, max_rps: 0 };
                const pct = maxHits > 0 ? (entry.hits / maxHits) * 100 : 0;
                return (
                  <div key={i} className="flex flex-col items-center flex-1 gap-1 h-full">
                    <div className="w-full flex flex-col justify-end flex-1">
                      <div
                        title={`${i}h: ${entry.hits} hits`}
                        style={{ height: `${Math.max(pct, 1)}%` }}
                        className={`w-full rounded-t transition-all ${
                          pct >= 70 ? 'bg-threat-critical' : pct >= 30 ? 'bg-threat-medium' : 'bg-accent-primary/60'
                        }`}
                      />
                    </div>
                    <span className="text-text-disabled text-xs">{i}</span>
                  </div>
                );
              })}
            </div>
            <div className="flex gap-4 mt-3 text-xs text-text-secondary">
              <span className="flex items-center gap-1"><span className="w-3 h-3 bg-threat-critical rounded-sm inline-block" /> Élevé (≥70%)</span>
              <span className="flex items-center gap-1"><span className="w-3 h-3 bg-threat-medium rounded-sm inline-block" /> Moyen (≥30%)</span>
              <span className="flex items-center gap-1"><span className="w-3 h-3 bg-accent-primary/60 rounded-sm inline-block" /> Faible</span>
            </div>
          </>
        )}
      </div>

      {/* Section 2: Heatmap matrix */}
      <div className="bg-background-secondary rounded-lg border border-border p-6">
        <h2 className="text-text-primary font-semibold mb-4">Heatmap Host × Heure</h2>
        {matrixLoading ? (
          <LoadingSpinner />
        ) : matrixError ? (
          <ErrorMessage message={matrixError} />
        ) : !matrixData || displayHosts.length === 0 ? (
          <p className="text-text-secondary text-sm">Aucune donnée disponible.</p>
        ) : (
          <div className="overflow-auto">
            <div className="inline-block min-w-full">
              {/* Hour headers */}
              <div className="flex" style={{ marginLeft: '180px' }}>
                {Array.from({ length: 24 }, (_, i) => (
                  <div key={i} className="text-center text-xs text-text-disabled" style={{ width: '28px', minWidth: '28px' }}>
                    {i}
                  </div>
                ))}
              </div>
              {/* Rows */}
              {displayHosts.map((host, rowIdx) => {
                const rowData = matrixData.matrix[rowIdx] ?? Array(24).fill(0);
                return (
                  <div key={host} className="flex items-center" style={{ height: '24px', marginBottom: '2px' }}>
                    <div className="text-xs text-text-secondary truncate text-right pr-2" style={{ width: '180px', minWidth: '180px' }} title={host}>
                      {host}
                    </div>
                    {Array.from({ length: 24 }, (_, h) => {
                      const val = rowData[h] ?? 0;
                      return (
                        <div
                          key={h}
                          title={`${host} ${h}h: ${val} hits`}
                          style={{
                            width: '26px',
                            minWidth: '26px',
                            height: '20px',
                            marginRight: '2px',
                            borderRadius: '2px',
                            ...heatmapCellStyle(val, matrixMax),
                          }}
                        />
                      );
                    })}
                  </div>
                );
              })}
            </div>
            <div className="flex gap-3 mt-4 text-xs text-text-secondary items-center">
              <span>Intensité :</span>
              {[
                { label: 'Nul', style: { backgroundColor: 'transparent', border: '1px solid rgba(255,255,255,0.1)' } },
                { label: 'Très faible', style: { backgroundColor: 'rgba(147, 197, 253, 0.15)' } },
                { label: 'Faible', style: { backgroundColor: 'rgba(96, 165, 250, 0.35)' } },
                { label: 'Moyen', style: { backgroundColor: 'rgba(59, 130, 246, 0.6)' } },
                { label: 'Élevé', style: { backgroundColor: 'rgba(168, 85, 247, 0.7)' } },
                { label: 'Critique', style: { backgroundColor: 'rgba(239, 68, 68, 0.85)' } },
              ].map(({ label, style }) => (
                <span key={label} className="flex items-center gap-1">
                  <span style={{ ...style, display: 'inline-block', width: '14px', height: '14px', borderRadius: '2px' }} />
                  {label}
                </span>
              ))}
            </div>
          </div>
        )}
      </div>

      {/* Section 3: Top hosts table */}
      <div className="bg-background-secondary rounded-lg border border-border overflow-hidden">
        <div className="px-6 py-4 border-b border-border">
          <h2 className="text-text-primary font-semibold">Top Hosts ciblés</h2>
        </div>
        {topHostsLoading ? (
          <LoadingSpinner />
        ) : topHostsError ? (
          <div className="p-4"><ErrorMessage message={topHostsError} /></div>
        ) : (
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-border text-text-secondary text-left">
                <th className="px-4 py-3">Host</th>
                <th className="px-4 py-3">Total hits</th>
                <th className="px-4 py-3">IPs uniques</th>
                <th className="px-4 py-3">JA4 uniques</th>
                <th className="px-4 py-3">Activité 24h</th>
              </tr>
            </thead>
            <tbody>
              {topHosts.map((h) => (
                <tr key={h.host} className="border-b border-border hover:bg-background-card transition-colors">
                  <td className="px-4 py-3 font-mono text-xs text-text-primary">{h.host}</td>
                  <td className="px-4 py-3 text-text-primary">{formatNumber(h.total_hits)}</td>
                  <td className="px-4 py-3 text-text-secondary">{formatNumber(h.unique_ips)}</td>
                  <td className="px-4 py-3 text-text-secondary">{formatNumber(h.unique_ja4s)}</td>
                  <td className="px-4 py-3">
                    <Sparkline data={h.hourly_hits ?? Array(24).fill(0)} />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}
