/* ============================================================
   AI4Colegios UI Kit — Ledger.jsx  (2.0 — column manager + sortable headers)
   KPI strip (defined, not rendered) · toolbar (search / grade / quick-views with
   counts / Households / Columns) · the ledger: per-column show-hide, click-to-sort
   headers, household group rows, press-a-month-to-register (button-styled cells).
   No fee caption, no WhatsApp column, no Status dropdown.
   ============================================================ */
(function () {
  const { Import, Export, Search } = window.Icons;
  const { t, money } = window.RZH;
  const D = window.RZDATA;
  const MB = D.MONTHS, CUR = D.CUR;

  // toggleable columns (sticky id cols are always shown). band = aPagar|pension|resumen
  const COLS = [
    { k:'mat',   band:'aPagar',  es:'Matrícula',   en:'Enrollment', sortable:true },
    { k:'costs', band:'aPagar',  es:'Costos',      en:'Fees',       sortable:true },
    { k:'pen',   band:'aPagar',  es:'Pensión/mes', en:'Tuition/mo', sortable:true },
    { k:'year',  band:'aPagar',  es:'Total año',   en:'Year total', sortable:true },
    { k:'cmat',  band:'pension', es:'Mat.✓',       en:'Enr.✓',      kind:'flag', flag:'matriculaPaid' },
    { k:'ccos',  band:'pension', es:'Cos.✓',       en:'Fee✓',       kind:'flag', flag:'costosPaid' },
    ...MB.map((m,i)=>({ k:'m'+i, band:'pension', es:m, en:m, kind:'month', mi:i })),
    { k:'tp',    band:'pension', es:'Tot. pagado', en:'Total paid', sortable:true },
    { k:'debio', band:'resumen', es:'Debió pagar', en:'Should have paid', sortable:true },
    { k:'saldo', band:'resumen', es:'Saldo en mora', en:'Overdue balance', sortable:true, saldo:true },
  ];
  const COL_KEYS = COLS.map(c=>c.k);
  const BANDS = [['aPagar','Valor a pagar','Amount due'],['pension','Pagos realizados','Payments made'],['resumen','Saldo','Balance']];
  const PRESETS = {
    completa: { es:'Completa',         en:'Full',             cols: COL_KEYS },
    cobro:    { es:'Cobro de morosos', en:'Collections',      cols: ['pen','debio','saldo'] },
    pagos:    { es:'Pagos del mes',    en:'Monthly payments', cols: ['cmat','ccos',...MB.map((m,i)=>'m'+i),'tp'] },
    resumen:  { es:'Resumen',          en:'Summary',          cols: ['pen','year','tp','debio','saldo'] },
  };
  const moneyOf = (s,k)=>({mat:s.matricula,costs:s.costos,pen:s.pension,year:s.totalAno,tp:s.totalPagado,debio:s.debioPagar,saldo:s.saldoMora}[k]);

  /* ---------- KPI strip (defined; not rendered) ---------- */
  function KpiStrip({ lang }) {
    const T = D.totals;
    const tiles = [
      { lbl:t(lang,'Recaudo año a la fecha','Year-to-date collections'), val:'$ '+money(T.recaudoYTD), tag:'COP' },
      { lbl:t(lang,'Mora pendiente','Outstanding balance'), val:'$ '+money(T.moraPendiente), tag:'COP', cls:'warn' },
      { lbl:t(lang,'Estudiantes al día','Students current'), val:T.alDia+' '+t(lang,'de','of')+' '+T.total, cls:'good' },
      { lbl:t(lang,'En mora 1+ mes','Overdue 1+ month'), val:T.enMora, cls:'warn' },
      { lbl:t(lang,'Total estudiantes','Total students'), val:T.total },
    ];
    return (<div className="stats">{tiles.map((s,i)=>(<div key={i} className={'stat '+(s.cls||'')}><div className="lbl">{s.lbl}</div><div className="val">{s.val}{s.tag&&<span className="currency-tag">{s.tag}</span>}</div></div>))}</div>);
  }

  /* ---------- Toolbar ---------- */
  function Toolbar({ lang, query, setQuery, quick, setQuick, byFamily, setByFamily, grade, setGrade, visible, setVisible }) {
    const [open, setOpen] = React.useState(false);
    const N = {
      all:   D.students.length,
      mora:  D.students.filter((s)=>/mora/.test(s.status)||s.status==='sinmat').length,
      mora2: D.students.filter((s)=>s.status==='mora2'||s.status==='sinmat').length,
      fam:   D.fams.length,
    };
    const QUICK = [ {id:'all',es:'Todos',en:'All',n:N.all}, {id:'mora',es:'Mora 1+',en:'Late 1+',n:N.mora}, {id:'mora2',es:'Mora 2+',en:'Late 2+',n:N.mora2} ];
    const GRADE_ORDER = ['PRE-J','JARDÍN','TRANSICIÓN','TRANS','1°','2°','3°','4°','5°','6°','7°','8°','9°','10°','11°'];
    const grades = [...new Set(D.students.map((s)=>s.grado))].sort((a,b)=>{ const ia=GRADE_ORDER.indexOf(a),ib=GRADE_ORDER.indexOf(b); return (ia<0?99:ia)-(ib<0?99:ib); });
    const applyPreset = (key) => setVisible(new Set(PRESETS[key].cols));
    const toggleCol = (k) => { const n=new Set(visible); n.has(k)?n.delete(k):n.add(k); setVisible(n); };
    const shownCount = visible.size;
    return (
      <div className="toolbar">
        <div className="search-wrap"><Search className="search-ico" /><input value={query} onChange={(e)=>setQuery(e.target.value)} placeholder={t(lang,'Buscar por estudiante o acudiente','Find by student or guardian')} /></div>
        <select value={grade} onChange={(e)=>setGrade(e.target.value)} aria-label={t(lang,'Grado','Grade')}>
          <option value="all">{t(lang,'Todos los grados','All grades')}</option>
          {grades.map((g)=><option key={g} value={g}>{g}</option>)}
        </select>
        <span className="qv-label">{t(lang,'Vistas rápidas','Quick views')}</span>
        {QUICK.map((q)=>(<button key={q.id} type="button" className={'qv-chip'+(quick===q.id?' active':'')} aria-pressed={quick===q.id} onClick={()=>setQuick(q.id)}>{t(lang,q.es,q.en)} <span className="qv-n">{q.n}</span></button>))}
        <button type="button" className={'qv-chip fam-chip'+(byFamily?' active':'')} aria-pressed={byFamily} onClick={()=>setByFamily(!byFamily)}>👪 {t(lang,'Familias','Households')} <span className="qv-n">{N.fam}</span></button>
        <span className="spacer" />
        <div className="vista-wrap">
          <button type="button" className="btn-ghost-mini vista-btn" onClick={()=>setOpen(o=>!o)}>▦ {t(lang,'Columnas','Columns')} <span className="vista-count">{shownCount}</span> ▾</button>
          {open && (
            <div className="vista-panel cols-panel" onMouseLeave={()=>setOpen(false)}>
              <div className="vista-h">{t(lang,'Vistas predefinidas','Preset views')}</div>
              <div className="preset-row">{Object.keys(PRESETS).map((k)=>(<button key={k} type="button" className="preset-pill" onClick={()=>applyPreset(k)}>{t(lang,PRESETS[k].es,PRESETS[k].en)}</button>))}</div>
              {BANDS.map(([band,es,en])=>(
                <div key={band} className="col-group">
                  <div className="vista-h">{t(lang,es,en)}</div>
                  {COLS.filter(c=>c.band===band).map((c)=>(
                    <label key={c.k} className="vista-col"><input type="checkbox" checked={visible.has(c.k)} onChange={()=>toggleCol(c.k)} /> {t(lang,c.es,c.en)}</label>
                  ))}
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    );
  }

  /* ---------- Pill (incl. sin-matrícula) ---------- */
  const PILL = { good:['good','AL DÍA','CURRENT'], mora1:['mora1','MORA 1 MES','1 MONTH LATE'],
    mora2:['mora2','MORA 2+ MESES','2+ MONTHS LATE'], mora3:['mora2','MORA 2+ MESES','2+ MONTHS LATE'],
    pagado:['pagado','PAGADO','PAID'], sinmat:['sinmat','SIN MATRÍCULA','NO ENROLLMENT'] };
  function Pill({ status, lang }) { const p = PILL[status]||PILL.good; return <span className={'pill '+p[0]}>{t(lang,p[1],p[2])}</span>; }

  function MonthCell({ state, current, onPress, lang }) {
    const pressable = state==='mora'||state==='future'||state==='empty';
    const cls=['money','cell']; if(state==='paid')cls.push('paid'); else if(state==='mora')cls.push('mora'); else if(state==='future')cls.push('future'); if(current)cls.push('current-month-col'); if(pressable)cls.push('payable');
    return (<td className={cls.join(' ')} role={pressable?'button':undefined} tabIndex={pressable?0:undefined} onClick={pressable?onPress:undefined}
      onKeyDown={pressable?(e)=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();onPress();}}:undefined}
      title={state==='paid'?t(lang,'Ya pagado','Already paid'):(pressable?t(lang,'Registrar pago','Register payment'):'')}>{state==='paid'?'✓':(pressable?'＋':'')}</td>);
  }

  /* ---------- The table ---------- */
  function LedgerTable({ lang, rows, selected, onToggleRow, onToggleAll, allChecked, someChecked, onPressCell, onName, visible, sort, onSort, byFamily }) {
    const vis = visible || new Set(COL_KEYS);
    const shownCols = COLS.filter(c=>vis.has(c.k));
    const bandCount = (band)=>shownCols.filter(c=>c.band===band).length;
    const totalCols = 5 + shownCols.length;
    const ind = (k)=> sort && sort.key===k ? (sort.dir==='asc'?' ▲':' ▼') : '';
    const Sortable = ({k, cls, children}) => <th className={(cls||'')+' sortable'} onClick={()=>onSort(k)} title={t(lang,'Ordenar','Sort')}>{children}{ind(k)}</th>;

    let lastFam = null;
    const body = [];
    rows.forEach((s)=>{
      if (byFamily && s.famIdx !== lastFam) {
        lastFam = s.famIdx;
        const fam = rows.filter(x=>x.famIdx===s.famIdx);
        const fsaldo = fam.reduce((a,x)=>a+x.saldoMora,0);
        body.push(<tr key={'g'+s.famIdx} className="group-head"><td colSpan={totalCols}>👪 {s.acu} · {fam.length} {t(lang,'estudiantes','students')} · {t(lang,'saldo','balance')} <b>$ {money(fsaldo)}</b></td></tr>);
      }
      const sel = selected.has(s.no);
      body.push(
        <tr key={s.no} className={sel?'row-selected':''}>
          <td className="selcol sticky-0"><input type="checkbox" checked={sel} onChange={()=>onToggleRow(s.no)} aria-label={t(lang,'Seleccionar ','Select ')+s.nombres} /></td>
          <td className="sticky-1 col-no">{s.no}</td>
          <td className="sticky-2 col-nm"><button type="button" className="name-link" onClick={()=>onName(s)}>{s.nombres}</button>{s.famIdx!=null&&<span className="fam-count" title={t(lang,'Hermanos','Siblings')}>⌂{D.fams[s.famIdx].members.length}</span>}</td>
          <td className="sticky-3 col-gr">{s.grado}</td>
          <td className="col-st"><Pill status={s.status} lang={lang} /></td>
          {shownCols.map((c)=>{
            if (c.kind==='month') return <MonthCell key={c.k} state={s.cells[c.mi]} current={c.mi===CUR} lang={lang} onPress={()=>onPressCell(s,MB[c.mi])} />;
            if (c.kind==='flag') return <td key={c.k} className={'money '+(s[c.flag]?'paid':'mora')}>{s[c.flag]?'✓':'—'}</td>;
            if (c.saldo) return <td key={c.k} className={'money col-saldo '+(s.saldoMora>0?'mora':'')}>{s.saldoMora>0?money(s.saldoMora):'0'}</td>;
            return <td key={c.k} className={'money auto'+(c.k==='tp'?' strong':'')}>{money(moneyOf(s,c.k))}</td>;
          })}
        </tr>
      );
    });

    return (
      <div className="sheet">
        <table className="libro">
          <thead>
            <tr className="band-row">
              <th className="selcol band-id"></th>
              <th className="band-id" colSpan={4}>{t(lang,'Identidad','Identity')}</th>
              {bandCount('aPagar')>0 && <th className="band-pay" colSpan={bandCount('aPagar')}>{t(lang,'Valor a pagar','Amount due')}</th>}
              {bandCount('pension')>0 && <th className="band-paid" colSpan={bandCount('pension')}>{t(lang,'Pagos realizados','Payments made')}</th>}
              {bandCount('resumen')>0 && <th className="band-saldo" colSpan={bandCount('resumen')}>{t(lang,'Saldo','Balance')}</th>}
            </tr>
            <tr className="head-row">
              <th className="selcol sticky-0"><input type="checkbox" aria-label={t(lang,'Seleccionar todo','Select all')} checked={allChecked} ref={(el)=>{if(el)el.indeterminate=someChecked&&!allChecked;}} onChange={onToggleAll} /></th>
              <Sortable k="no" cls="sticky-1 col-no">No</Sortable>
              <Sortable k="name" cls="sticky-2 col-nm">{t(lang,'Nombres','Names')}</Sortable>
              <Sortable k="grade" cls="sticky-3 col-gr">{t(lang,'Grado','Grade')}</Sortable>
              <Sortable k="status" cls="col-st">{t(lang,'Estado','Status')}</Sortable>
              {shownCols.map((c)=> c.sortable
                ? <Sortable key={c.k} k={c.k} cls={'money'+(c.saldo?' col-saldo':'')}>{t(lang,c.es,c.en)}</Sortable>
                : <th key={c.k} className={'money mcol'+(c.kind==='month'&&c.mi===CUR?' current-month':'')}>{t(lang,c.es,c.en)}</th>)}
            </tr>
          </thead>
          <tbody>{body}</tbody>
        </table>
      </div>
    );
  }

  window.Ledger = { KpiStrip, Toolbar, LedgerTable, COL_KEYS };
})();
