/**
 * Spec-Based Equivalence Matcher
 *
 * Matches FX products with competitor products by technical specification
 * when no OPN-based equivalence exists. Spec-matching is a fallback:
 * OPN-confirmed matches (confidence=1.0) always take priority.
 *
 * Match criteria:
 *   - Same form_factor (exact)
 *   - Same speed_gbps (exact)
 *   - Same reach tier (SR/IR/LR/ER/ZR)
 *   - Same primary wavelength within ±10nm (CWDM/WDM safe)
 *     OR both have no wavelength data (broadband products)
 *   - Max 30 competitor matches per FX product (safety cap)
 *
 * Match quality:
 *   confidence  = 0.85
 *   match_basis = '{spec}'
 *   status      = 'auto_approved'
 */

import { pool } from "../utils/db";

export interface SpecMatcherResult {
  inserted: number;
  fxProductsScanned: number;
  candidatePairs: number;
  skippedExisting: number;
}

// ── Queries ──────────────────────────────────────────────────────────────────

const INSERT_SPEC_MATCHES = `
  INSERT INTO transceiver_equivalences (
    flexoptix_id,
    competitor_id,
    confidence,
    status,
    match_basis,
    match_notes,
    created_at,
    updated_at
  )
  SELECT DISTINCT
    fx.id               AS flexoptix_id,
    comp.id             AS competitor_id,
    0.85                AS confidence,
    'auto_approved'     AS status,
    ARRAY['spec']       AS match_basis,
    'Spec match: ' || fx.form_factor || ' ' || fx.speed_gbps || 'G ' ||
      CASE WHEN fx.reach_meters <= 300   THEN 'SR'
           WHEN fx.reach_meters <= 2000  THEN 'IR'
           WHEN fx.reach_meters <= 10000 THEN 'LR'
           WHEN fx.reach_meters <= 40000 THEN 'ER'
           ELSE 'ZR' END ||
      CASE WHEN tip_extract_wavelength_nm(fx.wavelengths) IS NOT NULL
           THEN ' @' || tip_extract_wavelength_nm(fx.wavelengths) || 'nm'
           ELSE '' END AS match_notes,
    NOW()               AS created_at,
    NOW()               AS updated_at
  FROM transceivers fx
  JOIN vendors vfx ON vfx.id = fx.vendor_id AND UPPER(vfx.name) LIKE '%FLEXOPTIX%'
  JOIN transceivers comp
    ON comp.form_factor = fx.form_factor
    AND comp.speed_gbps = fx.speed_gbps
    AND comp.reach_meters >= 10
    AND tip_reach_tier(comp.reach_meters) = tip_reach_tier(fx.reach_meters)
    AND (
      (tip_extract_wavelength_nm(fx.wavelengths) IS NULL
       AND tip_extract_wavelength_nm(comp.wavelengths) IS NULL)
      OR ABS( COALESCE(tip_extract_wavelength_nm(comp.wavelengths), 0)
            - COALESCE(tip_extract_wavelength_nm(fx.wavelengths), 0) ) <= 10
    )
  JOIN vendors vcomp ON vcomp.id = comp.vendor_id AND vcomp.is_competitor = true
  WHERE fx.reach_meters >= 10
    AND fx.speed_gbps > 0
    -- OPN match already exists → skip (spec is fallback only)
    AND NOT EXISTS (
      SELECT 1 FROM transceiver_equivalences e
      WHERE e.flexoptix_id = fx.id AND 'opn' = ANY(e.match_basis)
    )
    -- Skip pairs that already have ANY equivalence
    AND NOT EXISTS (
      SELECT 1 FROM transceiver_equivalences e
      WHERE e.flexoptix_id = fx.id AND e.competitor_id = comp.id
    )
    -- Safety cap: skip if > 30 competitors would match (too generic)
    AND (
      SELECT COUNT(DISTINCT c2.id)
      FROM transceivers c2
      JOIN vendors vc2 ON vc2.id = c2.vendor_id AND vc2.is_competitor = true
      WHERE c2.form_factor = fx.form_factor
        AND c2.speed_gbps  = fx.speed_gbps
        AND c2.reach_meters >= 10
        AND tip_reach_tier(c2.reach_meters) = tip_reach_tier(fx.reach_meters)
        AND (
          (tip_extract_wavelength_nm(fx.wavelengths) IS NULL
           AND tip_extract_wavelength_nm(c2.wavelengths) IS NULL)
          OR ABS( COALESCE(tip_extract_wavelength_nm(c2.wavelengths), 0)
                - COALESCE(tip_extract_wavelength_nm(fx.wavelengths), 0) ) <= 10
        )
    ) <= 30
  ON CONFLICT DO NOTHING
`;

const COUNT_FX_WITHOUT_OPN = `
  SELECT COUNT(DISTINCT t.id) AS cnt
  FROM transceivers t
  JOIN vendors v ON v.id = t.vendor_id AND UPPER(v.name) LIKE '%FLEXOPTIX%'
  WHERE t.reach_meters >= 10
    AND t.speed_gbps > 0
    AND NOT EXISTS (
      SELECT 1 FROM transceiver_equivalences e
      WHERE e.flexoptix_id = t.id AND 'opn' = ANY(e.match_basis)
    )
`;

const COUNT_SPEC_CANDIDATES = `
  SELECT COUNT(DISTINCT (fx.id, comp.id)) AS cnt
  FROM transceivers fx
  JOIN vendors vfx ON vfx.id = fx.vendor_id AND UPPER(vfx.name) LIKE '%FLEXOPTIX%'
  JOIN transceivers comp
    ON comp.form_factor = fx.form_factor
    AND comp.speed_gbps = fx.speed_gbps
    AND comp.reach_meters >= 10
    AND tip_reach_tier(comp.reach_meters) = tip_reach_tier(fx.reach_meters)
    AND (
      (tip_extract_wavelength_nm(fx.wavelengths) IS NULL
       AND tip_extract_wavelength_nm(comp.wavelengths) IS NULL)
      OR ABS( COALESCE(tip_extract_wavelength_nm(comp.wavelengths), 0)
            - COALESCE(tip_extract_wavelength_nm(fx.wavelengths), 0) ) <= 10
    )
  JOIN vendors vcomp ON vcomp.id = comp.vendor_id AND vcomp.is_competitor = true
  WHERE fx.reach_meters >= 10
    AND fx.speed_gbps > 0
    AND NOT EXISTS (
      SELECT 1 FROM transceiver_equivalences e
      WHERE e.flexoptix_id = fx.id AND 'opn' = ANY(e.match_basis)
    )
`;

// ── Main export ───────────────────────────────────────────────────────────────

export async function runSpecMatcher(): Promise<SpecMatcherResult> {
  const ts = () => new Date().toISOString();
  console.log(`[${ts()}] Spec Matcher starting`);

  const fxRes = await pool.query<{ cnt: string }>(COUNT_FX_WITHOUT_OPN);
  const fxProductsScanned = parseInt(fxRes.rows[0].cnt, 10);

  const candRes = await pool.query<{ cnt: string }>(COUNT_SPEC_CANDIDATES);
  const candidatePairs = parseInt(candRes.rows[0].cnt, 10);

  console.log(
    `[${ts()}] Spec Matcher: ${fxProductsScanned} FX products without OPN, ` +
    `${candidatePairs} spec candidate pairs`,
  );

  const insertRes = await pool.query(INSERT_SPEC_MATCHES);
  const inserted = insertRes.rowCount ?? 0;
  const skippedExisting = candidatePairs - inserted;

  console.log(
    `[${ts()}] Spec Matcher done: ${inserted} new spec equivalences inserted ` +
    `(${skippedExisting} pairs already existed or capped)`,
  );

  return { inserted, fxProductsScanned, candidatePairs, skippedExisting };
}
