/* OM Group ERP — Universal drill-down stack for the Intelligence Center.
   Every node is an "explorer": KPIs → trend → every remaining dimension →
   the underlying ERP records → a single record. Nothing dead-ends.        */
const { useState: idSt, useMemo: idMemo, useEffect: idEf } = React;
const IE = window.IntelEngine;

const ID_DIMS = {
  sales:    [ {k:'material',cf:'materialId'}, {k:'customer',cf:'customerId'}, {k:'crusher',cf:'crusherSite'}, {k:'vehicle',cf:'vehicleFull'}, {k:'status',cf:'status'}, {k:'company',cf:'companyId'} ],
  purchase: [ {k:'material',cf:'materialId'}, {k:'vendor',cf:'vendorId'},     {k:'crusher',cf:'crusherSite'}, {k:'vehicle',cf:'vehicleFull'}, {k:'status',cf:'status'}, {k:'company',cf:'companyId'} ],
};

function idCsv(name, head, rows){
  const esc = v => '"'+String(v==null?'':v).replace(/"/g,'""')+'"';
  const txt=[head.map(esc).join(',')].concat(rows.map(r=>r.map(esc).join(','))).join('\n');
  const a=document.createElement('a');
  a.href=URL.createObjectURL(new Blob(['\ufeff'+txt],{type:'text/csv;charset=utf-8'}));
  a.download=name+'.csv'; document.body.appendChild(a); a.click();
  setTimeout(()=>{ URL.revokeObjectURL(a.href); a.remove(); },400);
  window.toast && window.toast('Exported '+rows.length+' rows','ok');
}

function IDMini({ label, value, kind, color }){
  return <div className="i-mini"><span>{label}</span><b style={color?{color}:null}><window.IC.Num value={value} kind={kind}/></b></div>;
}

function IDRecordRow({ rec, mode, onOpen }){
  const isP = mode==='purchase';
  const qty = isP ? IE.qtyOfPurch(rec) : IE.qtyOfSale(rec);
  const party = isP ? Store.name('vendors', rec.vendorId) : Store.name('customers', rec.customerId);
  return (
    <tr onClick={()=>onOpen(rec)} style={{cursor:'pointer'}}>
      <td>{window.fmtDate?window.fmtDate(rec.date):rec.date}</td>
      <td>{rec.challanNumber||'—'}</td>
      <td style={{maxWidth:180,overflow:'hidden',textOverflow:'ellipsis'}}>{party||'—'}</td>
      <td>{rec.materialId?Store.name('materials',rec.materialId):'Multi'}</td>
      <td className="r">{qty.toFixed(3)}</td>
      <td className="r">{window.IC.cur(window.gAmt(rec))}</td>
      <td>{rec.vehicleFull||'—'}</td>
      <td><span className={'bdg '+(rec.status==='Delivered'?'bg-gn':rec.status==='Cancelled'?'bg-rd':'bg-or')} style={{fontSize:9.5}}>{rec.status||'—'}</span></td>
    </tr>
  );
}

function IDExplore({ node, mode, companyId, onPush }){
  const [tab,setTab]=idSt(null);
  const dims = ID_DIMS[mode].filter(d=>!node.cf || node.cf[d.cf]==null);
  const active = (tab==='records' || (tab && dims.some(d=>d.k===tab))) ? tab : (dims[0] ? dims[0].k : 'records');
  const ds = idMemo(()=>IE.dataset(companyId, node.period, node.cf),[companyId,node.period.from,node.period.to,JSON.stringify(node.cf)]);
  const m = idMemo(()=>IE.metrics(ds),[ds]);
  const ser = idMemo(()=>IE.series(companyId, node.period, node.cf, null),[companyId,node.period.from,node.period.to,JSON.stringify(node.cf)]);
  const recs = mode==='purchase'?ds.purchases:ds.sales;
  const rows = idMemo(()=> active==='records'?[]:IE.splitBy(ds, active, mode),[ds,active,mode]);
  const vk = mode==='purchase'?'purchaseValue':'revenue';
  const color = window.IC.MODE_COLOR[mode];

  const trendVals = ser.points.map(p=>p.m[vk]);
  return (
    <>
      <div className="i-drill-kpis">
        {mode==='purchase' ? [
          <IDMini key="a" label="Purchase Value" value={m.purchaseValue} kind="cur" color="#2563EB"/>,
          <IDMini key="b" label="Quantity" value={m.qtyPurchased} kind="ton"/>,
          <IDMini key="c" label="Avg Rate" value={m.app} kind="rate"/>,
          <IDMini key="d" label="Entries" value={m.pos} kind="int"/>,
        ] : [
          <IDMini key="a" label="Revenue" value={m.revenue} kind="cur" color="#F97316"/>,
          <IDMini key="b" label="Gross Profit" value={m.grossProfit} kind="cur" color={m.grossProfit>=0?'#16A34A':'#DC2626'}/>,
          <IDMini key="c" label="Quantity Sold" value={m.qtySold} kind="ton"/>,
          <IDMini key="d" label="Orders" value={m.orders} kind="int"/>,
        ]}
      </div>

      {ser.points.length>1 && (
        <div className="i-card" style={{marginBottom:12,padding:'12px 14px'}}>
          <div className="i-card-hd">
            <div><div className="i-card-t">Trend inside this selection</div><div className="i-card-s">{ser.grain} buckets · click a point to drill into that window</div></div>
          </div>
          <window.IC.Area height={170} yKind="cur" labels={ser.points.map(p=>p.label)} subLabels={ser.points.map(p=>p.sub)}
            series={[{key:'v',label:mode==='purchase'?'Purchase Value':'Revenue',color,values:trendVals}]}
            onPointClick={i=>onPush({ kind:'explore', label:ser.points[i].period.label, period:ser.points[i].period, cf:node.cf })}/>
        </div>
      )}

      <div style={{display:'flex',gap:6,flexWrap:'wrap',marginBottom:10}}>
        {dims.map(d=>(
          <button key={d.k} className={'i-ctl sm'+(active===d.k?' on':'')} onClick={()=>setTab(d.k)}>
            By {IE.DIMS[d.k].label}
          </button>
        ))}
        <button className={'i-ctl sm'+(active==='records'?' on':'')} onClick={()=>setTab('records')}>
          Records <b style={{marginLeft:3}}>{recs.length}</b>
        </button>
        <button className="i-ctl sm" style={{marginLeft:'auto'}} onClick={()=>{
          idCsv('OM-Analytics-'+(node.label||'drill').replace(/[^\w]+/g,'-'),
            ['Date','Challan','Party','Material','Quantity','Amount','Vehicle','Status'],
            recs.map(r=>[r.date, r.challanNumber||'', mode==='purchase'?Store.name('vendors',r.vendorId):Store.name('customers',r.customerId),
              r.materialId?Store.name('materials',r.materialId):'Multi',
              (mode==='purchase'?IE.qtyOfPurch(r):IE.qtyOfSale(r)).toFixed(3), window.gAmt(r).toFixed(2), r.vehicleFull||'', r.status||'']));
        }}>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>
          Export CSV
        </button>
      </div>

      {active==='records' ? (
        recs.length ? (
          <div style={{overflowX:'auto'}}>
            <table className="i-dl-tbl">
              <thead><tr><th>Date</th><th>Challan</th><th>{mode==='purchase'?'Vendor':'Customer'}</th><th>Material</th><th className="r">Qty (T)</th><th className="r">Amount</th><th>Vehicle</th><th>Status</th></tr></thead>
              <tbody>{recs.slice(0,300).map(r=><IDRecordRow key={r.id} rec={r} mode={mode} onOpen={rec=>onPush({kind:'record',rec,label:(rec.challanNumber||'Record')})}/>)}</tbody>
            </table>
            {recs.length>300 && <div style={{fontSize:10.5,color:'var(--txt3)',padding:'9px 4px'}}>Showing first 300 of {recs.length} records — narrow the period or add a filter to see the rest.</div>}
          </div>
        ) : <window.IC.Empty msg="No records in this selection"/>
      ) : (
        <window.IC.Rank rows={rows} valueKind="cur" limit={40}
          right={r=>window.formatQuantity(r.qty)+' T · '+r.count+(r.count===1?' entry':' entries')}
          onClick={r=>{
            const d=dims.find(x=>x.k===active);
            const cf=Object.assign({}, node.cf||{}); cf[d.cf]=r.id;
            onPush({ kind:'explore', label:r.label, period:node.period, cf });
          }}/>
      )}
    </>
  );
}

function IDRecord({ node, mode }){
  const r=node.rec; const isP=mode==='purchase';
  const g = window.GstEngine.recalcRecord(r);
  const items = r.items && r.items.length ? r.items : [{ materialId:r.materialId, quantity:r.quantity, ratePerTon:r.rate||r.ratePerTon, uom:r.uom }];
  const rows=[
    ['Date', window.fmtDate?window.fmtDate(r.date):r.date],
    [isP?'Vendor':'Customer', isP?Store.name('vendors',r.vendorId):Store.name('customers',r.customerId)],
    ['Challan Number', r.challanNumber||'—'],
    ['Vehicle', r.vehicleFull||'—'],
    ['Status', r.status||'—'],
    ['Company', Store.name('companies', r.companyId)],
  ];
  if(isP && r.royaltyPass) rows.push(['Royalty Pass', r.royaltyPass]);
  if(isP && r.dieselSource) rows.push(['Diesel Source', r.dieselSource+(r.dieselQty?' · '+r.dieselQty+' L':'')]);
  return (
    <>
      <div className="i-drill-kpis">
        <IDMini label="Taxable" value={g.subtotal} kind="cur"/>
        <IDMini label="GST" value={g.gstAmount} kind="cur"/>
        <IDMini label="Total" value={g.total} kind="cur" color={isP?'#2563EB':'#F97316'}/>
        <IDMini label="Quantity" value={isP?IE.qtyOfPurch(r):IE.qtyOfSale(r)} kind="ton"/>
      </div>
      <div className="i-grid i-g2" style={{marginBottom:12}}>
        <div className="i-card" style={{padding:'12px 14px'}}>
          <div className="i-card-t" style={{marginBottom:9}}>{isP?'Purchase':'Sales Order'} details</div>
          <div className="i-dl">
            {rows.map((x,i)=>(<div key={i} style={{display:'flex',justifyContent:'space-between',gap:12,padding:'6px 2px',borderBottom:'1px solid #F6F4F2',fontSize:11.5}}>
              <span style={{color:'var(--txt2)',fontWeight:600}}>{x[0]}</span><b style={{fontWeight:700}}>{x[1]}</b></div>))}
          </div>
        </div>
        <div className="i-card" style={{padding:'12px 14px'}}>
          <div className="i-card-t" style={{marginBottom:9}}>Line items</div>
          <table className="i-dl-tbl">
            <thead><tr><th>Material</th><th className="r">Qty</th><th>UOM</th><th className="r">Rate</th><th className="r">Amount</th></tr></thead>
            <tbody>
              {items.map((it,i)=>{ const q=IE.num(it.quantity), rt=IE.num(it.ratePerTon||it.rate);
                return <tr key={i}><td>{Store.name('materials',it.materialId)}</td><td className="r">{q.toFixed(3)}</td><td>{it.uom||'Ton'}</td><td className="r">₹{rt.toFixed(2)}</td><td className="r">{window.IC.cur(it.subtotal!=null?it.subtotal:(it.amount!=null?it.amount:q*rt))}</td></tr>; })}
            </tbody>
          </table>
        </div>
      </div>
      <div style={{fontSize:10.5,color:'var(--txt3)',lineHeight:1.55,padding:'0 2px'}}>
        This is the original ERP record. GST is recomputed live from each line's taxable amount, so the figures above always reconcile with the {isP?'Purchases':'Sales Orders'} module.
      </div>
    </>
  );
}

function IDPattern({ node, mode, companyId, onPush }){
  const p=node.pat;
  const hist = idMemo(()=>{
    const key = p.dim==='vendor'?'vendorId':'customerId';
    const all = (p.dim==='vendor'?Store.all('purchases',companyId):Store.all('salesOrders',companyId))||[];
    const rs=all.filter(r=>r[key]===p.id).sort((a,b)=>String(a.date).localeCompare(String(b.date)));
    const byM={};
    rs.forEach(r=>{ const ym=String(r.date).slice(0,7); byM[ym]=(byM[ym]||0)+window.gAmt(r); });
    const keys=Object.keys(byM).sort();
    return { recs:rs, labels:keys.map(k=>IE.MON[+k.slice(5,7)-1]+" '"+k.slice(2,4)), values:keys.map(k=>byM[k]) };
  },[p.id,companyId]);
  const color=window.IC.MODE_COLOR[mode];
  return (
    <>
      <div className="i-drill-kpis">
        <IDMini label="Lifetime Value" value={p.lifetimeValue} kind="cur" color={color}/>
        <IDMini label="Typical Cycle" value={p.medianGap} kind="int"/>
        <IDMini label="Avg Quantity" value={p.avgQty} kind="ton"/>
        <IDMini label="Confidence" value={p.confidence} kind="int"/>
      </div>
      <div className="i-card" style={{marginBottom:12,padding:'12px 14px'}}>
        <div className="i-card-hd"><div><div className="i-card-t">Full history</div><div className="i-card-s">Every month this account has transacted · click to open that month</div></div></div>
        <window.IC.Area height={180} yKind="cur" labels={hist.labels} series={[{key:'v',label:'Value',color,values:hist.values}]}/>
      </div>
      <div className="i-card" style={{marginBottom:12,padding:'13px 15px'}}>
        <div className="i-card-t" style={{marginBottom:8}}>Why the system predicts this</div>
        <ul className="i-ins-r" style={{marginTop:0,paddingTop:0,borderTop:0,'--ic':color}}>
          {p.reasons.map((r,i)=><li key={i} style={{'--ic':color}}>{r}</li>)}
        </ul>
        <div style={{marginTop:11,padding:'10px 12px',borderRadius:11,background:'#FCFBFA',border:'1px solid var(--bdr)',display:'grid',gridTemplateColumns:'repeat(auto-fit,minmax(120px,1fr))',gap:9}}>
          {[['Expected next', IE.util.fmtD(p.nextDate)],['Expected quantity', window.formatQuantity(p.avgQty)+' T'],['Expected value', window.IC.short(p.expectedValue)],['Preferred material', p.topMaterialName||'—'],['Cycles observed', String(p.cycles)],['Last activity', p.sinceLast+' days ago']].map((x,i)=>(
            <div key={i}><div style={{fontSize:9,fontWeight:800,letterSpacing:'.07em',textTransform:'uppercase',color:'var(--txt3)'}}>{x[0]}</div><div style={{fontSize:12,fontWeight:800,color:'var(--txt)',marginTop:2}}>{x[1]}</div></div>
          ))}
        </div>
      </div>
      <div style={{overflowX:'auto'}}>
        <table className="i-dl-tbl">
          <thead><tr><th>Date</th><th>Challan</th><th>Material</th><th className="r">Qty (T)</th><th className="r">Amount</th><th>Status</th></tr></thead>
          <tbody>{hist.recs.slice(-60).reverse().map(r=>(
            <tr key={r.id} style={{cursor:'pointer'}} onClick={()=>onPush({kind:'record',rec:r,label:r.challanNumber||'Record'})}>
              <td>{window.fmtDate?window.fmtDate(r.date):r.date}</td><td>{r.challanNumber||'—'}</td>
              <td>{r.materialId?Store.name('materials',r.materialId):'Multi'}</td>
              <td className="r">{(p.dim==='vendor'?IE.qtyOfPurch(r):IE.qtyOfSale(r)).toFixed(3)}</td>
              <td className="r">{window.IC.cur(window.gAmt(r))}</td><td>{r.status||'—'}</td>
            </tr>))}
          </tbody>
        </table>
      </div>
    </>
  );
}

function IDInsight({ node, onPush }){
  const ins=node.ins;
  const col = ins.kind==='risk'?'#DC2626':ins.kind==='opportunity'?'#16A34A':ins.kind==='action'?'#F97316':'#2563EB';
  return (
    <div className="i-card" style={{padding:'16px 18px'}}>
      <span className="i-ins-k" style={{'--ic':col}}>{ins.kind}</span>
      <div className="i-ins-t" style={{fontSize:16,marginTop:10}}>{ins.title}</div>
      <div className="i-ins-d" style={{fontSize:12}}>{ins.detail}</div>
      <div className="i-ins-r" style={{marginTop:13}}>
        {(ins.reasons||[]).map((r,i)=><li key={i} style={{'--ic':col,fontSize:11.5}}>{r}</li>)}
      </div>
    </div>
  );
}

function IDForecast({ node, mode }){
  const fc=node.fc, color=window.IC.MODE_COLOR[mode];
  const n=fc.history.length;
  const labels=(node.labels||[]).concat(fc.points.map((p,i)=>'F+'+(i+1)));
  const hist=fc.history.concat(fc.points.map(()=>null));
  const proj=fc.history.map((v,i)=>i===n-1?v:null).concat(fc.points.map(p=>p.value));
  const hiB=fc.history.map(()=>null).concat(fc.points.map(p=>p.hi));
  return (
    <>
      <div className="i-drill-kpis">
        <IDMini label="Next bucket" value={fc.points[0]?fc.points[0].value:0} kind="cur" color={color}/>
        <IDMini label="Horizon total" value={fc.total||0} kind="cur"/>
        <IDMini label="Confidence" value={fc.confidence} kind="int"/>
        <IDMini label="Trend R²" value={fc.r2*100} kind="int"/>
      </div>
      <div className="i-card" style={{marginBottom:12,padding:'12px 14px'}}>
        <window.IC.Area height={220} yKind="cur" labels={labels} series={[
          {key:'hi',label:'Upper band',color:'#C8C4BF',dashed:true,values:hiB.map(v=>v||0)},
          {key:'h',label:'Actual',color:color,values:hist.map(v=>v||0)},
          {key:'p',label:'Forecast',color:'#7C3AED',dashed:true,values:proj.map(v=>v||0)},
        ]}/>
      </div>
      <div className="i-card" style={{padding:'13px 15px'}}>
        <div className="i-card-t" style={{marginBottom:4}}>{fc.method}</div>
        <div className="i-card-s" style={{marginBottom:9}}>Computed entirely in-browser from this company's own transaction history — no external model, no fabricated numbers.</div>
        <ul className="i-ins-r" style={{marginTop:0,paddingTop:0,borderTop:0}}>
          {fc.reasons.map((r,i)=><li key={i} style={{'--ic':color,fontSize:11.5}}>{r}</li>)}
        </ul>
        <table className="i-dl-tbl" style={{marginTop:12}}>
          <thead><tr><th>Bucket</th><th className="r">Forecast</th><th className="r">Low</th><th className="r">High</th></tr></thead>
          <tbody>{fc.points.map((p,i)=>(<tr key={i}><td>{(node.horizonLabels&&node.horizonLabels[i])||('Next +'+(i+1))}</td><td className="r">{window.IC.cur(p.value)}</td><td className="r">{window.IC.cur(p.lo)}</td><td className="r">{window.IC.cur(p.hi)}</td></tr>))}</tbody>
        </table>
      </div>
    </>
  );
}

function IDHealth({ node }){
  const h=node.health;
  return (
    <>
      <div className="i-card" style={{marginBottom:12,display:'flex',alignItems:'center',gap:22,flexWrap:'wrap'}}>
        <window.IC.Gauge value={h.score} size={200} label={h.grade.toUpperCase()} sub="Business Health"/>
        <div style={{flex:1,minWidth:240}}>
          <window.IC.Radar size={230} axes={h.parts.map(p=>p.label)} series={[{label:'Score',color:'#F97316',values:h.parts.map(p=>p.score/100)}]}/>
        </div>
      </div>
      <div className="i-card">
        <div className="i-card-t" style={{marginBottom:11}}>Every contributing driver</div>
        <div className="i-hp">
          {h.parts.slice().sort((a,b)=>b.score-a.score).map(p=>(
            <div className="i-hp-row" key={p.key}>
              <div className="i-hp-top"><span className="i-hp-l">{p.label}<span className="i-hp-w">{(p.weight*100).toFixed(0)}% weight</span></span><span className="i-hp-v">{p.score.toFixed(0)}</span></div>
              <div className="i-hp-track"><div className="i-hp-fill" style={{width:p.score+'%',background:p.score>=70?'#16A34A':p.score>=50?'#F97316':'#DC2626'}}></div></div>
              <div className="i-hp-d">{p.detail}</div>
            </div>
          ))}
        </div>
      </div>
    </>
  );
}

function IDSeason({ node, mode, onPush }){
  const s=node.seas;
  return (
    <>
      <div className="i-card" style={{marginBottom:12}}>
        <div className="i-card-hd"><div><div className="i-card-t">Monthly seasonality index</div><div className="i-card-s">1.00 = the average month across {s.years} year{s.years===1?'':'s'} of history</div></div></div>
        <window.IC.Bars height={220} yKind="cur" rows={s.index.map(x=>({label:x.label,v:x.value,sub:x.index.toFixed(2)+'×'}))}
          keys={[{key:'v',label:'Total value',color:window.IC.MODE_COLOR[mode]}]}
          onClick={r=>{ const mi=IE.MON.indexOf(r.label); if(mi>=0) onPush({kind:'explore',label:r.label,period:IE.Periods.month(new Date().getFullYear(),mi),cf:{}}); }}/>
      </div>
      <div className="i-card">
        <div className="i-card-t" style={{marginBottom:11}}>Recurring seasonal windows</div>
        <div className="i-dl">
          {s.seasons.map(x=>(
            <div className="i-dl-row" key={x.key} style={{cursor:'default'}}>
              <b>{x.label}</b>
              <em style={{flex:1,fontWeight:500}}>{x.note}</em>
              <i style={{color:x.deltaPct>=0?'#16A34A':'#DC2626'}}>{x.deltaPct>=0?'+':''}{x.deltaPct.toFixed(0)}%</i>
            </div>
          ))}
        </div>
      </div>
    </>
  );
}

function IntelDrill({ stack, mode, companyId, onPush, onPopTo, onClose }){
  const node = stack[stack.length-1];
  idEf(()=>{
    const h=e=>{ if(e.key==='Escape'){ if(stack.length>1) onPopTo(stack.length-2); else onClose(); } };
    document.addEventListener('keydown',h); return ()=>document.removeEventListener('keydown',h);
  },[stack.length]);
  if(!node) return null;
  let body=null;
  if(node.kind==='explore') body=<IDExplore node={node} mode={mode} companyId={companyId} onPush={onPush}/>;
  else if(node.kind==='record') body=<IDRecord node={node} mode={mode}/>;
  else if(node.kind==='pattern') body=<IDPattern node={node} mode={mode} companyId={companyId} onPush={onPush}/>;
  else if(node.kind==='insight') body=<IDInsight node={node} onPush={onPush}/>;
  else if(node.kind==='forecast') body=<IDForecast node={node} mode={mode}/>;
  else if(node.kind==='health') body=<IDHealth node={node}/>;
  else if(node.kind==='season') body=<IDSeason node={node} mode={mode} onPush={onPush}/>;
  return (
    <div className="i-drill-bg" onMouseDown={e=>{ if(e.target===e.currentTarget) onClose(); }}>
      <div className="i-drill">
        <div className="i-drill-hd">
          <div className="i-crumbs">
            {stack.map((s,i)=>(
              <React.Fragment key={i}>
                {i>0 && <span className="i-crumb-sep">›</span>}
                <span className={'i-crumb'+(i===stack.length-1?' cur':'')} onClick={()=>i<stack.length-1&&onPopTo(i)}>{s.label}</span>
              </React.Fragment>
            ))}
          </div>
          <button className="i-drill-x" onClick={onClose} aria-label="Close">×</button>
        </div>
        <div className="i-drill-bd">{body}</div>
      </div>
    </div>
  );
}

Object.assign(window, { IntelDrill, IDMini });
