import { useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { useDetections } from '../hooks/useDetections';
import DataTable, { Column } from './ui/DataTable';
import { InfoTip } from './ui/Tooltip';
import { TIPS } from './ui/tooltips';
import { formatDate, formatDateOnly, formatTimeOnly } from '../utils/dateUtils';

type SortField = 'detected_at' | 'threat_level' | 'anomaly_score' | 'src_ip' | 'country_code' | 'asn_number' | 'host' | 'hits' | 'hit_velocity';
type SortOrder = 'asc' | 'desc';

interface ColumnConfig {
  key: string;
  label: string;
  visible: boolean;
  sortable: boolean;
}

interface DetectionRow {
  src_ip: string;
  ja4?: string;
  host?: string;
  client_headers?: string;
  model_name: string;
  anomaly_score: number;
  threat_level?: string;
  bot_name?: string;
  hits?: number;
  hit_velocity?: number;
  asn_org?: string;
  asn_number?: string | number;
  asn_score?: number | null;
  asn_rep_label?: string;
  country_code?: string;
  detected_at: string;
  first_seen?: string;
  last_seen?: string;
  unique_ja4s?: string[];
  unique_hosts?: string[];
  unique_client_headers?: string[];
  anubis_bot_name?: string;
  anubis_bot_action?: string;
  anubis_bot_category?: string;
}

export function DetectionsList() {
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();

  const page = parseInt(searchParams.get('page') || '1');
  const modelName = searchParams.get('model_name') || undefined;
  const search = searchParams.get('search') || undefined;
  const sortField = (searchParams.get('sort_by') || searchParams.get('sort') || 'detected_at') as SortField;
  const sortOrder = (searchParams.get('sort_order') || searchParams.get('order') || 'desc') as SortOrder;
  const scoreType = searchParams.get('score_type') || undefined;

  const [groupByIP, setGroupByIP] = useState(true);

  const { data, loading, error } = useDetections({
    page,
    page_size: 25,
    model_name: modelName,
    search,
    sort_by: sortField,
    sort_order: sortOrder,
    group_by_ip: groupByIP,
    score_type: scoreType,
  });

  const [searchInput, setSearchInput] = useState(search || '');
  const [showColumnSelector, setShowColumnSelector] = useState(false);
  const [columns, setColumns] = useState<ColumnConfig[]>([
    { key: 'ip_ja4', label: 'IP / JA4', visible: true, sortable: true },
    { key: 'host', label: 'Host', visible: true, sortable: true },
    { key: 'client_headers', label: 'Client Headers', visible: false, sortable: false },
    { key: 'model_name', label: 'Modèle', visible: true, sortable: true },
    { key: 'anomaly_score', label: 'Score', visible: true, sortable: true },
    { key: 'anubis', label: '🤖 Anubis', visible: true, sortable: false },
    { key: 'hits', label: 'Hits', visible: true, sortable: true },
    { key: 'hit_velocity', label: 'Velocity', visible: true, sortable: true },
    { key: 'asn', label: 'ASN', visible: true, sortable: true },
    { key: 'country', label: 'Pays', visible: true, sortable: true },
    { key: 'detected_at', label: 'Date', visible: true, sortable: true },
  ]);

  const handleSearch = (e: React.FormEvent) => {
    e.preventDefault();
    const newParams = new URLSearchParams(searchParams);
    if (searchInput.trim()) {
      newParams.set('search', searchInput.trim());
    } else {
      newParams.delete('search');
    }
    newParams.set('page', '1');
    setSearchParams(newParams);
  };

  const handleFilterChange = (key: string, value: string) => {
    const newParams = new URLSearchParams(searchParams);
    if (value) {
      newParams.set(key, value);
    } else {
      newParams.delete(key);
    }
    newParams.set('page', '1');
    setSearchParams(newParams);
  };

  const toggleColumn = (key: string) => {
    setColumns(cols => cols.map(col => 
      col.key === key ? { ...col, visible: !col.visible } : col
    ));
  };

  const handlePageChange = (newPage: number) => {
    const newParams = new URLSearchParams(searchParams);
    newParams.set('page', newPage.toString());
    setSearchParams(newParams);
  };

  const handleSort = (key: string, dir: 'asc' | 'desc') => {
    const newParams = new URLSearchParams(searchParams);
    newParams.set('sort_by', key);
    newParams.set('sort_order', dir);
    newParams.set('page', '1');
    setSearchParams(newParams);
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center h-64">
        <div className="text-text-secondary">Chargement...</div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="bg-threat-critical_bg border border-threat-critical rounded-lg p-4">
        <p className="text-threat-critical">Erreur: {error.message}</p>
      </div>
    );
  }

  if (!data) return null;

  // Backend handles grouping — data is already grouped when groupByIP=true
  const processedData = data;

  // Build DataTable columns from visible column configs
  const tableColumns: Column<DetectionRow>[] = columns
    .filter((col) => col.visible)
    .map((col): Column<DetectionRow> => {
      switch (col.key) {
        case 'ip_ja4':
          return {
            key: 'src_ip',
            label: col.label,
            sortable: true,
            render: (_, row) => (
              <div>
                <div className="font-mono text-sm text-text-primary">{row.src_ip}</div>
                {groupByIP && row.unique_ja4s && row.unique_ja4s.length > 0 ? (
                  <div className="mt-1 space-y-1">
                    <div className="text-xs text-text-secondary font-medium">
                      {row.unique_ja4s.length} JA4{row.unique_ja4s.length > 1 ? 's' : ''} unique{row.unique_ja4s.length > 1 ? 's' : ''}
                    </div>
                    {row.unique_ja4s.slice(0, 3).map((ja4, idx) => (
                      <div key={idx} className="font-mono text-xs text-text-secondary break-all whitespace-normal">
                        {ja4}
                      </div>
                    ))}
                    {row.unique_ja4s.length > 3 && (
                      <div className="font-mono text-xs text-text-disabled">
                        +{row.unique_ja4s.length - 3} autre{row.unique_ja4s.length - 3 > 1 ? 's' : ''}
                      </div>
                    )}
                  </div>
                ) : (
                  <div className="font-mono text-xs text-text-secondary break-all whitespace-normal">
                    {row.ja4 || '-'}
                  </div>
                )}
              </div>
            ),
          };
        case 'host':
          return {
            key: 'host',
            label: col.label,
            sortable: true,
            render: (_, row) =>
              groupByIP && row.unique_hosts && row.unique_hosts.length > 0 ? (
                <div className="space-y-1">
                  <div className="text-xs text-text-secondary font-medium">
                    {row.unique_hosts.length} Host{row.unique_hosts.length > 1 ? 's' : ''} unique{row.unique_hosts.length > 1 ? 's' : ''}
                  </div>
                  {row.unique_hosts.slice(0, 3).map((host, idx) => (
                    <div key={idx} className="text-sm text-text-primary break-all whitespace-normal max-w-md">
                      {host}
                    </div>
                  ))}
                  {row.unique_hosts.length > 3 && (
                    <div className="text-xs text-text-disabled">
                      +{row.unique_hosts.length - 3} autre{row.unique_hosts.length - 3 > 1 ? 's' : ''}
                    </div>
                  )}
                </div>
              ) : (
                <div className="text-sm text-text-primary break-all whitespace-normal max-w-md">
                  {row.host || '-'}
                </div>
              ),
          };
        case 'client_headers':
          return {
            key: 'client_headers',
            label: col.label,
            sortable: false,
            render: (_, row) =>
              groupByIP && row.unique_client_headers && row.unique_client_headers.length > 0 ? (
                <div className="space-y-1">
                  <div className="text-xs text-text-secondary font-medium">
                    {row.unique_client_headers.length} Header{row.unique_client_headers.length > 1 ? 's' : ''} unique{row.unique_client_headers.length > 1 ? 's' : ''}
                  </div>
                  {row.unique_client_headers.slice(0, 3).map((header, idx) => (
                    <div key={idx} className="text-xs text-text-primary break-all whitespace-normal font-mono">
                      {header}
                    </div>
                  ))}
                  {row.unique_client_headers.length > 3 && (
                    <div className="text-xs text-text-disabled">
                      +{row.unique_client_headers.length - 3} autre{row.unique_client_headers.length - 3 > 1 ? 's' : ''}
                    </div>
                  )}
                </div>
              ) : (
                <div className="text-xs text-text-primary break-all whitespace-normal font-mono">
                  {row.client_headers || '-'}
                </div>
              ),
          };
        case 'model_name':
          return {
            key: 'model_name',
            label: col.label,
            sortable: true,
            render: (_, row) => <ModelBadge model={row.model_name} />,
          };
        case 'anubis':
          return {
            key: 'anubis_bot_name',
            label: (
              <span className="inline-flex items-center gap-1">
                🤖 Anubis
                <InfoTip content={TIPS.anubis_identification} />
              </span>
            ),
            sortable: false,
            render: (_, row) => {
              const name = row.anubis_bot_name;
              const action = row.anubis_bot_action;
              const category = row.anubis_bot_category;
              if (!name) return <span className="text-text-disabled text-xs">—</span>;
              const actionColor =
                action === 'ALLOW' ? 'bg-green-500/15 text-green-400 border-green-500/30' :
                action === 'DENY'  ? 'bg-red-500/15 text-red-400 border-red-500/30' :
                                     'bg-yellow-500/15 text-yellow-400 border-yellow-500/30';
              return (
                <div className="space-y-0.5">
                  <div className={`inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded border ${actionColor}`}>
                    <span className="font-medium">{name}</span>
                  </div>
                  <div className="flex gap-1 flex-wrap">
                    {action && <span className="text-[10px] text-text-secondary">{action}</span>}
                    {category && <span className="text-[10px] text-text-disabled">· {category}</span>}
                  </div>
                </div>
              );
            },
          };
        case 'anomaly_score':
          return {
            key: 'anomaly_score',
            label: col.label,
            sortable: true,
            align: 'right' as const,
            render: (_, row) => (
              <ScoreBadge
                score={row.anomaly_score}
                threatLevel={row.threat_level}
                botName={row.bot_name}
                anubisAction={row.anubis_bot_action}
              />
            ),
          };
        case 'hits':
          return {
            key: 'hits',
            label: col.label,
            sortable: true,
            align: 'right' as const,
            render: (_, row) => (
              <div className="text-sm text-text-primary font-medium">{row.hits ?? 0}</div>
            ),
          };
        case 'hit_velocity':
          return {
            key: 'hit_velocity',
            label: col.label,
            sortable: true,
            align: 'right' as const,
            render: (_, row) => (
              <div
                className={`text-sm font-medium ${
                  row.hit_velocity && row.hit_velocity > 10
                    ? 'text-threat-high'
                    : row.hit_velocity && row.hit_velocity > 1
                    ? 'text-threat-medium'
                    : 'text-text-primary'
                }`}
              >
                {row.hit_velocity ? row.hit_velocity.toFixed(2) : '0.00'}
                <span className="text-xs text-text-secondary ml-1">req/s</span>
              </div>
            ),
          };
        case 'asn':
          return {
            key: 'asn_org',
            label: col.label,
            sortable: true,
            render: (_, row) => (
              <div>
                <div className="text-sm text-text-primary">{row.asn_org || row.asn_number || '-'}</div>
                {row.asn_number && (
                  <div className="text-xs text-text-secondary">AS{row.asn_number}</div>
                )}
                <AsnRepBadge score={row.asn_score} label={row.asn_rep_label} />
              </div>
            ),
          };
        case 'country':
          return {
            key: 'country_code',
            label: col.label,
            sortable: true,
            align: 'center' as const,
            render: (_, row) =>
              row.country_code ? (
                <span className="text-lg">{getFlag(row.country_code)}</span>
              ) : (
                <span>-</span>
              ),
          };
        case 'detected_at':
          return {
            key: 'detected_at',
            label: col.label,
            sortable: true,
            render: (_, row) =>
              groupByIP && row.first_seen ? (() => {
                const first = new Date(row.first_seen!);
                const last = new Date(row.last_seen!);
                const sameTime = first.getTime() === last.getTime();
                const fmt = (d: Date) => formatDate(d.toISOString());
                return sameTime ? (
                  <div className="text-xs text-text-secondary">{fmt(last)}</div>
                ) : (
                  <div className="space-y-1">
                    <div className="text-xs text-text-secondary">
                      <span className="font-medium">Premier:</span> {fmt(first)}
                    </div>
                    <div className="text-xs text-text-secondary">
                      <span className="font-medium">Dernier:</span> {fmt(last)}
                    </div>
                  </div>
                );
              })() : (
                <>
                  <div className="text-sm text-text-primary">
                    {formatDateOnly(row.detected_at)}
                  </div>
                  <div className="text-xs text-text-secondary">
                    {formatTimeOnly(row.detected_at)}
                  </div>
                </>
              ),
          };
        default:
          return { key: col.key, label: col.label, sortable: col.sortable };
      }
    });

  return (
    <div className="space-y-4 animate-fade-in">
      {/* En-tête */}
      <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
        <div className="flex items-center gap-4">
          <h1 className="text-2xl font-bold text-text-primary">Détections</h1>
          <div className="flex items-center gap-2 text-sm text-text-secondary">
            <span>{data.items.length}</span>
            <span>→</span>
            <span>{data.total} détections</span>
          </div>
        </div>

        <div className="flex gap-2">
          {/* Toggle Grouper par IP */}
          <button
            onClick={() => setGroupByIP(!groupByIP)}
            className={`border rounded-lg px-4 py-2 text-sm transition-colors ${
              groupByIP
                ? 'bg-accent-primary text-white border-accent-primary'
                : 'bg-background-card text-text-secondary border-background-card hover:text-text-primary'
            }`}
            title={groupByIP ? 'Passer en vue détections individuelles' : 'Passer en vue groupée par IP'}
          >
            {groupByIP ? '⊞ Vue : Groupé par IP' : '⊟ Vue : Individuelle'}
          </button>

          {/* Sélecteur de colonnes */}
          <div className="relative">
            <button
              onClick={() => setShowColumnSelector(!showColumnSelector)}
              className="bg-background-card hover:bg-background-card/80 border border-background-card rounded-lg px-4 py-2 text-text-primary transition-colors"
            >
              Colonnes ▾
            </button>
            
            {showColumnSelector && (
              <div className="absolute right-0 mt-2 w-48 bg-background-secondary border border-background-card rounded-lg shadow-lg z-10 p-2">
                <p className="text-xs text-text-secondary mb-2 px-2">Afficher les colonnes</p>
                {columns.map(col => (
                  <label
                    key={col.key}
                    className="flex items-center gap-2 px-2 py-1.5 hover:bg-background-card rounded cursor-pointer"
                  >
                    <input
                      type="checkbox"
                      checked={col.visible}
                      onChange={() => toggleColumn(col.key)}
                      className="rounded bg-background-card border-background-card text-accent-primary"
                    />
                    <span className="text-sm text-text-primary">{col.label}</span>
                  </label>
                ))}
              </div>
            )}
          </div>

          {/* Recherche */}
          <form onSubmit={handleSearch} className="flex gap-2">
            <input
              type="text"
              value={searchInput}
              onChange={(e) => setSearchInput(e.target.value)}
              placeholder="Rechercher IP, JA4, Host..."
              className="bg-background-card border border-background-card rounded-lg px-4 py-2 text-text-primary placeholder-text-disabled focus:outline-none focus:border-accent-primary w-64"
            />
            <button
              type="submit"
              className="bg-accent-primary hover:bg-accent-primary/80 text-white px-4 py-2 rounded-lg transition-colors"
            >
              Rechercher
            </button>
          </form>
        </div>
      </div>

      {/* Filtres */}
      <div className="bg-background-secondary rounded-lg p-4">
        <div className="flex flex-wrap gap-3 items-center">
          <select
            value={modelName || ''}
            onChange={(e) => handleFilterChange('model_name', e.target.value)}
            className="bg-background-card border border-background-card rounded-lg px-4 py-2 text-text-primary focus:outline-none focus:border-accent-primary"
          >
            <option value="">Tous modèles</option>
            <option value="Complet">Complet</option>
            <option value="Applicatif">Applicatif</option>
          </select>

          <select
            value={scoreType || ''}
            onChange={(e) => handleFilterChange('score_type', e.target.value)}
            className="bg-background-card border border-background-card rounded-lg px-4 py-2 text-text-primary focus:outline-none focus:border-accent-primary"
          >
            <option value="">Tous types de score</option>
            <option value="BOT">🟢 BOT seulement</option>
            <option value="REGLE">🔴 RÈGLE seulement</option>
            <option value="BOT_REGLE">BOT + RÈGLE</option>
            <option value="SCORE">Score numérique seulement</option>
          </select>

          {(modelName || scoreType || search || sortField !== 'detected_at') && (
            <button
              onClick={() => setSearchParams({})}
              className="bg-background-card hover:bg-background-card/80 border border-background-card rounded-lg px-4 py-2 text-text-secondary hover:text-text-primary transition-colors"
            >
              Effacer filtres
            </button>
          )}
        </div>
      </div>

      {/* Tableau */}
      <div className="bg-background-secondary rounded-lg overflow-x-auto">
        <DataTable<DetectionRow>
          data={processedData.items as DetectionRow[]}
          columns={tableColumns}
          rowKey={(row) => `${row.src_ip}-${row.detected_at}-${groupByIP ? 'g' : 'i'}`}
          defaultSortKey={sortField}
          defaultSortDir={sortOrder}
          onSort={handleSort}
          onRowClick={(row) => navigate(`/detections/ip/${encodeURIComponent(row.src_ip)}`)}
          emptyMessage="Aucune détection trouvée"
          compact
        />
      </div>

      {/* Pagination */}
      {data.total_pages > 1 && (
        <div className="flex items-center justify-between">
          <p className="text-text-secondary text-sm">
            Page {data.page} sur {data.total_pages} ({data.total} détections)
          </p>
          <div className="flex gap-2">
            <button
              onClick={() => handlePageChange(data.page - 1)}
              disabled={data.page === 1}
              className="bg-background-card hover:bg-background-card/80 disabled:opacity-50 disabled:cursor-not-allowed text-text-primary px-4 py-2 rounded-lg transition-colors"
            >
              ← Précédent
            </button>
            <button
              onClick={() => handlePageChange(data.page + 1)}
              disabled={data.page === data.total_pages}
              className="bg-background-card hover:bg-background-card/80 disabled:opacity-50 disabled:cursor-not-allowed text-text-primary px-4 py-2 rounded-lg transition-colors"
            >
              Suivant →
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

// Composant ModelBadge
function ModelBadge({ model }: { model: string }) {
  const styles: Record<string, string> = {
    Complet: 'bg-accent-primary/20 text-accent-primary',
    Applicatif: 'bg-purple-500/20 text-purple-400',
  };

  return (
    <span className={`${styles[model] || 'bg-background-card'} px-2 py-1 rounded text-xs`}>
      {model}
    </span>
  );
}

// Composant ScoreBadge
// Les scores non-IF (ANUBIS_DENY, KNOWN_BOT) sont stockés comme sentinels
// (-1.0 et 0.0) et doivent être affichés comme des badges textuels,
// pas comme des scores numériques calculés par l'IsolationForest.
function ScoreBadge({
  score,
  threatLevel,
  botName,
  anubisAction,
}: {
  score: number;
  threatLevel?: string;
  botName?: string;
  anubisAction?: string;
}) {
  // ANUBIS_DENY : menace identifiée par règle, pas par IF
  if (threatLevel === 'ANUBIS_DENY' || anubisAction === 'DENY') {
    return (
      <span className="inline-flex items-center text-xs px-1.5 py-0.5 rounded border bg-red-500/15 text-red-400 border-red-500/30 font-medium">
        RÈGLE
      </span>
    );
  }
  // KNOWN_BOT : bot légitime identifié par dictionnaire ou Anubis ALLOW
  if (threatLevel === 'KNOWN_BOT' || (botName && botName !== '')) {
    return (
      <span className="inline-flex items-center text-xs px-1.5 py-0.5 rounded border bg-green-500/15 text-green-400 border-green-500/30 font-medium">
        BOT
      </span>
    );
  }

  // Score IF réel
  let color = 'text-threat-low';
  if (score < -0.3) color = 'text-threat-critical';
  else if (score < -0.15) color = 'text-threat-high';
  else if (score < -0.05) color = 'text-threat-medium';

  return (
    <span className={`font-mono text-sm ${color}`}>
      {score.toFixed(3)}
    </span>
  );
}

// Helper pour les drapeaux
function getFlag(countryCode: string): string {
  const code = countryCode.toUpperCase();
  return code.replace(/./g, char => String.fromCodePoint(char.charCodeAt(0) + 127397));
}

// Badge de réputation ASN
function AsnRepBadge({ score, label }: { score?: number | null; label?: string }) {
  if (score == null) return null;
  let bg: string;
  let text: string;
  let display: string;
  if (score < 0.3) {
    bg = 'bg-threat-critical/20';
    text = 'text-threat-critical';
  } else if (score < 0.6) {
    bg = 'bg-threat-medium/20';
    text = 'text-threat-medium';
  } else {
    bg = 'bg-threat-low/20';
    text = 'text-threat-low';
  }
  display = label || (score < 0.3 ? 'malicious' : score < 0.6 ? 'suspect' : 'ok');
  return (
    <span className={`mt-1 inline-block text-xs px-1.5 py-0.5 rounded ${bg} ${text}`}>
      {display}
    </span>
  );
}
