// gp-modules.jsx — shared module UI + Dashboard + generic template
// ───────────────────────────────────────────────────────────────
const { Icon: MIcon, ALL_MODULES: MODS, MODULE_GROUPS: MGROUPS, ESTIMATION_MODULES: EST,
  moduleById: modById, PROJECT: DPROJ, PROJECTS: DPROJECTS, fmt: fmtN, HelpButton: MHelp } = window;

const STATUS_LABEL = { done: 'Complété', prog: 'En cours', none: 'Non commencé' };

function StatusPill({ status }) {
  return (
    <span className={'pill ' + status}>
      <span className="d" /> {STATUS_LABEL[status] || 'Non commencé'}
    </span>);

}

function ModuleHeader({ mod, status, children }) {
  return (
    <div className="mhead">
      <div className="mhead-ic"><MIcon n={mod.icon} /></div>
      <div className="mhead-tx">
        <div className="mhead-tt">{mod.name}</div>
        <div className="mhead-sub">{mod.cat} · matériau de référence : {mod.mat || '—'}</div>
      </div>
      <div className="mhead-side">
        <StatusPill status={status} />
        {MHelp && <MHelp topic={mod.id} />}
        {children}
      </div>
    </div>);

}

function Steps({ steps, active, onChange }) {
  return (
    <div className="steps">
      {steps.map((s, i) =>
      <button key={s} className={'step' + (active === i ? ' on' : '')} onClick={() => onChange(i)}>
          <span className="step-n">{i + 1}</span> {s}
        </button>
      )}
    </div>);

}

// Generic summary card used by every module
function SummaryAside({ heroLabel, heroVal, heroUnit, heroRows = [], title, rows = [], buffer, onBuffer, accentNote }) {
  return (
    <div className="sum tickbox">
      <div className="sum-hero">
        <div className="sum-hero-lbl">{heroLabel}</div>
        <div className="sum-hero-val"><b>{heroVal}</b><span>{heroUnit}</span></div>
        {heroRows.map((r, i) =>
        <div className="sum-hero-row" key={i}>
            <span>{r.k}</span><b>{r.v}</b>
          </div>
        )}
      </div>
      <div className="sum-body">
        {title && <div className="sum-title">{title}</div>}
        {rows.map((r, i) =>
        <div className="sum-row" key={i}>
            <div>
              <div className="sum-row-n">{r.n}</div>
              {r.s && <div className="sum-row-s">{r.s}</div>}
            </div>
            <div className="sum-row-v"><b>{r.v}</b><span>{r.u}</span></div>
          </div>
        )}

        {buffer != null &&
        <div className="sum-buffer">
            <div className="sum-buffer-h">
              <span className="l">Surplus / pertes</span><b>{buffer}%</b>
            </div>
            <input type="range" className="ctl-slider" min="0" max="25" value={buffer}
          onChange={(e) => onBuffer(Number(e.target.value))} />
          </div>
        }

        {accentNote && <div className="note" style={{ marginTop: 12 }}>{accentNote}</div>}

        <div className="sum-exports">
          <button className="btn ghost"><MIcon n="file" /> PDF</button>
          <button className="btn ghost"><MIcon n="download" /> JSON</button>
        </div>
      </div>
    </div>);

}

// ── Dashboard ──────────────────────────────────────────────────
const SEQ = [
{ id: 'projet', n: 1, t: 'Projet', s: 'infos client', done: true },
{ id: 'config', n: 2, t: 'Configuration', s: 'hypothèses', done: true },
{ id: 'mesure', n: 3, t: 'Plan', s: 'téléverser & mesurer', done: true },
{ id: null, n: 4, t: 'Modules', s: 'relevés par élément', on: true },
{ id: 'soumission', n: 5, t: 'Soumission', s: 'liste de matériaux' }];


function Dashboard({ onNav, measures = [], project, org }) {
  const proj = project || DPROJ;
  const done = EST.filter((m) => m.status === 'done').length;
  const total = EST.length;
  const kpis = [
  { l: 'Modules complétés', v: `${done}/${total}`, s: 'éléments du bâtiment' },
  { l: 'Surface enveloppe', v: '5 054', s: 'pi² · murs + toiture' },
  { l: 'Formes relevées', v: String(measures.length), s: 'mesures liées au plan' },
  { l: 'Ouvertures', v: '34', s: 'fenêtres + portes' }];

  const assign = org && org.assign || {};
  const subcats = org && org.subcats || {};
  const widgetCat = org && org.widgetCat || {};
  const hidden = org && org.hidden || {};
  const catOf = (m) => widgetCat[m.id] || m.cat;
  const visible = EST.filter((m) => !hidden[m.id]);
  // catégories d'estimation, dans l'ordre admin (ou registre), non vides
  const order = org && org.cats && org.cats.length ? org.cats : MGROUPS.map((g) => g.group);
  const cats = order.filter((c) => visible.some((m) => catOf(m) === c));

  const Card = (m) =>
  <button className="mod-card" key={m.id} onClick={() => onNav(m.id)}>
      <div className="mod-card-top">
        <div className="mod-ic"><MIcon n={m.icon} /></div>
        {m.soon ? <span className="pill none"><span className="d" /> À venir</span> : <StatusPill status={m.status} />}
      </div>
      <div>
        <div className="mod-name">{m.name}</div>
        <div className="mod-cat">{m.cat}</div>
      </div>
      <div className="mod-foot">
        <div className="mod-q">{m.q} <small>{m.qu}</small></div>
        <MIcon n="chev" style={{ width: 16, height: 16, opacity: .4 }} />
      </div>
    </button>;


  return (
    <div className="fade-in">
      <div className="mhead" style={{ paddingBottom: 18 }}>
        <div className="mhead-ic"><MIcon n="grid" /></div>
        <div className="mhead-tx">
          <div className="mhead-tt">Tableau de bord</div>
          <div className="mhead-sub">{proj.nom} · dossier {proj.no} — un set d’outils par élément du bâtiment.</div>
        </div>
        <div className="mhead-side">
          <button className="btn" onClick={() => onNav('soumission')}><MIcon n="receipt" /> Soumission</button>
          <button className="btn accent" onClick={() => onNav('mesure')}><MIcon n="ruler" /> Mesure sur plan</button>
        </div>
      </div>

      <div className="seq">
        {SEQ.map((s) =>
        <button key={s.n} className={'seq-step' + (s.done ? ' done' : '') + (s.on ? ' on' : '')}
        onClick={() => s.id && onNav(s.id)}>
            <span className="seq-n">{s.done ? '✓' : s.n}</span>
            <span className="seq-tx"><span className="seq-t">{s.t}</span><span className="seq-s">{s.s}</span></span>
          </button>
        )}
      </div>

      <div className="kpis">
        {kpis.map((k, i) =>
        <div className="kpi" key={i}>
            <div className="kpi-l">{k.l}</div>
            <div className="kpi-v">{k.v}</div>
            <div className="kpi-s">{k.s}</div>
          </div>
        )}
      </div>

      <div className="sum-title" style={{ margin: '4px 2px 14px' }}>Modules d’estimation</div>

      {cats.map((cat) => {
        const items = visible.filter((m) => catOf(m) === cat);
        const subs = subcats[cat] || [];
        // regroupe par sous-catégorie puis « Non classé »
        const sections = [];
        subs.forEach((s) => {
          const list = items.filter((m) => assign[m.id] === s.id);
          if (list.length) sections.push({ id: s.id, name: s.name, list });
        });
        const classified = new Set(sections.flatMap((s) => s.list.map((m) => m.id)));
        const rest = items.filter((m) => !classified.has(m.id));
        const hasSubs = sections.length > 0;
        if (rest.length) sections.push({ id: '_rest', name: hasSubs ? 'Non classé' : null, list: rest });

        return (
          <div className="dash-cat" key={cat}>
            <div className="dash-cat-hrow">
              <button className="dash-cat-h" onClick={() => onNav('cat:' + cat)} title={`Voir la catégorie ${cat}`}>
                {cat} <em>{items.length}</em>
                <MIcon n="chev" style={{ width: 13, height: 13, opacity: .5 }} />
              </button>
              {MHelp && <MHelp topic={'cat:' + cat} compact={true} />}
            </div>
            {hasSubs ?
            sections.map((sec) =>
            <div className="dash-sub" key={sec.id}>
                  {sec.name && <div className="cat-sec-h"><MIcon n={sec.id === '_rest' ? 'folderPlus' : 'folders'} style={{ width: 13, height: 13 }} /> {sec.name} <em>{sec.list.length}</em></div>}
                  <div className="mod-grid">{sec.list.map(Card)}</div>
                </div>
            ) :
            <div className="mod-grid">{items.map(Card)}</div>}
          </div>);

      })}

      <div className="dash-cat">
        <div className="mod-grid">
          <button className="mod-card mod-add" onClick={() => onNav('organisation')}>
            <div className="mod-add-ic"><MIcon n="plus" /></div>
            <div>
              <div className="mod-name">Organiser les widgets</div>
              <div className="mod-cat">Catégories & sous-catégories</div>
            </div>
            <div className="mod-add-note">Créez des sous-catégories et rangez-y les modules — la structure se reflète ici et dans les vues de catégorie.</div>
          </button>
        </div>
      </div>
    </div>);

}

// ── Generic module template (not-yet-built elements) ───────────
function GenericModule({ mod, unit, onMesure, measures = [] }) {
  const [step, setStep] = React.useState(0);
  const steps = ['Configuration', 'Relevé', 'Ouvertures', 'Matériaux'];
  const u = unit === 'si' ? 'm²' : 'pi²';
  const linked = measures.filter((m) => m.target === mod.id);
  const linkedTotal = linked.reduce((s, m) => s + m.val, 0);
  return (
    <div className="fade-in">
      <ModuleHeader mod={mod} status={mod.status}>
        {onMesure && <button className="btn" onClick={onMesure}><MIcon n="ruler" /> Mesure sur plan</button>}
        <button className="btn"><MIcon n="copy" /> Dupliquer config</button>
      </ModuleHeader>
      <Steps steps={steps} active={step} onChange={setStep} />

      <div className="grid-2">
        <div className="col">
          <div className="card">
            <div className="card-h">
              <div className="card-h-l"><span className="badge-n">1</span><span className="card-t">Paramètres par défaut</span></div>
              <span className="card-hint">valeurs appliquées à chaque relevé</span>
            </div>
            <div className="fgrid">
              <div className="fcell">
                <label className="lbl">Assemblage</label>
                <select className="field"><option>{mod.mat}</option><option>Personnalisé…</option></select>
              </div>
              <div className="fcell">
                <label className="lbl">Valeur R cible</label>
                <input className="field mono" defaultValue="R-24" />
              </div>
              <div className="fcell full">
                <label className="lbl">Marge de pertes</label>
                <input type="range" className="ctl-slider" min="0" max="20" defaultValue="8" />
              </div>
            </div>
          </div>

          <div className="card">
            <div className="card-h">
              <div className="card-h-l"><span className="badge-n">2</span><span className="card-t">Relevé des surfaces</span></div>
              {linked.length > 0 && <span className="tag plan"><MIcon n="link" />{linked.length} du plan</span>}
            </div>

            {linked.length > 0 ?
            <div className="tbl-wrap">
                <table>
                  <thead><tr>
                    <th>Forme relevée</th><th style={{ width: 90 }}>Type</th>
                    <th style={{ width: 80 }}>Page</th><th className="num">Valeur</th>
                  </tr></thead>
                  <tbody>
                    {linked.map((m) =>
                  <tr key={m.id}>
                        <td style={{ fontWeight: 500 }}>{m.name} <span className="tag plan"><MIcon n="ruler" />plan</span></td>
                        <td className="muted">{m.kind}</td>
                        <td className="cell-ro" style={{ textAlign: 'left' }}>p. {m.page}</td>
                        <td className="cell-ro">{fmtN(m.val, m.kind === 'ligne' ? 1 : 0)} {m.unit}</td>
                      </tr>
                  )}
                  </tbody>
                  <tfoot><tr className="tfoot"><td colSpan="3">Total relevé</td><td className="cell-ro">{fmtN(linkedTotal, 0)}</td></tr></tfoot>
                </table>
              </div> :

            <div className="empty tickbox">
                <MIcon n={mod.icon} />
                <div className="empty-t">Gabarit prêt — aucune mesure pour l’instant</div>
                <div className="empty-s">
                  Ce module suit le même gabarit que « Murs hors sol » : relevé tabulaire, sections de niveaux,
                  ouvertures à retrancher et sommaire matériaux. Relevez des formes dans
                  <b> Mesure sur plan </b>(elles se lient ici automatiquement) ou ajoutez une ligne manuelle.
                </div>
                {onMesure && <button className="btn accent" style={{ margin: '14px auto 0' }} onClick={onMesure}><MIcon n="ruler" /> Ouvrir Mesure sur plan</button>}
              </div>
            }
            <button className="addrow" onClick={onMesure}><MIcon n="plus" /> Ajouter une ligne</button>
          </div>
        </div>

        <aside className="aside">
          <SummaryAside
            heroLabel={`${mod.mat} requis`}
            heroVal={linked.length ? fmtN(Math.ceil(linkedTotal / 32)) : '—'} heroUnit={mod.qu || 'unités'}
            heroRows={[{ k: `Surface (${u})`, v: linked.length ? fmtN(linkedTotal, 0) : '—' }, { k: 'Formes liées', v: String(linked.length) }]}
            title="Détail par section"
            rows={[
            { n: 'Rez-de-chaussée', s: 'à relever', v: '—', u: u },
            { n: 'Étage', s: 'à relever', v: '—', u: u },
            { n: 'Garage', s: 'à relever', v: '—', u: u }]
            }
            buffer={8} onBuffer={() => {}} />
          
        </aside>
      </div>
    </div>);

}

// ── Portfolio (vue de tous les projets) ────────────────────────
const PORTFOLIO_STATUS = { 'En cours': 'prog', 'Soumission': 'done', 'Relevé': 'none' };

function Portfolio({ projects = [], activeId, onOpen, onNew }) {
  const totalMontant = projects.length;
  const kpis = [
  { l: 'Projets actifs', v: String(projects.length), s: 'dans le portefeuille' },
  { l: 'En soumission', v: String(projects.filter((p) => p.statut === 'Soumission').length), s: 'prêts à livrer' },
  { l: 'Avancement moyen', v: Math.round(projects.reduce((s, p) => s + (p.avancement || 0), 0) / Math.max(projects.length, 1)) + '%', s: 'tous projets' }];

  return (
    <div className="fade-in">
      <div className="mhead" style={{ paddingBottom: 18 }}>
        <div className="mhead-ic"><MIcon n="folders" /></div>
        <div className="mhead-tx">
          <div className="mhead-tt">Portefeuille</div>
          <div className="mhead-sub">Tous vos projets — ouvrez-en un pour accéder à ses modules, recettes et soumission.</div>
        </div>
        <div className="mhead-side">
          {onNew && <button className="btn accent" onClick={onNew}><MIcon n="plus" /> Nouveau projet</button>}
        </div>
      </div>

      <div className="kpis" style={{ gridTemplateColumns: 'repeat(3,1fr)' }}>
        {kpis.map((k, i) =>
        <div className="kpi" key={i}>
            <div className="kpi-l">{k.l}</div>
            <div className="kpi-v">{k.v}</div>
            <div className="kpi-s">{k.s}</div>
          </div>
        )}
      </div>

      <div className="sum-title" style={{ margin: '4px 2px 12px' }}>Projets</div>
      <div className="proj-grid">
        {projects.map((p) =>
        <button className={'proj-card' + (p.id === activeId ? ' active' : '')} key={p.id} onClick={() => onOpen(p.id)}>
            <div className="proj-card-top">
              <div>
                <div className="proj-card-name">{p.nom}</div>
                <div className="proj-card-no">{p.no} · {p.ville}</div>
              </div>
              <span className={'pill ' + (PORTFOLIO_STATUS[p.statut] || 'none')}><span className="d" /> {p.statut}</span>
            </div>
            <div className="proj-card-client">{p.clientPrenom} {p.clientNom} · {p.type}</div>
            <div className="proj-bar"><span style={{ width: (p.avancement || 0) + '%' }} /></div>
            <div className="proj-card-foot">
              <span className="muted">
                {p.id === activeId && <span className="proj-active-tag"><MIcon n="check" style={{ width: 11, height: 11 }} /> Actif</span>}
                {p.avancement}% · {p.modulesFaits} modules
              </span>
              <span className="proj-card-montant">{p.montant}</span>
            </div>
          </button>
        )}
      </div>
    </div>);

}

// ── Vue par catégorie (depuis le fil d'Ariane) ─────────────────
function CategoryView({ cat, onNav, org }) {
  const group = MGROUPS.find((g) => g.group === cat);
  const widgetCat = org && org.widgetCat || {};
  const hidden = org && org.hidden || {};
  const catOf = (m) => widgetCat[m.id] || m.cat;
  const items = MODS.filter((m) => m.id !== 'dashboard' && !m.tool && !hidden[m.id] && catOf(m) === cat);
  const icon = items[0] && items[0].icon || (group && group.items[0] ? group.items[0].icon : 'grid');

  // sous-catégories admin (si définies pour cette catégorie)
  const subs = org && org.subcats && org.subcats[cat] || [];
  const assign = org && org.assign || {};
  // regroupe les widgets par sous-catégorie, puis « Non classé »
  const sections = [];
  subs.forEach((s) => {
    const list = items.filter((m) => assign[m.id] === s.id);
    if (list.length) sections.push({ id: s.id, name: s.name, list });
  });
  const classified = new Set(sections.flatMap((s) => s.list.map((m) => m.id)));
  const rest = items.filter((m) => !classified.has(m.id));
  const hasSubs = sections.length > 0;
  if (rest.length) sections.push({ id: '_rest', name: hasSubs ? 'Non classé' : null, list: rest });

  const Card = (m) =>
  <button className="mod-card" key={m.id} onClick={() => onNav(m.id)}>
      <div className="mod-card-top">
        <div className="mod-ic"><MIcon n={m.icon} /></div>
        {m.soon ? <span className="pill none"><span className="d" /> À venir</span> : m.status ? <StatusPill status={m.status} /> : <span className="pill none"><span className="d" /> Outil</span>}
      </div>
      <div>
        <div className="mod-name">{m.name}</div>
        <div className="mod-cat">{m.mat || m.cat}</div>
      </div>
      <div className="mod-foot">
        <div className="mod-q">{m.q || '—'} <small>{m.qu}</small></div>
        <MIcon n="chev" style={{ width: 16, height: 16, opacity: .4 }} />
      </div>
    </button>;


  return (
    <div className="fade-in">
      <div className="mhead" style={{ paddingBottom: 18 }}>
        <div className="mhead-ic"><MIcon n={icon} /></div>
        <div className="mhead-tx">
          <div className="mhead-tt">{cat}</div>
          <div className="mhead-sub">{items.length} module{items.length > 1 ? 's' : ''}{hasSubs ? ` · ${subs.length} sous-catégorie${subs.length > 1 ? 's' : ''}` : ''} — choisissez un élément à estimer.</div>
        </div>
        <div className="mhead-side">
          <button className="btn" onClick={() => onNav('dashboard')}><MIcon n="grid" /> Tableau de bord</button>
          {MHelp && <MHelp topic={items[0] ? items[0].id : 'cat:' + cat} />}
        </div>
      </div>

      {hasSubs ?
      sections.map((sec) =>
      <div className="cat-sec" key={sec.id}>
            {sec.name && <div className="cat-sec-h"><MIcon n={sec.id === '_rest' ? 'folderPlus' : 'folders'} style={{ width: 14, height: 14 }} /> {sec.name} <em>{sec.list.length}</em></div>}
            <div className="mod-grid">{sec.list.map(Card)}</div>
          </div>
      ) :
      <div className="mod-grid">{items.map(Card)}</div>}
    </div>);

}

// ── Pager séquentiel précédent · actuel · suivant (haut de page) ──
function ModulePager({ prev, cur, next, onNav }) {
  if (!prev && !next) return null;
  return (
    <div className="pager">
      {prev ?
      <button className="pager-btn prev" onClick={() => onNav(prev.id)} title={`Précédent : ${prev.name}`}>
          <MIcon n="chev" style={{ width: 17, height: 17, transform: 'rotate(180deg)' }} />
          <span className="pager-tx">
            <span className="pager-lbl">Précédent</span>
            <span className="pager-name">{prev.name}</span>
          </span>
        </button> : <span className="pager-btn ghost" />}

      {cur &&
      <div className="pager-cur">
          <MIcon n={cur.icon} style={{ width: 15, height: 15 }} />
          <span className="pager-cur-tx">
            <span className="pager-cur-name">{cur.name}</span>
            <span className="pager-cur-cat">{cur.cat}</span>
          </span>
        </div>}

      {next ?
      <button className="pager-btn next" onClick={() => onNav(next.id)} title={`Suivant : ${next.name}`}>
          <span className="pager-tx">
            <span className="pager-lbl">Suivant</span>
            <span className="pager-name">{next.name}</span>
          </span>
          <MIcon n="chev" style={{ width: 17, height: 17 }} />
        </button> : <span className="pager-btn ghost" />}
    </div>);
}

Object.assign(window, { StatusPill, ModuleHeader, Steps, SummaryAside, Dashboard, GenericModule, Portfolio, CategoryView, ModulePager });