// Utility/regulator profile helpers — ANRE (energy), ANCOM (telco), CNSC (procurement
// contestations). Each returns null when the CUI has no presence in the source so the
// UI can skip the badge/section entirely. Mirrors the style of the existing helpers
// in profile-queries.ts (RegAS / AEP / ANAF). Always uses query() from './db.js' and
// PostgreSQL parameter binding ($1) with the standard normCui regex normalization.
import { query } from './db.js';

// ─────────────────────────────────────────────────────────────
// ANRE — Autoritatea Națională de Reglementare în domeniul Energiei.
// Source: anre.licente (corporate licenses, 3 sub-registries) and the
// per-CUI rollup anre.mv_licente_per_cui.
// ─────────────────────────────────────────────────────────────

export interface AnreLicentaPreview {
  license_source: string;          // 'electricitate' | 'gaze' | 'atestat'
  license_no: string;
  license_type: string | null;     // 'Licenta' | 'Autorizatie de Infiintare' | 'Atestat' | …
  license_subtype: string | null;  // 'Furnizare' | 'Producere' | 'Distributie' | …
  stare: string | null;            // 'Acordata' | 'Expirata' | 'Retrasa' | …
  data_emitere: string | null;
  data_expirare: string | null;
}

export interface AnreStatus {
  nr_licente_total: number;
  nr_active: number;
  nr_expirate: number;
  nr_retrase: number;
  nr_electricitate: number;
  nr_gaze: number;
  nr_atestate: number;
  surse: string[];
  subtipuri: string[];
  prima_emitere: string | null;
  ultima_emitere: string | null;
  ultima_expirare: string | null;
  recent: AnreLicentaPreview[];
}

export async function getAnreStatus(cui: string): Promise<AnreStatus | null> {
  const normCui = cui.replace(/^RO\s*/i, '').trim();
  const aggR = await query<any>(
    `SELECT nr_licente_total::int,
            nr_active::int,
            nr_expirate::int,
            nr_retrase::int,
            nr_electricitate::int,
            nr_gaze::int,
            nr_atestate::int,
            surse,
            subtipuri,
            to_char(prima_emitere, 'YYYY-MM-DD')   AS prima_emitere,
            to_char(ultima_emitere, 'YYYY-MM-DD')  AS ultima_emitere,
            to_char(ultima_expirare, 'YYYY-MM-DD') AS ultima_expirare
     FROM anre.mv_licente_per_cui
     WHERE cui = $1`,
    [normCui],
  );
  const a = aggR.rows[0];
  if (!a || Number(a.nr_licente_total) === 0) return null;

  const recentR = await query<AnreLicentaPreview>(
    `SELECT license_source,
            license_no,
            license_type,
            license_subtype,
            stare,
            to_char(data_emitere, 'YYYY-MM-DD')  AS data_emitere,
            to_char(data_expirare, 'YYYY-MM-DD') AS data_expirare
     FROM anre.licente
     WHERE titular_cui = $1
     ORDER BY (CASE WHEN stare ILIKE 'Acord%' OR stare ILIKE 'Activ%' THEN 0 ELSE 1 END),
              data_emitere DESC NULLS LAST
     LIMIT 10`,
    [normCui],
  );

  return {
    nr_licente_total: Number(a.nr_licente_total),
    nr_active: Number(a.nr_active) || 0,
    nr_expirate: Number(a.nr_expirate) || 0,
    nr_retrase: Number(a.nr_retrase) || 0,
    nr_electricitate: Number(a.nr_electricitate) || 0,
    nr_gaze: Number(a.nr_gaze) || 0,
    nr_atestate: Number(a.nr_atestate) || 0,
    surse: a.surse || [],
    subtipuri: a.subtipuri || [],
    prima_emitere: a.prima_emitere,
    ultima_emitere: a.ultima_emitere,
    ultima_expirare: a.ultima_expirare,
    recent: recentR.rows,
  };
}

// ─────────────────────────────────────────────────────────────
// ANCOM — Autoritatea Națională pentru Administrare și Reglementare
// în Comunicații. CUI is direct on the registry detail page.
// Source: ancom.operatori + ancom.mv_operatori_per_cui (rollup).
// ─────────────────────────────────────────────────────────────

export interface AncomOperatorPreview {
  ancom_id: number;
  titular_name: string;
  status: string;
  judet: string | null;
  detail_url: string;
}

export interface AncomStatus {
  nr_autorizatii: number;
  retele: string[];                // ['R1','R3', …]  (codes)
  servicii: string[];              // ['S1','S2', …]  (codes)
  are_internet_fix: boolean;
  are_mobil: boolean;
  are_fibra: boolean;
  are_status_activ: boolean;
  prima_autorizare: string | null;
  ultima_autorizare: string | null;
  operatori: AncomOperatorPreview[];
}

export async function getAncomStatus(cui: string): Promise<AncomStatus | null> {
  const normCui = cui.replace(/^RO\s*/i, '').trim();
  const aggR = await query<any>(
    `SELECT nr_autorizatii::int,
            retele,
            servicii,
            are_internet_fix,
            are_mobil,
            are_fibra,
            are_status_activ,
            to_char(prima_autorizare, 'YYYY-MM-DD')   AS prima_autorizare,
            to_char(ultima_autorizare, 'YYYY-MM-DD')  AS ultima_autorizare
     FROM ancom.mv_operatori_per_cui
     WHERE cui = $1`,
    [normCui],
  );
  const a = aggR.rows[0];
  if (!a || Number(a.nr_autorizatii) === 0) return null;

  const opR = await query<AncomOperatorPreview>(
    `SELECT ancom_id,
            titular_name,
            status,
            judet,
            detail_url
     FROM ancom.operatori
     WHERE titular_cui = $1
     ORDER BY (CASE WHEN status = 'autorizat' THEN 0 ELSE 1 END), ancom_id
     LIMIT 5`,
    [normCui],
  );

  return {
    nr_autorizatii: Number(a.nr_autorizatii),
    retele: a.retele || [],
    servicii: a.servicii || [],
    are_internet_fix: !!a.are_internet_fix,
    are_mobil: !!a.are_mobil,
    are_fibra: !!a.are_fibra,
    are_status_activ: !!a.are_status_activ,
    prima_autorizare: a.prima_autorizare,
    ultima_autorizare: a.ultima_autorizare,
    operatori: opR.rows,
  };
}

// ─────────────────────────────────────────────────────────────
// CNSC — Consiliul Național de Soluționare a Contestațiilor.
// A CUI can appear as either authority (the public buyer being contested)
// or contestator (the bidder filing the complaint). We expose both sides;
// return null only when neither side has any rows.
// Stage 2 PDF parse hasn't run yet → decision_type is mostly NULL; UI hides
// fields that are NULL.
// ─────────────────────────────────────────────────────────────

export interface CnscDeciziePreview {
  decision_no: number;
  decision_year: number;
  registration_no_cnsc: string | null;
  registration_date: string | null;
  contestator_names: string[];
  contestator_cuis: string[];
  authority_name: string | null;
  authority_cuis: string[];
  decision_type: string | null;
  pdf_url: string | null;
}

export interface CnscAuthoritySide {
  contestation_count: number;
  admis_count: number;
  admis_in_parte_count: number;
  respins_count: number;
  resolved_count: number;
  first_contestation_date: string | null;
  last_contestation_date: string | null;
  recent: CnscDeciziePreview[];
}

export interface CnscContestatorSide {
  contestations_filed: number;
  won_admis: number;
  won_partial: number;
  lost_respins: number;
  resolved_count: number;
  first_contestation_date: string | null;
  last_contestation_date: string | null;
  recent: CnscDeciziePreview[];
}

export interface CnscStatus {
  asAuthority: CnscAuthoritySide | null;
  asContestator: CnscContestatorSide | null;
}

export async function getCnscStatus(cui: string): Promise<CnscStatus | null> {
  const normCui = cui.replace(/^RO\s*/i, '').trim();

  const authAggR = await query<any>(
    `SELECT contestation_count::int,
            admis_count::int,
            admis_in_parte_count::int,
            respins_count::int,
            resolved_count::int,
            to_char(first_contestation_date, 'YYYY-MM-DD') AS first_contestation_date,
            to_char(last_contestation_date,  'YYYY-MM-DD') AS last_contestation_date
     FROM cnsc.mv_per_authority_cui
     WHERE cui = $1`,
    [normCui],
  );

  const contAggR = await query<any>(
    `SELECT contestations_filed::int,
            won_admis::int,
            won_partial::int,
            lost_respins::int,
            resolved_count::int,
            to_char(first_contestation_date, 'YYYY-MM-DD') AS first_contestation_date,
            to_char(last_contestation_date,  'YYYY-MM-DD') AS last_contestation_date
     FROM cnsc.mv_per_contestator_cui
     WHERE cui = $1`,
    [normCui],
  );

  const authAgg = authAggR.rows[0];
  const contAgg = contAggR.rows[0];

  const hasAuth = !!authAgg && Number(authAgg.contestation_count) > 0;
  const hasCont = !!contAgg && Number(contAgg.contestations_filed) > 0;
  if (!hasAuth && !hasCont) return null;

  let asAuthority: CnscAuthoritySide | null = null;
  if (hasAuth) {
    const recentR = await query<any>(
      `SELECT decision_no,
              decision_year,
              registration_no_cnsc,
              to_char(registration_date, 'YYYY-MM-DD') AS registration_date,
              contestator_names,
              contestator_cuis,
              authority_name,
              authority_cuis,
              decision_type,
              pdf_url
       FROM cnsc.decizii
       WHERE $1 = ANY(authority_cuis)
       ORDER BY decision_year DESC, decision_no DESC
       LIMIT 10`,
      [normCui],
    );
    asAuthority = {
      contestation_count: Number(authAgg.contestation_count),
      admis_count: Number(authAgg.admis_count) || 0,
      admis_in_parte_count: Number(authAgg.admis_in_parte_count) || 0,
      respins_count: Number(authAgg.respins_count) || 0,
      resolved_count: Number(authAgg.resolved_count) || 0,
      first_contestation_date: authAgg.first_contestation_date,
      last_contestation_date: authAgg.last_contestation_date,
      recent: recentR.rows.map(r => ({
        decision_no: Number(r.decision_no),
        decision_year: Number(r.decision_year),
        registration_no_cnsc: r.registration_no_cnsc,
        registration_date: r.registration_date,
        contestator_names: r.contestator_names || [],
        contestator_cuis: r.contestator_cuis || [],
        authority_name: r.authority_name,
        authority_cuis: r.authority_cuis || [],
        decision_type: r.decision_type,
        pdf_url: r.pdf_url,
      })),
    };
  }

  let asContestator: CnscContestatorSide | null = null;
  if (hasCont) {
    const recentR = await query<any>(
      `SELECT decision_no,
              decision_year,
              registration_no_cnsc,
              to_char(registration_date, 'YYYY-MM-DD') AS registration_date,
              contestator_names,
              contestator_cuis,
              authority_name,
              authority_cuis,
              decision_type,
              pdf_url
       FROM cnsc.decizii
       WHERE $1 = ANY(contestator_cuis)
       ORDER BY decision_year DESC, decision_no DESC
       LIMIT 10`,
      [normCui],
    );
    asContestator = {
      contestations_filed: Number(contAgg.contestations_filed),
      won_admis: Number(contAgg.won_admis) || 0,
      won_partial: Number(contAgg.won_partial) || 0,
      lost_respins: Number(contAgg.lost_respins) || 0,
      resolved_count: Number(contAgg.resolved_count) || 0,
      first_contestation_date: contAgg.first_contestation_date,
      last_contestation_date: contAgg.last_contestation_date,
      recent: recentR.rows.map(r => ({
        decision_no: Number(r.decision_no),
        decision_year: Number(r.decision_year),
        registration_no_cnsc: r.registration_no_cnsc,
        registration_date: r.registration_date,
        contestator_names: r.contestator_names || [],
        contestator_cuis: r.contestator_cuis || [],
        authority_name: r.authority_name,
        authority_cuis: r.authority_cuis || [],
        decision_type: r.decision_type,
        pdf_url: r.pdf_url,
      })),
    };
  }

  return { asAuthority, asContestator };
}

// ─────────────────────────────────────────────────────────────
// Bugetar — Transparență Bugetară MFP. Phase 1 ingest covers the
// universe of reporting public entities (18,822 rows) but not
// actual execuții data (Phase 2 needs 2captcha). Surfacing
// registry membership on autoritate profile is still useful:
// confirms this is a "real" public budget entity + links to
// the MFP search UI for manual lookup.
// ─────────────────────────────────────────────────────────────

const BUGETAR_SECTOR_LABELS: Record<string, string> = {
  '01': 'buget de stat',
  '02': 'bugete locale',
  '03': 'asigurări sociale',
  '04': 'șomaj',
  '05': 'sănătate (FNUASS)',
};

export interface BugetarStatus {
  sector_bugetar: string;
  sector_label: string;
  judet: string | null;
  entity_name: string;
  is_ordonator_principal: boolean;
  cui_match_method: string | null;
  cui_match_score: number | null;
}

export async function getBugetarStatus(cui: string): Promise<BugetarStatus | null> {
  const norm = cui.replace(/^RO\s*/i, '').trim();
  const r = await query<{
    sector_bugetar: string;
    judet: string;
    entity_name: string;
    is_ordonator_principal: boolean;
    cui_match_method: string | null;
    cui_match_score: number | null;
  }>(
    `SELECT sector_bugetar, judet, entity_name, is_ordonator_principal,
            cui_match_method, cui_match_score
     FROM bugetar.entitate
     WHERE cui = $1
     ORDER BY is_ordonator_principal DESC, sector_bugetar
     LIMIT 1`,
    [norm],
  );
  const row = r.rows[0];
  if (!row) return null;
  return {
    sector_bugetar: row.sector_bugetar,
    sector_label: BUGETAR_SECTOR_LABELS[row.sector_bugetar] || row.sector_bugetar,
    judet: row.judet,
    entity_name: row.entity_name,
    is_ordonator_principal: row.is_ordonator_principal,
    cui_match_method: row.cui_match_method,
    cui_match_score: row.cui_match_score == null ? null : Number(row.cui_match_score),
  };
}
