/**
 * services/calc.js
 * Helpers partagés : calculs, formatage, seuils métier RLA
 */

const SEUIL_STANDARD       = parseFloat(process.env.SEUIL_STANDARD       || 70);
const SEUIL_MODERNISATION  = parseFloat(process.env.SEUIL_MODERNISATION   || 50);
const SEUIL_CRITIQUE_PCT   = parseFloat(process.env.SEUIL_CRITIQUE_PCT    || 90);
const DELAI_CRITIQUE        = parseInt(process.env.DELAI_CRITIQUE          || 45,  10);
const DELAI_ATTENTION       = parseInt(process.env.DELAI_ATTENTION         || 90,  10);

// ─── Parseurs ───────────────────────────────────────────────────────────────

function parseNum(v) {
  const n = parseFloat(String(v ?? '').replace(/\s/g, '').replace(',', '.'));
  return isNaN(n) ? 0 : n;
}

function parseDateFR(d) {
  if (!d) return null;
  // ISO or FR dd/mm/yyyy
  const parts = String(d).split(/[\/\-]/);
  if (parts.length === 3) {
    const [a, b, c] = parts;
    if (a.length === 4) return new Date(`${a}-${b}-${c}`);      // YYYY-MM-DD
    if (c.length === 4) return new Date(`${c}-${b}-${a}`);      // DD/MM/YYYY
  }
  const dt = new Date(d);
  return isNaN(dt.getTime()) ? null : dt;
}

// ─── Formatage ───────────────────────────────────────────────────────────────

function formatMontant(v) {
  const n = parseNum(v);
  if (n === 0) return '—';
  return n.toLocaleString('fr-TN', { minimumFractionDigits: 0, maximumFractionDigits: 3 }) + ' DT';
}

function formatDateFR(d) {
  const dt = parseDateFR(d);
  if (!dt) return '—';
  return dt.toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric' });
}

function formatPct(v) {
  const n = parseNum(v);
  return n === 0 ? '0 %' : `${n.toFixed(1)} %`;
}

// ─── Détermination de statuts métier ─────────────────────────────────────────

function isCloture(r) {
  const obs = String(r.observation || r.statut || '').toLowerCase();
  return obs.includes('clôtur') || obs.includes('clotur') || !!r.date_cloture;
}

function getDelaiRestant(r) {
  if (r.delai_restant != null && r.delai_restant !== '') {
    const v = parseInt(r.delai_restant, 10);
    return isNaN(v) ? null : v;
  }
  const fin = r.date_fin || r.datefin;
  const dt  = parseDateFR(fin);
  if (!dt) return null;
  return Math.ceil((dt - new Date()) / 86400000);
}

function niveauAlerte(delai) {
  if (delai === null) return 'indéterminé';
  if (delai <= DELAI_CRITIQUE)  return 'critique';
  if (delai <= DELAI_ATTENTION) return 'attention';
  return 'normal';
}

function niveauAvancement(tauxPhy, nature) {
  const t   = parseNum(tauxPhy);
  const seuil = String(nature || '').toLowerCase().includes('modern') ? SEUIL_MODERNISATION : SEUIL_STANDARD;
  if (t >= SEUIL_CRITIQUE_PCT) return 'dépassé';
  if (t >= seuil)               return 'sous_avancement';
  return 'normal';
}

// ─── Niveau de risque global ─────────────────────────────────────────────────

function niveauRisque(r) {
  const delai = getDelaiRestant(r);
  const avt   = parseNum(r.taux_phy || r.avt_fin);
  const nd    = niveauAlerte(delai);
  if (nd === 'critique' || avt >= SEUIL_CRITIQUE_PCT) return 'critique';
  if (nd === 'attention')                              return 'élevé';
  if (avt >= SEUIL_STANDARD)                          return 'moyen';
  return 'faible';
}

// ─── Normalisation d'un marché ───────────────────────────────────────────────

function normalizeMarche(r) {
  const delaiRestant = getDelaiRestant(r);
  const tauxPhy      = parseNum(r.taux_phy  ?? r.avt_phy  ?? r.avancement_physique);
  const tauxFin      = parseNum(r.taux_fin  ?? r.avt_fin  ?? r.avancement_financier);
  const montant      = parseNum(r.tot_marche ?? r.totmarche ?? r.montant);
  const consomme     = parseNum(r.consomme ?? r.montant_consomme ?? (montant * tauxFin / 100));
  const restant      = montant - consomme;

  return {
    id:              r.id,
    ref:             r.ref || r.reference || r.id_marche || '',
    projet:          r.projet || '',
    region:          r.region || r.region_csc || '',
    entrepreneur:    r.entrepreneur || '',
    nature:          r.nature || '',
    statut:          r.statut || '',
    observation:     r.observation || '',
    cloture:         isCloture(r),
    date_debut:      formatDateFR(r.date_debut),
    date_fin:        formatDateFR(r.date_fin || r.datefin),
    date_cloture:    formatDateFR(r.date_cloture),
    montant_raw:     montant,
    montant:         formatMontant(montant),
    consomme_raw:    consomme,
    consomme:        formatMontant(consomme),
    restant_raw:     restant,
    restant:         formatMontant(restant),
    taux_phy_raw:    tauxPhy,
    taux_phy:        formatPct(tauxPhy),
    taux_fin_raw:    tauxFin,
    taux_fin:        formatPct(tauxFin),
    delai_restant:   delaiRestant,
    niveau_alerte:   niveauAlerte(delaiRestant),
    niveau_avancement: niveauAvancement(r.taux_phy ?? r.avt_phy, r.nature),
    niveau_risque:   niveauRisque(r),
  };
}

// ─── Seuils exportés ─────────────────────────────────────────────────────────

module.exports = {
  SEUIL_STANDARD,
  SEUIL_MODERNISATION,
  SEUIL_CRITIQUE_PCT,
  DELAI_CRITIQUE,
  DELAI_ATTENTION,
  parseNum,
  parseDateFR,
  formatMontant,
  formatDateFR,
  formatPct,
  isCloture,
  getDelaiRestant,
  niveauAlerte,
  niveauAvancement,
  niveauRisque,
  normalizeMarche,
};
