/**
 * PivotView — Cross-entity correlation matrix
 *
 * SOC analysts add multiple IPs or JA4 fingerprints.
 * The page fetches variability data for each entity and renders a
 * comparison matrix highlighting shared values (correlations).
 *
 * Columns = entities added by the analyst
 * Rows    = attribute categories (JA4, User-Agent, Country, ASN, Subnet)
 * ★       = value shared by 2+ entities → possible campaign link
 */

import { useState, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { InfoTip } from './ui/Tooltip';
import { TIPS } from './ui/tooltips';
import { getCountryFlag } from '../utils/countryUtils';

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

type EntityType = 'ip' | 'ja4';

interface EntityCol {
  id: string;
  type: EntityType;
  value: string;
  loading: boolean;
  error: string | null;
  data: VariabilityData | null;
}

interface AttrItem {
  value: string;
  count: number;
  percentage: number;
}

interface VariabilityData {
  total_detections: number;
  unique_ips?: number;
  attributes: {
    ja4?: AttrItem[];
    user_agents?: AttrItem[];
    countries?: AttrItem[];
    asns?: AttrItem[];
    hosts?: AttrItem[];
    subnets?: AttrItem[];
  };
}

type AttrKey = keyof VariabilityData['attributes'];

const ATTR_ROWS: { key: AttrKey; label: string; icon: string; tip?: string }[] = [
  { key: 'ja4',         label: 'JA4 Fingerprint', icon: '🔐', tip: TIPS.ja4 },
  { key: 'user_agents', label: 'User-Agents',      icon: '🤖' },
  { key: 'countries',   label: 'Pays',             icon: '🌍' },
  { key: 'asns',        label: 'ASN',              icon: '🏢', tip: TIPS.asn },
  { key: 'hosts',       label: 'Hosts cibles',     icon: '🖥️' },
  { key: 'subnets',     label: 'Subnets',          icon: '🔷' },
];

const MAX_VALUES_PER_CELL = 4;

function detectType(input: string): EntityType {
  // JA4 fingerprints are ~36 chars containing letters, digits, underscores
  // IP addresses match IPv4 pattern
  if (/^\d{1,3}(\.\d{1,3}){3}$/.test(input.trim())) return 'ip';
  return 'ja4';
}

// ─── Component ────────────────────────────────────────────────────────────────

export function PivotView() {
  const navigate = useNavigate();
  const [cols, setCols] = useState<EntityCol[]>([]);
  const [input, setInput] = useState('');

  const fetchEntity = useCallback(async (col: EntityCol): Promise<EntityCol> => {
    try {
      const encoded = encodeURIComponent(col.value);
      const url = col.type === 'ip'
        ? `/api/variability/ip/${encoded}`
        : `/api/variability/ja4/${encoded}`;
      const res = await fetch(url);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data: VariabilityData = await res.json();
      return { ...col, loading: false, data };
    } catch (e) {
      return { ...col, loading: false, error: (e as Error).message };
    }
  }, []);

  const addEntity = useCallback(async () => {
    const val = input.trim();
    if (!val) return;

    // Support batch: comma-separated
    const values = val.split(/[,\s]+/).map(v => v.trim()).filter(Boolean);
    setInput('');

    for (const v of values) {
      const id = `${Date.now()}-${v}`;
      const type = detectType(v);
      const pending: EntityCol = { id, type, value: v, loading: true, error: null, data: null };
      setCols(prev => {
        if (prev.some(c => c.value === v)) return prev;
        return [...prev, pending];
      });
      const resolved = await fetchEntity(pending);
      setCols(prev => prev.map(c => c.id === id ? resolved : c));
    }
  }, [input, fetchEntity]);

  const removeCol = (id: string) => setCols(prev => prev.filter(c => c.id !== id));

  // Find shared values across all loaded cols for a given attribute key
  const getSharedValues = (key: AttrKey): Set<string> => {
    const loaded = cols.filter(c => c.data);
    if (loaded.length < 2) return new Set();
    const valueCounts = new Map<string, number>();
    for (const col of loaded) {
      const items = col.data?.attributes[key] ?? [];
      for (const item of items.slice(0, 10)) {
        valueCounts.set(item.value, (valueCounts.get(item.value) ?? 0) + 1);
      }
    }
    const shared = new Set<string>();
    valueCounts.forEach((count, val) => { if (count >= 2) shared.add(val); });
    return shared;
  };

  const sharedByKey = Object.fromEntries(
    ATTR_ROWS.map(r => [r.key, getSharedValues(r.key)])
  ) as Record<AttrKey, Set<string>>;

  const totalCorrelations = ATTR_ROWS.reduce(
    (sum, r) => sum + sharedByKey[r.key].size, 0
  );

  return (
    <div className="space-y-6 animate-fade-in">
      {/* Header */}
      <div>
        <h1 className="text-2xl font-bold text-text-primary">🔗 Pivot — Corrélation Multi-Entités</h1>
        <p className="text-text-secondary text-sm mt-1">
          Ajoutez des IPs ou JA4. Les valeurs partagées <span className="text-yellow-400 font-bold">★</span> révèlent des campagnes coordonnées.
        </p>
      </div>

      {/* Input bar */}
      <div className="flex gap-3">
        <input
          type="text"
          value={input}
          onChange={e => setInput(e.target.value)}
          onKeyDown={e => { if (e.key === 'Enter') addEntity(); }}
          placeholder="IP (ex: 1.2.3.4) ou JA4, séparés par des virgules…"
          className="flex-1 bg-background-secondary border border-background-card rounded-lg px-4 py-2.5 text-text-primary placeholder-text-disabled font-mono text-sm focus:outline-none focus:border-accent-primary"
        />
        <button
          onClick={addEntity}
          disabled={!input.trim()}
          className="px-5 py-2.5 bg-accent-primary text-white rounded-lg text-sm font-medium hover:bg-accent-primary/80 disabled:opacity-40 transition-colors"
        >
          + Ajouter
        </button>
        {cols.length > 0 && (
          <button
            onClick={() => setCols([])}
            className="px-4 py-2.5 bg-background-card text-text-secondary rounded-lg text-sm hover:text-text-primary transition-colors"
          >
            Tout effacer
          </button>
        )}
      </div>

      {/* Empty state */}
      {cols.length === 0 && (
        <div className="bg-background-secondary rounded-xl p-12 text-center space-y-3">
          <div className="text-5xl">🔗</div>
          <div className="text-lg font-medium text-text-primary">Aucune entité ajoutée</div>
          <div className="text-sm text-text-secondary max-w-md mx-auto">
            Entrez plusieurs IPs ou fingerprints JA4 pour identifier des corrélations — JA4 partagés, même pays d'origine, mêmes cibles, même ASN.
          </div>
          <div className="text-xs text-text-disabled pt-2">
            Exemple : <span className="font-mono text-text-secondary">1.2.3.4, 5.6.7.8, 9.10.11.12</span>
          </div>
        </div>
      )}

      {/* Correlation summary badge */}
      {cols.length >= 2 && cols.some(c => c.data) && (
        <div className={`flex items-center gap-3 px-4 py-3 rounded-lg border ${
          totalCorrelations > 0
            ? 'bg-yellow-500/10 border-yellow-500/30 text-yellow-400'
            : 'bg-background-secondary border-background-card text-text-secondary'
        }`}>
          <span className="text-xl">{totalCorrelations > 0 ? '⚠️' : 'ℹ️'}</span>
          <div>
            {totalCorrelations > 0 ? (
              <>
                <span className="font-bold">{totalCorrelations} corrélation{totalCorrelations > 1 ? 's' : ''} détectée{totalCorrelations > 1 ? 's' : ''}</span>
                {' '}— attributs partagés par 2+ entités. Possible campagne coordonnée.
              </>
            ) : (
              'Aucune corrélation détectée entre les entités analysées.'
            )}
          </div>
        </div>
      )}

      {/* Matrix */}
      {cols.length > 0 && (
        <div className="overflow-x-auto rounded-xl border border-background-card">
          <table className="w-full min-w-max">
            {/* Column headers */}
            <thead>
              <tr className="bg-background-secondary border-b border-background-card">
                <th className="px-4 py-3 text-left text-xs font-semibold text-text-disabled uppercase tracking-wider w-40">
                  Attribut
                </th>
                {cols.map(col => (
                  <th key={col.id} className="px-4 py-3 text-left w-56">
                    <div className="flex items-start justify-between gap-2">
                      <div>
                        <div className="flex items-center gap-1.5">
                          <span className="text-xs text-text-disabled">
                            {col.type === 'ip' ? '🌐' : '🔐'}
                          </span>
                          <button
                            onClick={() => navigate(
                              col.type === 'ip'
                                ? `/investigation/${col.value}`
                                : `/investigation/ja4/${col.value}`
                            )}
                            className="font-mono text-sm text-accent-primary hover:underline truncate max-w-[160px] text-left"
                            title={col.value}
                          >
                            {col.value.length > 20 ? col.value.slice(0, 20) + '…' : col.value}
                          </button>
                        </div>
                        {col.data && (
                          <div className="text-xs text-text-disabled mt-0.5">
                            {col.data.total_detections.toLocaleString()} det.
                            {col.type === 'ja4' && col.data.unique_ips !== undefined && (
                              <> · {col.data.unique_ips} IPs</>
                            )}
                          </div>
                        )}
                        {col.loading && (
                          <div className="text-xs text-text-disabled mt-0.5 animate-pulse">Chargement…</div>
                        )}
                        {col.error && (
                          <div className="text-xs text-red-400 mt-0.5">⚠ {col.error}</div>
                        )}
                      </div>
                      <button
                        onClick={() => removeCol(col.id)}
                        className="text-text-disabled hover:text-red-400 transition-colors text-base leading-none shrink-0 mt-0.5"
                        title="Retirer"
                      >
                        ×
                      </button>
                    </div>
                  </th>
                ))}
              </tr>
            </thead>

            {/* Attribute rows */}
            <tbody className="divide-y divide-background-card">
              {ATTR_ROWS.map(row => {
                const shared = sharedByKey[row.key];
                const hasAnyData = cols.some(c => (c.data?.attributes[row.key]?.length ?? 0) > 0);
                if (!hasAnyData && cols.every(c => c.data !== null && !c.loading)) return null;

                return (
                  <tr key={row.key} className="hover:bg-background-card/20 transition-colors">
                    <td className="px-4 py-3 align-top">
                      <div className="flex items-center gap-1.5">
                        <span>{row.icon}</span>
                        <span className="text-xs font-medium text-text-secondary">{row.label}</span>
                        {row.tip && <InfoTip content={row.tip} />}
                      </div>
                      {shared.size > 0 && (
                        <div className="mt-1">
                          <span className="text-xs bg-yellow-500/20 text-yellow-400 px-1.5 py-0.5 rounded">
                            ★ {shared.size} commun{shared.size > 1 ? 's' : ''}
                          </span>
                        </div>
                      )}
                    </td>

                    {cols.map(col => {
                      const items = col.data?.attributes[row.key] ?? [];
                      return (
                        <td key={col.id} className="px-3 py-3 align-top">
                          {col.loading ? (
                            <div className="h-16 bg-background-card/30 rounded animate-pulse" />
                          ) : items.length === 0 ? (
                            <span className="text-xs text-text-disabled">—</span>
                          ) : (
                            <div className="space-y-1.5">
                              {items.slice(0, MAX_VALUES_PER_CELL).map((item, i) => {
                                const isShared = shared.has(item.value);
                                return (
                                  <div
                                    key={i}
                                    className={`rounded px-2 py-1.5 text-xs ${
                                      isShared
                                        ? 'bg-yellow-500/15 border border-yellow-500/30'
                                        : 'bg-background-card/40'
                                    }`}
                                  >
                                    <div className="flex items-start justify-between gap-1">
                                      <div className={`font-mono break-all leading-tight ${
                                        isShared ? 'text-yellow-300' : 'text-text-primary'
                                      }`}>
                                        {isShared && <span className="mr-1 text-yellow-400">★</span>}
                                        {row.key === 'countries'
                                          ? `${getCountryFlag(item.value)} ${item.value}`
                                          : item.value.length > 60
                                          ? item.value.slice(0, 60) + '…'
                                          : item.value}
                                      </div>
                                    </div>
                                    <div className="text-text-disabled mt-0.5 flex gap-2">
                                      <span>{item.count.toLocaleString()}</span>
                                      <span>{item.percentage.toFixed(1)}%</span>
                                    </div>
                                  </div>
                                );
                              })}
                              {items.length > MAX_VALUES_PER_CELL && (
                                <div className="text-xs text-text-disabled px-2">
                                  +{items.length - MAX_VALUES_PER_CELL} autres
                                </div>
                              )}
                            </div>
                          )}
                        </td>
                      );
                    })}
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {/* Legend */}
      {cols.length >= 2 && (
        <div className="flex items-center gap-4 text-xs text-text-disabled">
          <span className="flex items-center gap-1">
            <span className="w-3 h-3 rounded bg-yellow-500/20 border border-yellow-500/30 inline-block" />
            Valeur partagée par 2+ entités ★
          </span>
          <span>|</span>
          <span>Cliquer sur une entité → Investigation complète</span>
        </div>
      )}
    </div>
  );
}
