// gp-registry.jsx — EXTENSIBILITY CORE
// ════════════════════════════════════════════════════════════════
//  Pour ajouter un nouvel estimateur à la plateforme :
//    1. Ajoutez son entrée dans MODULE_GROUPS (gp-data) → apparaît
//       dans la barre latérale et le tableau de bord.
//    2. Ajoutez un objet dans SPEC_OVERRIDES ci-dessous → décrit
//       ce qu'il consomme du plan, ses champs et son pilote de calcul.
//    3. Ajoutez une ou plusieurs recettes (RECIPES, gp-data) avec
//       module:'<id>' → le moteur calcule les quantités tout seul.
//  Aucune autre modification n'est requise : le moteur générique
//  (gp-engine) rend l'écran, lie les mesures du plan et agrège la
//  soumission automatiquement.
// ════════════════════════════════════════════════════════════════

// ── Spec par défaut : un estimateur de surface standard ──────────
const DEFAULT_SPEC = {
  consumes: ['surface'],     // types de formes du plan repris automatiquement
  rowMode: 'surface',        // 'surface' (L×H) | 'linear' (L) | 'count' (Qté) | 'none'
  primaryDriver: 'area',     // 'area' | 'perim' | 'units' — alimente le sommaire
  buffer: 8,                 // surplus % par défaut
  unitOut: 'unités',         // libellé de la quantité principale
  fields: [
    { key:'assemblage', label:'Assemblage', type:'select', opts:['Standard','Personnalisé…'] },
    { key:'r', label:'Valeur R cible', type:'mono', val:'R-24' },
  ],
  hint: 'Relevez des formes dans Mesure sur plan — elles se lient ici automatiquement — ou ajoutez une ligne manuelle.',
};

// ── Surcharges par module (le « catalogue de produits ») ─────────
const SPEC_OVERRIDES = {
  'sous-dalle': { consumes:['surface'], rowMode:'surface', primaryDriver:'area', unitOut:'paquets',
    fields:[
      { key:'iso', label:'Isolant', type:'select', opts:['Polystyrène extrudé (XPS)','Polystyrène expansé (EPS)','Polyuréthane'] },
      { key:'ep', label:'Épaisseur (po)', type:'mono', val:'4' },
      { key:'r', label:'Valeur R cible', type:'mono', val:'R-20' },
    ] },
  fondation: { consumes:['ligne','surface'], rowMode:'surface', primaryDriver:'area', unitOut:'paquets',
    fields:[
      { key:'type', label:'Type', type:'select', opts:['Béton coulé 8″','Béton coulé 10″','ICF'] },
      { key:'haut', label:'Hauteur hors-terre (pi)', type:'mono', val:'2' },
      { key:'r', label:'Valeur R cible', type:'mono', val:'R-14' },
    ] },
  toiture: { consumes:['surface'], rowMode:'surface', primaryDriver:'area', unitOut:'sacs',
    fields:[
      { key:'assemblage', label:'Assemblage', type:'select', opts:['Toit cathédrale','Combles ventilés','Toit plat'] },
      { key:'r', label:'Valeur R cible', type:'mono', val:'R-60' },
    ] },
  isolation: { consumes:['surface'], rowMode:'surface', primaryDriver:'area', unitOut:'sacs',
    fields:[
      { key:'prod', label:'Produit', type:'select', opts:['PROFIB CELL','Greenfiber'] },
      { key:'dens', label:'Densité (lb/pi³)', type:'mono', val:'1.6' },
      { key:'r', label:'Valeur R cible', type:'mono', val:'R-60' },
    ] },
  matelas: { consumes:['surface'], rowMode:'surface', primaryDriver:'area', unitOut:'paquets',
    fields:[
      { key:'prod', label:'Produit', type:'select', opts:['Laine minérale (Roxul)','Fibre de verre','Laine de bois'] },
      { key:'larg', label:'Largeur de cavité (po)', type:'select', opts:['16″ c/c','24″ c/c'] },
      { key:'r', label:'Valeur R cible', type:'mono', val:'R-24' },
    ] },
  chanvre: { consumes:['surface'], rowMode:'surface', primaryDriver:'area', unitOut:'sacs',
    fields:[
      { key:'ep', label:'Épaisseur (po)', type:'mono', val:'12' },
      { key:'dens', label:'Densité', type:'select', opts:['Mur (banché)','Toiture (allégé)','Dalle'] },
      { key:'liant', label:'Liant', type:'select', opts:['Chaux aérienne','Chaux hydraulique'] },
    ] },
  acoustique: { consumes:['surface'], rowMode:'surface', primaryDriver:'area', unitOut:'paquets',
    fields:[
      { key:'prod', label:'Produit', type:'select', opts:['Laine minérale Safe’n’Sound','Fibre de verre'] },
      { key:'cible', label:'Indice STC cible', type:'mono', val:'STC 50' },
    ] },
  membranes: { consumes:['surface','ligne'], rowMode:'linear', primaryDriver:'perim', unitOut:'rouleaux',
    fields:[
      { key:'int', label:'Membrane intérieure', type:'select', opts:['Pro Clima Intello Plus','SIGA Majrex'] },
      { key:'ext', label:'Pare-intempéries', type:'select', opts:['Solitex Mento 1000','Tyvek'] },
    ] },
  // noBuffer: true → retire le surplus (slider + calcul) pour ce module.
  // Décommenter si l'équipe décide que la Structure n'a pas besoin de surplus.
  structure: { consumes:['ligne'], rowMode:'linear', primaryDriver:'perim', unitOut:'pmp', /* noBuffer:true, */
    fields:[
      { key:'sys', label:'Système', type:'select', opts:['Ossature légère','Poutres & colonnes','LVL / ingénierie'] },
      { key:'ess', label:'Essence', type:'select', opts:['SPF','Douglas','LVL'] },
    ] },
  bois: { consumes:['ligne'], rowMode:'linear', primaryDriver:'perim', unitOut:'pmp',
    fields:[
      { key:'ess', label:'Essence', type:'select', opts:['SPF','Pin','Cèdre','LVL'] },
      { key:'grade', label:'Qualité', type:'select', opts:['Charpente n°2','Sélect','Apparent'] },
    ] },
  plancher: { consumes:['surface'], rowMode:'surface', primaryDriver:'area', unitOut:'pi²',
    fields:[
      { key:'type', label:'Type', type:'select', opts:['Bois franc','Ingénierie','Flottant'] },
      { key:'ess', label:'Essence/finition', type:'select', opts:['Chêne','Érable','Frêne'] },
    ] },
  revetement: { consumes:['surface'], rowMode:'surface', primaryDriver:'area', unitOut:'pi²',
    fields:[
      { key:'type', label:'Type', type:'select', opts:['Pin blanc rainuré','Maibec','Canexel','Fibrociment'] },
      { key:'pose', label:'Sens de pose', type:'select', opts:['Horizontal','Vertical','Diagonal'] },
    ] },
  charge: { consumes:[], rowMode:'none', primaryDriver:'area', unitOut:'BTU/h', isCalc:true,
    fields:[
      { key:'volume', label:'Volume chauffé (pi³)', type:'mono', val:'20 160' },
      { key:'designT', label:'ΔT de design (°C)', type:'mono', val:'42' },
      { key:'ach', label:'Étanchéité (ACH₅₀)', type:'mono', val:'0.6' },
    ] },
  ventilation: { consumes:[], rowMode:'count', primaryDriver:'units', unitOut:'unités',
    fields:[
      { key:'sys', label:'Système', type:'select', opts:['VRC haute efficacité','VEC (enthalpie)','VRC standard'] },
      { key:'cfm', label:'Débit cible (pi³/min)', type:'mono', val:'120' },
    ] },
  'grille-ventilation': { consumes:['count'], rowMode:'count', primaryDriver:'units', unitOut:'grilles',
    fields:[
      { key:'type', label:'Type de grille', type:'select', opts:['Diffuseur plafond','Grille murale','Grille de reprise','Grille extérieure'] },
      { key:'fini', label:'Fini', type:'select', opts:['Blanc','Aluminium','Acier inox','Noir'] },
    ] },
};

function getSpec(id) {
  return { ...DEFAULT_SPEC, id, ...(SPEC_OVERRIDES[id] || {}) };
}
// Modules rendus par un composant sur mesure plutôt que par le moteur générique.
const CUSTOM_MODULES = { murs:'MursModule', fenestration:'FenestrationModule' };

Object.assign(window, { getSpec, SPEC_OVERRIDES, DEFAULT_SPEC, CUSTOM_MODULES });
