/**
 * Wavelength Enricher Robot
 *
 * Füllt fehlende wavelength_tx_nm / wavelength_rx_nm / connector_type
 * aus drei Quellen (Priorität absteigend):
 *   1. IEEE/MSA Lookup-Tabelle (sql/111) — deterministisch, keine Kosten
 *   2. Produktname-Regex (heuristisch, pattern-basiert)
 *   3. Quarantäne: Produkt bleibt ohne Match bis Daten vorhanden
 *
 * Kein LLM, kein Scraper, keine externen Calls — rein datenbankbasiert.
 */
import { pool } from "../utils/db";

// ── Regex-Patterns für Wellenlänge aus Produktnamen ──────────────────────────

const WAVELENGTH_PATTERNS: Array<{
  pattern: RegExp;
  tx: number;
  rx?: number;
  notes: string;
}> = [
  // BiDi explizit
  { pattern: /\b1270\s*\/\s*1330\b/i, tx: 1270, rx: 1330, notes: "BiDi 1270/1330" },
  { pattern: /\b1330\s*\/\s*1270\b/i, tx: 1330, rx: 1270, notes: "BiDi 1330/1270" },
  { pattern: /\b1310\s*\/\s*1550\b/i, tx: 1310, rx: 1550, notes: "BiDi 1310/1550" },
  { pattern: /\b1550\s*\/\s*1310\b/i, tx: 1550, rx: 1310, notes: "BiDi 1550/1310" },
  { pattern: /\b1295\s*\/\s*1310\b/i, tx: 1295, rx: 1310, notes: "BiDi CWDM" },
  // Direkte nm-Angabe
  { pattern: /\b850\s*nm\b/i,         tx: 850,              notes: "850nm explicit" },
  { pattern: /\b1310\s*nm\b/i,        tx: 1310,             notes: "1310nm explicit" },
  { pattern: /\b1550\s*nm\b/i,        tx: 1550,             notes: "1550nm explicit" },
  { pattern: /\b1270\s*nm\b/i,        tx: 1270,             notes: "1270nm explicit" },
  { pattern: /\b1330\s*nm\b/i,        tx: 1330,             notes: "1330nm explicit" },
  // DWDM Channels (C-Band ~1530-1565nm)
  { pattern: /\bDWDM\b.*\bC\d{2}\b/i, tx: 1550,            notes: "DWDM C-Band" },
  { pattern: /\bDWDM\b/i,             tx: 1550,             notes: "DWDM generic" },
  // Standard-Kurzbezeichnungen → implizite Wellenlänge
  { pattern: /\bSR4?\b/i,             tx: 850,              notes: "SR/SR4 = 850nm MMF" },
  { pattern: /\bLR4?\b/i,             tx: 1310,             notes: "LR/LR4 = 1310nm SMF" },
  { pattern: /\bER4?\b/i,             tx: 1310,             notes: "ER/ER4 = 1310nm SMF" },
  { pattern: /\bFR4?\b/i,             tx: 1310,             notes: "FR/FR4 = 1310nm SMF" },
  { pattern: /\bDR4?\b/i,             tx: 1310,             notes: "DR/DR4 = 1310nm SMF" },
  { pattern: /\bZR4?\b/i,             tx: 1550,             notes: "ZR/ZR4 = 1550nm SMF" },
];

const CONNECTOR_PATTERNS: Array<{ pattern: RegExp; connector: string }> = [
  { pattern: /\bMPO.?16\b/i,      connector: "MPO-16" },
  { pattern: /\bMPO.?12\b/i,      connector: "MPO-12" },
  { pattern: /\bMPO\b/i,          connector: "MPO-12" },  // default MPO = MPO-12
  { pattern: /\bMTP\b/i,          connector: "MPO-12" },
  { pattern: /\bCS\s*connector\b/i, connector: "CS" },
  { pattern: /\bSN\s*connector\b/i, connector: "SN" },
  { pattern: /\bRJ.?45\b/i,       connector: "RJ45" },
  { pattern: /\bbase.?t\b/i,      connector: "RJ45" },
  { pattern: /\bSC\b/i,           connector: "SC" },
  { pattern: /\bLC\b/i,           connector: "LC" },      // LC zuletzt (häufig im Text)
];

// DAC/AOC haben keinen Fiber-Connector
const DAC_AOC_PATTERN = /\bDAC\b|\bAOC\b|\btwinax\b/i;

function extractWavelengthFromName(name: string): { tx: number; rx?: number; notes: string } | null {
  for (const p of WAVELENGTH_PATTERNS) {
    if (p.pattern.test(name)) {
      return { tx: p.tx, rx: p.rx, notes: p.notes };
    }
  }
  return null;
}

function extractConnectorFromName(name: string): string | null {
  if (DAC_AOC_PATTERN.test(name)) return "DAC/AOC";
  for (const p of CONNECTOR_PATTERNS) {
    if (p.pattern.test(name)) return p.connector;
  }
  return null;
}

export async function runWavelengthEnricher(): Promise<void> {
  console.log("=== Wavelength Enricher Robot ===");

  // Alle Transceivers mit fehlenden Pflichtfeldern
  const { rows: transceivers } = await pool.query<{
    id: string;
    standard_name: string;
    part_number: string;
    form_factor: string;
    speed_gbps: number;
    fiber_type: string;
    reach_meters: number;
    wavelength_tx_nm: number | null;
    wavelength_rx_nm: number | null;
    connector_type: string | null;
  }>(`
    SELECT id, standard_name, part_number, form_factor, speed_gbps,
           fiber_type, reach_meters, wavelength_tx_nm, wavelength_rx_nm, connector_type
    FROM transceivers
    WHERE enrichment_needed = TRUE
    ORDER BY data_completeness DESC  -- Produkte mit mehr Daten zuerst
    LIMIT 5000
  `);

  let fromIeee = 0;
  let fromRegex = 0;
  let stillMissing = 0;

  for (const t of transceivers) {
    let txNm = t.wavelength_tx_nm;
    let rxNm = t.wavelength_rx_nm;
    let connector = t.connector_type;
    let source = "";

    // ── Quelle 1: IEEE/MSA Lookup ───────────────────────────────────────────
    if (txNm === null && t.form_factor && t.speed_gbps && t.fiber_type && t.reach_meters) {
      const { rows: ieee } = await pool.query<{
        wavelength_tx_nm: number;
        wavelength_rx_nm: number | null;
        connector_type: string;
      }>(`
        SELECT wavelength_tx_nm, wavelength_rx_nm, connector_type
        FROM ieee_wavelength_lookup
        WHERE form_factor = $1
          AND speed_gbps = $2
          AND fiber_type = $3
          AND reach_min_m <= $4
          AND reach_max_m >= $4
        LIMIT 1
      `, [t.form_factor, t.speed_gbps, t.fiber_type, t.reach_meters]);

      if (ieee.length > 0) {
        txNm = ieee[0].wavelength_tx_nm;
        rxNm = ieee[0].wavelength_rx_nm ?? null;
        if (!connector) connector = ieee[0].connector_type;
        source = "ieee_lookup";
        fromIeee++;
      }
    }

    // ── Quelle 2: Produktname-Regex ─────────────────────────────────────────
    const nameForExtraction = [t.standard_name, t.part_number].filter(Boolean).join(" ");

    if (txNm === null && nameForExtraction) {
      const extracted = extractWavelengthFromName(nameForExtraction);
      if (extracted) {
        txNm = extracted.tx;
        rxNm = extracted.rx ?? null;
        source = `regex:${extracted.notes}`;
        fromRegex++;
      }
    }

    if (connector === null && nameForExtraction) {
      const extractedConn = extractConnectorFromName(nameForExtraction);
      if (extractedConn && extractedConn !== "DAC/AOC") connector = extractedConn;
    }

    // ── Update wenn etwas gefunden ──────────────────────────────────────────
    if (txNm !== null || connector !== null) {
      await pool.query(`
        UPDATE transceivers SET
          wavelength_tx_nm = COALESCE($1, wavelength_tx_nm),
          wavelength_rx_nm = COALESCE($2, wavelength_rx_nm),
          connector_type   = COALESCE($3, connector_type),
          updated_at       = NOW()
        WHERE id = $4
      `, [txNm, rxNm, connector, t.id]);
    } else {
      stillMissing++;
    }
  }

  console.log(`  IEEE Lookup:    ${fromIeee} enriched`);
  console.log(`  Regex Extract:  ${fromRegex} enriched`);
  console.log(`  Still missing:  ${stillMissing} (Quarantäne bis Daten verfügbar)`);
  console.log("=== Wavelength Enricher Complete ===");
}
