/**
 * OPN-Based Equivalence Matcher
 *
 * Uses the manufacturer-provided compatibility matrix (fx_compatibilities)
 * to create high-confidence equivalences between Flexoptix products and
 * their exact OEM counterparts in competitor catalogs.
 *
 * "OPN" = OEM Part Number — the actual part number the customer buys from
 * the original manufacturer (e.g. Cisco QSFP-100G-LR4-S).
 *
 * Match quality:
 *   - confidence = 1.0 (manufacturer-confirmed)
 *   - match_mode = 'opn'
 *   - status = 'auto_approved' (same as deterministic spec match)
 *
 * Strategy:
 *   - Only processes FX products whose fx_compatibilities was updated recently
 *     (detail_synced_at > last_opn_run OR last_opn_run IS NULL)
 *   - Skips pairs that already have ANY status (approved, auto_approved, rejected)
 *   - Case-insensitive part_number match on the competitor side
 *   - Minimum OPN length = 4 chars (skips empty or trivially short entries)
 *   - Excludes MSA Standard and Flexoptix self-references
 */

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

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

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

const INSERT_OPN_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,
    1.0                 AS confidence,
    'auto_approved'     AS status,
    ARRAY['opn']        AS match_basis,
    'Manufacturer-confirmed: FX compatibility matrix lists ' ||
      COALESCE(compat->>'compatible_to_vendor', '?') || ' OPN ' ||
      COALESCE(compat->>'original_part_number', '?') 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%'
  CROSS JOIN LATERAL jsonb_array_elements(fx.fx_compatibilities) AS compat
  JOIN transceivers comp
    ON UPPER(comp.part_number) = UPPER(compat->>'original_part_number')
  JOIN vendors vcomp ON vcomp.id = comp.vendor_id AND vcomp.is_competitor = true
  WHERE fx.fx_compatibilities IS NOT NULL
    AND compat->>'original_part_number' IS NOT NULL
    AND length(trim(compat->>'original_part_number')) >= 4
    AND compat->>'compatible_to_vendor' NOT IN ('MSA Standard (Default)', 'Flexoptix')
    AND NOT EXISTS (
      SELECT 1
      FROM transceiver_equivalences e
      WHERE e.flexoptix_id = fx.id
        AND e.competitor_id = comp.id
    )
  ON CONFLICT DO NOTHING
`;

const COUNT_FX_WITH_COMPAT = `
  SELECT COUNT(*) AS cnt
  FROM transceivers t
  JOIN vendors v ON v.id = t.vendor_id AND UPPER(v.name) LIKE '%FLEXOPTIX%'
  WHERE t.fx_compatibilities IS NOT NULL
`;

const COUNT_CANDIDATE_PAIRS = `
  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%'
  CROSS JOIN LATERAL jsonb_array_elements(fx.fx_compatibilities) AS compat
  JOIN transceivers comp
    ON UPPER(comp.part_number) = UPPER(compat->>'original_part_number')
  JOIN vendors vcomp ON vcomp.id = comp.vendor_id AND vcomp.is_competitor = true
  WHERE fx.fx_compatibilities IS NOT NULL
    AND compat->>'original_part_number' IS NOT NULL
    AND length(trim(compat->>'original_part_number')) >= 4
    AND compat->>'compatible_to_vendor' NOT IN ('MSA Standard (Default)', 'Flexoptix')
`;

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

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

  // Count FX products with compatibility data
  const fxRes = await pool.query<{ cnt: string }>(COUNT_FX_WITH_COMPAT);
  const fxProductsScanned = parseInt(fxRes.rows[0].cnt, 10);

  // Count candidate pairs (informational)
  const candRes = await pool.query<{ cnt: string }>(COUNT_CANDIDATE_PAIRS);
  const candidatePairs = parseInt(candRes.rows[0].cnt, 10);

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

  // Insert new OPN-based equivalences
  const insertRes = await pool.query(INSERT_OPN_MATCHES);
  const inserted = insertRes.rowCount ?? 0;
  const skippedExisting = candidatePairs - inserted;

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

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