/* OM Group ERP — reusable Profit Engine waterfall drill-down.
   One generic modal for Revenue / Purchase / Transport / Net Profit clicks
   in the Financial Intelligence waterfall (Diesel Margin routes to the
   existing DRPeriodSheet instead — one source of truth, one look, for the
   diesel numbers wherever they surface). Every value below is read straight
   out of the live IntelDomains pack — nothing is stored, cached or
   recomputed by a second engine.                                          */
const { useEffect: afEf, useRef: afRef } = React;

function AFRow({ label, value, kind, color }){
  return <div className="dr-fact"><span>{label}</span><b style={color?{color}:null}>{typeof value==='number'?window.IC.fmt(value,kind||'cur'):value}</b></div>;
}

function AFinanceDrill({ title, subtitle, accent, kpis, calc, records, columns, company, periodRange, filters, onClose }){
  const closeRef = afRef(null);
  afEf(()=>{
    const h=e=>{ if(e.key==='Escape') onClose(); };
    document.addEventListener('keydown',h);
    if(closeRef.current) closeRef.current.focus();
    return ()=>document.removeEventListener('keydown',h);
  },[onClose]);
  return ReactDOM.createPortal((
    <div className="dr-bg" onMouseDown={e=>{ if(e.target===e.currentTarget) onClose(); }}>
      <div className="dr-sheet" role="dialog" aria-modal="true" aria-label={title} style={{'--drA':accent}}>
        <div className="dr-hd">
          <div className="dr-hd-t">
            <div className="dr-eyebrow"><i></i>Profit Engine</div>
            <div className="dr-hd-date">{title}</div>
            <div className="dr-hd-sub">{subtitle}</div>
          </div>
          <div className="dr-hd-nav">
            <button className="dr-ico x" ref={closeRef} onClick={onClose} title="Close (Esc)" aria-label="Close">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4"><path d="M6 6l12 12M18 6L6 18"/></svg></button>
          </div>
        </div>
        <div className="dr-bd">
          <div className="dr-kpis" style={{gridTemplateColumns:'repeat('+Math.min(kpis.length,4)+',minmax(0,1fr))'}}>
            {kpis.map((k,i)=>(
              <div className="dr-kpi" key={i} style={{'--kc':k.color||accent}}>
                <span>{k.label}</span><b><window.IC.Num value={k.value} kind={k.kind||'cur'}/></b>
                {k.note && <em>{k.note}</em>}
              </div>
            ))}
          </div>
          {calc && calc.length>0 && (<>
            <div className="dr-sub-t">Calculation breakdown</div>
            <div className="dr-facts">{calc.map((c,i)=><AFRow key={i} label={c.label} value={c.value} kind={c.kind} color={c.color}/>)}</div>
          </>)}
          {records && (<>
            <div className="dr-sub-t">Source records — {records.length} record{records.length===1?'':'s'}</div>
            {!records.length ? <window.IC.Empty msg="No records in this selection" h={120}/> : (
              <div className="dr-tbl-wrap">
                <table className="i-dl-tbl dr-tbl">
                  <thead><tr>{columns.map(c=><th key={c.key} className={c.num?'r':''}>{c.label}</th>)}</tr></thead>
                  <tbody>{records.slice(0,200).map((r,i)=>(
                    <tr key={r.id||i}>{columns.map(c=><td key={c.key} className={c.num?'r':''}>{c.render?c.render(r):(r[c.key]==null||r[c.key]===''?'—':r[c.key])}</td>)}</tr>
                  ))}</tbody>
                </table>
                {records.length>200 && <div style={{fontSize:10.5,color:'var(--iInk3)',padding:'9px 4px'}}>Showing first 200 of {records.length} records — narrow the period or add a filter to see the rest.</div>}
              </div>
            )}
          </>)}
        </div>
        <div className="dr-ft"><span>{company}{periodRange?' · '+periodRange:''}{filters?' · '+filters:''} · live from the ERP records</span></div>
      </div>
    </div>
  ), document.body);
}

/* step: the clicked ICWaterfall bar {label, value, color, total?}
   pack: the Financial Intelligence pack from IntelDomains.build('finance', …) */
function buildWaterfallDrill(step, pack){
  const company = !pack.companyId || pack.companyId==='group' ? 'OM Group (All Companies)' : (window.Store && window.Store.name('companies',pack.companyId)) || 'Selected company';
  const periodRange = pack.period.label;
  const cfN = pack.cf ? Object.keys(pack.cf).filter(k=>pack.cf[k]!=null && pack.cf[k]!=='' ).length : 0;
  const filters = cfN ? cfN+' filter'+(cfN===1?'':'s')+' applied' : '';
  const dateCol = { key:'date', label:'Date', render:r=>(window.IntelEngine&&window.IntelEngine.util.fmtD(r.date))||r.date };
  const head = step.label==='Revenue' ? 'Revenue' : step.label==='Purchase' ? 'Purchase Cost' : step.label==='Transport' ? 'Transport' : null;

  if(head){
    const recs = (pack.rows||[]).filter(r=>r.head===head);
    const total = recs.reduce((s,r)=>s+(Number(r.value)||0),0);
    const qty = recs.reduce((s,r)=>s+(Number(r.qty)||0),0);
    const partyLabel = step.label==='Purchase' ? 'Vendor' : step.label==='Transport' ? 'Transporter' : 'Customer';
    const perTon = qty>0 ? total/qty : 0;
    const perRecord = recs.length>0 ? total/recs.length : 0;
    const cols=[dateCol,{key:'ref',label:'Reference'},{key:'party',label:partyLabel},
      {key:'qty',label:'Qty (T)',num:true,render:r=>window.formatQuantity(r.qty)},
      {key:'value',label:'Amount',num:true,render:r=>window.IC.cur(r.value)},
      {key:'status',label:'Status'}];
    return {
      title: step.label==='Purchase' ? 'Purchase Cost' : step.label,
      subtitle: (step.label==='Revenue'?'Sales value in scope':step.label==='Purchase'?'Landed procurement cost':'Logistics expenditure')+' — '+periodRange,
      accent: step.color,
      kpis: [
        { label: (step.label==='Purchase'?'Purchase Cost':step.label)+' Total', value: total, kind:'cur', color: step.color },
        { label: step.label==='Transport'?'Trips':'Records', value: recs.length, kind:'int' },
        { label: 'Quantity', value: qty, kind:'ton' },
        { label: step.label==='Transport'?'Avg / Trip':'Avg / Ton', value: step.label==='Transport'?perRecord:perTon, kind: step.label==='Transport'?'cur':'rate' },
      ],
      calc: [
        { label: 'Total '+(step.label==='Purchase'?'purchase cost':step.label.toLowerCase()), value: total, kind:'cur' },
        { label: 'Records counted', value: recs.length, kind:'int' },
        { label: 'Total quantity', value: qty, kind:'ton' },
        { label: step.label==='Transport'?'Average cost per record':'Average rate per ton', value: step.label==='Transport'?perRecord:perTon, kind: step.label==='Transport'?'cur':'rate' },
      ],
      records: recs, columns: cols, company, periodRange, filters,
    };
  }

  /* Net Profit — the full composition, same figures the waterfall itself draws from */
  const c = pack.cur;
  const rows=[
    { label:'Revenue', value:c.revenue },
    { label:'Purchase Cost', value:-c.purchaseValue },
    { label:'Transport Cost', value:-c.transportCost },
    { label:'Diesel Margin', value:c.dieselMargin },
  ];
  return {
    title:'Net Profit', subtitle:'Full composition — '+periodRange, accent: step.color,
    kpis:[
      { label:'Net Profit', value:c.netProfit, kind:'cur', color: c.netProfit>=0?'#15803D':'#DC2626' },
      { label:'Revenue', value:c.revenue, kind:'cur' },
      { label:'Total Cost', value:(c.purchaseValue||0)+(c.transportCost||0), kind:'cur' },
      { label:'Net Margin', value:c.netMargin, kind:'pct' },
    ],
    calc: rows.concat([{ label:'Net Profit', value:c.netProfit, kind:'cur', color: c.netProfit>=0?'#15803D':'#DC2626' }]).map(r=>({label:r.label,value:r.value,kind:'cur',color:r.color})),
    records: pack.rows||[],
    columns: [dateCol,{key:'head',label:'Head'},{key:'party',label:'Party'},
      {key:'value',label:'Amount',num:true,render:r=>window.IC.cur(r.value)},{key:'status',label:'Status'}],
    company, periodRange, filters,
  };
}

/* Top-level Financial Intelligence KPI rail (Revenue, Net Profit, Net Margin,
   Contribution, Working Capital, Total Exposure). Every figure and record
   below is read straight off the same `pack` the KPI card itself renders
   from (IntelDomains.build('finance', …)) — period, comparison, company and
   cross-filters all already baked in, so the card value, this popup's
   headline and the sum of the records table can never disagree. */
function buildKpiDrill(key, pack){
  const company = !pack.companyId || pack.companyId==='group' ? 'OM Group (All Companies)' : (window.Store && window.Store.name('companies',pack.companyId)) || 'Selected company';
  const periodRange = pack.period.label;
  const cfN = pack.cf ? Object.keys(pack.cf).filter(k=>pack.cf[k]!=null && pack.cf[k]!=='' ).length : 0;
  const filters = cfN ? cfN+' filter'+(cfN===1?'':'s')+' applied' : '';
  const dateCol = { key:'date', label:'Date', render:r=>(window.IntelEngine&&window.IntelEngine.util.fmtD(r.date))||r.date };
  const c = pack.cur, p = pack.prev;
  function varianceCalc(curV, prevV, kind){
    if(prevV==null) return [];
    const d = curV-prevV;
    const pct = prevV!==0 ? (d/Math.abs(prevV)*100) : (curV>0?100:0);
    return [
      { label:'Previous period'+(pack.cmpPeriod?' ('+pack.cmpPeriod.label+')':''), value: prevV, kind: kind||'cur' },
      { label:'Variance', value: d, kind: kind||'cur', color: d>=0?'#15803D':'#DC2626' },
      { label:'Variance %', value: pct, kind:'pct', color: d>=0?'#15803D':'#DC2626' },
    ];
  }
  const financeCols=(partyLabel)=>[dateCol,{key:'ref',label:'Reference'},{key:'party',label:partyLabel},
    {key:'qty',label:'Qty (T)',num:true,render:r=>window.formatQuantity(r.qty)},
    {key:'value',label:'Amount',num:true,render:r=>window.IC.cur(r.value)},
    {key:'status',label:'Status'}];
  const headCols=[dateCol,{key:'head',label:'Head'},{key:'party',label:'Party'},
    {key:'value',label:'Amount',num:true,render:r=>window.IC.cur(r.value)},{key:'status',label:'Status'}];

  if(key==='revenue'){
    const recs=(pack.rows||[]).filter(r=>r.head==='Revenue');
    const qty=recs.reduce((s,r)=>s+(Number(r.qty)||0),0);
    const avg=qty>0?c.revenue/qty:0;
    return { title:'Revenue', subtitle:'Financial Intelligence — '+periodRange, accent:'#16A34A',
      kpis:[{label:'Revenue',value:c.revenue,kind:'cur',color:'#16A34A'},{label:'Sales Orders',value:recs.length,kind:'int'},{label:'Quantity Sold',value:qty,kind:'ton'},{label:'Avg Selling Rate',value:avg,kind:'rate'}],
      calc:[{label:'Gross revenue',value:c.revenue,kind:'cur'},{label:'Sales orders',value:recs.length,kind:'int'},{label:'Quantity sold',value:qty,kind:'ton'},{label:'Average selling rate',value:avg,kind:'rate'}].concat(varianceCalc(c.revenue, p?p.revenue:null)),
      records:recs, columns:financeCols('Customer'), company, periodRange, filters };
  }
  if(key==='netProfit'){
    const d = window.buildWaterfallDrill({label:'Net Profit',value:c.netProfit,color:c.netProfit>=0?'#15803D':'#DC2626',total:true}, pack);
    d.calc = d.calc.concat(varianceCalc(c.netProfit, p?p.netProfit:null));
    return d;
  }
  if(key==='netMargin'){
    return { title:'Net Margin', subtitle:'Financial Intelligence — '+periodRange, accent:'#15803D',
      kpis:[{label:'Net Margin',value:c.netMargin,kind:'pct',color:'#15803D'},{label:'Revenue',value:c.revenue,kind:'cur'},{label:'Net Profit',value:c.netProfit,kind:'cur'},{label:'Records',value:(pack.rows||[]).length,kind:'int'}],
      calc:[{label:'Revenue',value:c.revenue,kind:'cur'},{label:'Net Profit',value:c.netProfit,kind:'cur'},{label:'Net Margin = Net Profit ÷ Revenue',value:c.netMargin,kind:'pct'}].concat(varianceCalc(c.netMargin,p?p.netMargin:null,'pct')),
      records: pack.rows||[], columns:headCols, company, periodRange, filters };
  }
  if(key==='contribution'){
    const recs=(pack.rows||[]).filter(r=>r.head==='Revenue'||r.head==='Purchase Cost'||r.head==='Transport');
    return { title:'Contribution', subtitle:'Revenue less purchase and transport cost — '+periodRange, accent:'#2563EB',
      kpis:[{label:'Contribution',value:c.contribution,kind:'cur',color:'#2563EB'},{label:'Revenue',value:c.revenue,kind:'cur'},{label:'Purchase + Transport',value:(c.purchaseValue||0)+(c.transportCost||0),kind:'cur'},{label:'Contribution Margin',value:c.contributionMargin,kind:'pct'}],
      calc:[{label:'Revenue',value:c.revenue,kind:'cur'},{label:'Purchase Cost',value:-(c.purchaseValue||0),kind:'cur'},{label:'Transport Cost',value:-(c.transportCost||0),kind:'cur'},{label:'Contribution',value:c.contribution,kind:'cur'}].concat(varianceCalc(c.contribution,p?p.contribution:null)),
      records:recs, columns:headCols, company, periodRange, filters };
  }
  if(key==='workingCapital'){
    const recs=(pack.rows||[]).filter(r=>(r.head==='Revenue'||r.head==='Purchase Cost') && r.status==='Pending');
    return { title:'Working Capital', subtitle:'Pending receivable less pending payable — '+periodRange, accent:'#6B7068',
      kpis:[{label:'Working Capital',value:c.workingCapital,kind:'cur'},{label:'Receivable',value:c.receivable,kind:'cur',color:'#DC2626'},{label:'Payable',value:c.payable,kind:'cur',color:'#2563EB'},{label:'Pending Records',value:recs.length,kind:'int'}],
      calc:[{label:'Pending receivable (sales)',value:c.receivable,kind:'cur'},{label:'Pending payable (purchases)',value:-(c.payable||0),kind:'cur'},{label:'Working capital',value:c.workingCapital,kind:'cur'}].concat(varianceCalc(c.workingCapital,p?p.workingCapital:null)),
      records:recs, columns:[dateCol,{key:'head',label:'Type'},{key:'party',label:'Party'},{key:'value',label:'Amount',num:true,render:r=>window.IC.cur(r.value)},{key:'status',label:'Status'}], company, periodRange, filters };
  }
  if(key==='exposure'){
    const recs=(pack.rows||[]).filter(r=>(r.head==='Revenue'&&r.status==='Pending') || (r.head==='Diesel'&&Number(r.unrecovered)>0));
    return { title:'Total Exposure', subtitle:'Pending receivable plus unrecovered diesel — '+periodRange, accent:'#DC2626',
      kpis:[{label:'Total Exposure',value:c.exposure,kind:'cur',color:'#DC2626'},{label:'Receivable',value:c.receivable,kind:'cur'},{label:'Unrecovered Diesel',value:c.dieselUnrecovered,kind:'cur'},{label:'Records',value:recs.length,kind:'int'}],
      calc:[{label:'Pending receivable',value:c.receivable,kind:'cur'},{label:'Unrecovered diesel',value:c.dieselUnrecovered,kind:'cur'},{label:'Total exposure',value:c.exposure,kind:'cur'}].concat(varianceCalc(c.exposure,p?p.exposure:null)),
      records:recs, columns:[dateCol,{key:'head',label:'Type'},{key:'party',label:'Party'},{key:'value',label:'Amount',num:true,render:r=>window.IC.cur(r.value)},{key:'status',label:'Status'}], company, periodRange, filters };
  }
  return null;
}

Object.assign(window, { AFinanceDrill, buildWaterfallDrill, buildKpiDrill });
