// OM Group Calendar — Premium Operational Intelligence Calendar v3
// Slide-over panel · Month / Week / Day views · 11-tab drill-down · Fully dynamic
const { useState:cSt, useEffect:cEf, useMemo:cMemo, useRef:cRf } = React;

const CAL_MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December'];
const CAL_DAYS   = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];

const CAL_METRICS = [
  { id:'rev',       label:'Revenue',                fn:d=>d.rev,                         fmt:v=>window.fmtCur(v),      color:'#EA580C' },
  { id:'purchVal',  label:'Purchase Value',         fn:d=>d.purchVal,                    fmt:v=>window.fmtCur(v),      color:'#92400E' },
  { id:'profit',    label:'Gross Profit',           fn:d=>Math.max(0,d.rev-d.purchVal),  fmt:v=>window.fmtCur(v),      color:'#16A34A' },
  { id:'trips',     label:'Total Trips',            fn:d=>d.trips,                       fmt:v=>v+' trips',            color:'#2563EB' },
  { id:'soldTons',  label:'Tons Sold',              fn:d=>d.soldTons,                    fmt:v=>window.formatQuantity(v)+' T',     color:'#374151' },
  { id:'purchTons', label:'Tons Purchased',         fn:d=>d.purchTons,                   fmt:v=>window.formatQuantity(v)+' T',     color:'#374151' },
  { id:'transfers', label:'Internal Transfers',     fn:d=>d.transfers,                   fmt:v=>v+' transfers',        color:'#7C3AED' },
  { id:'transSett', label:'Transport Settlements',  fn:d=>d.transSettCount||0,           fmt:v=>v+' settlements',      color:'#0891B2' },
  { id:'vendSett',  label:'Vendor Settlements',     fn:d=>d.vendSettCount||0,            fmt:v=>v+' settlements',      color:'#7C3AED' },
  { id:'dieselCal', label:'Diesel',                 fn:d=>d.diesel||0,                   fmt:v=>window.fmtCur(v),      color:'#B45309' },
  { id:'stockMov',  label:'Stockyard Movements',    fn:d=>d.stockMoveCount||0,           fmt:v=>v+' movements',        color:'#065F46' },
  { id:'debrisMov', label:'Debris Movements',       fn:d=>d.debrisMovCount||0,           fmt:v=>v+' dispatches',       color:'#6D28D9' },
];

const PANEL_TABS = [
  {id:'overview',label:'Overview'},{id:'companies',label:'Companies'},{id:'materials',label:'Materials'},
  {id:'customers',label:'Customers'},{id:'vendors',label:'Vendors'},{id:'transporters',label:'Transport'},
  {id:'crushers',label:'Crushers'},{id:'vehicles',label:'Vehicles'},{id:'transfers',label:'Transfers'},
  {id:'financial',label:'Financial'},{id:'timeline',label:'Timeline'},
];

function calHeat(t) {
  if (t <= 0)   return { bg:'#F9FAFB', numC:'#CBD5E1', valC:'transparent', border:'#F1F5F9' };
  if (t < 0.05) return { bg:'#FFF7ED', numC:'#374151', valC:'#F97316',     border:'#FED7AA' };
  if (t < 0.20) return { bg:'#FFEDD5', numC:'#7C2D12', valC:'#EA580C',     border:'#FED7AA' };
  if (t < 0.40) return { bg:'#FED7AA', numC:'#7C2D12', valC:'#C2410C',     border:'#FB923C' };
  if (t < 0.65) return { bg:'#FB923C', numC:'#fff',    valC:'#FFF7ED',     border:'#EA580C' };
  if (t < 0.85) return { bg:'#EA580C', numC:'#fff',    valC:'#FFEDD5',     border:'#C2410C' };
  return              { bg:'#9A3412', numC:'#fff',    valC:'#FED7AA',     border:'#7C2D12' };
}

function fmtCompact(v, metricId) {
  if (!v || v <= 0) return null;
  if (['rev','purchVal','profit','dieselCal'].includes(metricId)) {
    if (v >= 10000000) return `₹${(v/10000000).toFixed(1)}Cr`;
    if (v >= 100000)   return `₹${(v/100000).toFixed(1)}L`;
    if (v >= 1000)     return `₹${(v/1000).toFixed(0)}K`;
    return `₹${Math.round(v)}`;
  }
  if (['soldTons','purchTons'].includes(metricId)) return `${Math.round(v)}T`; // compact cell label — full 3-dp value shown on the day popover
  if (metricId==='transSett'||metricId==='vendSett') return `${Math.round(v)} sett`;
  if (metricId==='stockMov')  return `${Math.round(v)} mov`;
  if (metricId==='debrisMov') return `${Math.round(v)} disp`;
  return `${Math.round(v)}`;
}

// ── Hover Tooltip ─────────────────────────────────────────────────────────────
function CalTooltip({ date, data, pos, metric }) {
  const C = window.fmtCur;
  const [yr,mo,dy] = date.split('-');
  const label = `${CAL_DAYS[new Date(date).getDay()]}, ${CAL_MONTHS[+mo-1].slice(0,3)} ${+dy}, ${yr}`;
  const profit = data.rev - data.purchVal;
  const left = Math.max(8, Math.min(pos.x - 117, (window.innerWidth||1200) - 248));
  const showAbove = pos.y > (window.innerHeight||800) * 0.55;
  const NEW_METRICS = ['transSett','vendSett','dieselCal','stockMov','debrisMov'];
  let rows;
  if (metric==='transSett') {
    rows = [['Settlements',data.transSettCount||0,'#0891B2'],['Gross Freight',C(data.transSettGross||0),'#16A34A'],['Diesel Deduction',C(data.transSettDiesel||0),'#B45309'],['Net Payable',C(data.transSettNet||0),'#EA580C'],['Amount Paid',C(data.transSettPaid||0),'#16A34A'],['Outstanding',C(data.transSettOut||0),(data.transSettOut||0)>0?'#DC2626':'#9CA3AF']];
  } else if (metric==='vendSett') {
    rows = [['Settlements',data.vendSettCount||0,'#7C3AED'],['Purchase Value',C(data.vendSettGross||0),'#92400E'],['Diesel Deduction',C(data.vendSettDiesel||0),'#B45309'],['Net Payable',C(data.vendSettNet||0),'#EA580C'],['Amount Paid',C(data.vendSettPaid||0),'#16A34A'],['Outstanding',C(data.vendSettOut||0),(data.vendSettOut||0)>0?'#DC2626':'#9CA3AF']];
  } else if (metric==='dieselCal') {
    rows = [['Transactions',data.dieselCount||0,'#B45309'],['Total Litres',window.formatQuantity((data.dieselLitres||0))+' L','#374151'],['Total Value',C(data.diesel||0),'#EA580C'],['Transport Alloc',C(data.dieselTransAlloc||0),'#2563EB'],['Vendor Alloc',C(data.dieselVendAlloc||0),'#7C3AED']];
  } else if (metric==='stockMov') {
    rows = [['Movements',data.stockMoveCount||0,'#065F46'],['Qty Moved',window.formatQuantity((data.stockMoveQty||0))+' T','#374151'],['Stockyards',data.stockMoveYards||0,'#6B7280'],['Materials',data.stockMoveMats||0,'#9CA3AF']];
  } else if (metric==='debrisMov') {
    rows = [['Dispatches',data.debrisMovCount||0,'#6D28D9'],['Qty Dispatched',window.formatQuantity((data.debrisMovQty||0))+' T','#374151'],['Revenue',C(data.debrisMovRev||0),'#16A34A'],['Customers',data.debrisMovCusts||0,'#9CA3AF']];
  } else {
    rows = [['Revenue',C(data.rev),'#EA580C'],['Purchase',C(data.purchVal),'#78350F'],['Profit',C(profit),profit>=0?'#16A34A':'#DC2626'],['Trips',data.trips,'#2563EB'],['Tons Sold',window.formatQuantity(data.soldTons)+' T','#374151'],['Transfers',data.transfers,'#7C3AED']];
  }
  return (
    <div style={{position:'fixed',left,top:showAbove?pos.y-(rows.length*26+52):pos.bottom+8,zIndex:3000,background:'#fff',border:'1px solid #E5E7EB',borderRadius:14,boxShadow:'0 8px 32px rgba(0,0,0,.13)',padding:'12px 14px',width:236,pointerEvents:'none',animation:'calTipIn .12s ease'}}>
      <div style={{fontSize:11.5,fontWeight:700,color:'#111827',marginBottom:8,paddingBottom:7,borderBottom:'1px solid #F3F4F6'}}>{label}</div>
      <div style={{display:'flex',flexDirection:'column',gap:5}}>
        {rows.map(([l,v,c])=>(
          <div key={l} style={{display:'flex',justifyContent:'space-between',alignItems:'center'}}>
            <span style={{fontSize:11,color:'#9CA3AF'}}>{l}</span>
            <span style={{fontSize:11.5,fontWeight:700,color:c}}>{v}</span>
          </div>
        ))}
      </div>
      <div style={{marginTop:8,paddingTop:7,borderTop:'1px solid #F3F4F6',fontSize:10,color:'#C0CAD6',textAlign:'center'}}>Click to {NEW_METRICS.includes(metric)?'open module':'open full daily report'}</div>
    </div>
  );
}

// ── Ranked Table used inside panel tabs ───────────────────────────────────────
function RankedTable({ rows, nameFn, subFn, valueFn, valueFmtFn, emptyText }) {
  if (!rows || !rows.length) {
    return <div style={{padding:'32px',textAlign:'center',color:'#9CA3AF',fontSize:12}}>{emptyText||'No data for this day'}</div>;
  }
  const maxV = Math.max(...rows.map(valueFn), 0.001);
  const RANK = ['#EA580C','#C2410C','#9A3412','#78350F','#6B7280','#4B5563','#374151'];
  return (
    <div style={{display:'flex',flexDirection:'column',gap:1}}>
      {rows.map((row,i) => {
        const v   = valueFn(row);
        const pct = maxV > 0 ? v / maxV * 100 : 0;
        const c   = RANK[Math.min(i, RANK.length-1)];
        return (
          <div key={i} style={{display:'flex',alignItems:'center',gap:9,padding:'8px 10px',borderRadius:10,transition:'background .1s',cursor:'default'}}
            onMouseEnter={e=>e.currentTarget.style.background='#FFF7ED'}
            onMouseLeave={e=>e.currentTarget.style.background=''}>
            <div style={{width:24,height:24,borderRadius:7,background:c+'14',display:'flex',alignItems:'center',justifyContent:'center',fontSize:10,fontWeight:700,color:c,flexShrink:0}}>{i+1}</div>
            <div style={{flex:1,minWidth:0}}>
              <div style={{fontSize:12,fontWeight:600,color:'#374151',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{nameFn(row)}</div>
              {subFn&&<div style={{fontSize:10.5,color:'#9CA3AF',marginTop:1}}>{subFn(row)}</div>}
            </div>
            <div style={{textAlign:'right',flexShrink:0}}>
              <div style={{fontSize:12.5,fontWeight:700,color:c,whiteSpace:'nowrap'}}>{valueFmtFn ? valueFmtFn(v,row) : v}</div>
              <window.PremiumProgress pct={Math.min(100,pct)} color={c} height={4} style={{width:56,marginTop:4,marginLeft:'auto'}} />
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ── Day Slide-Over Panel ──────────────────────────────────────────────────────
function CalDayPanel({ date, activeFilters, onClose, isMobile }) {
  const C = window.fmtCur;
  const [tab, setTab] = cSt('overview');
  const tabRef = cRf();

  // ── Issue 4: Mouse-scroll tab strip (wheel + click-drag) ─────────────────
  cEf(() => {
    const el = tabRef.current;
    if (!el) return;
    // Wheel: scroll horizontally (Shift+Wheel or native horizontal wheel)
    function onWheel(e) {
      e.preventDefault();
      el.scrollLeft += e.shiftKey ? e.deltaY : (Math.abs(e.deltaX) > Math.abs(e.deltaY) ? e.deltaX : e.deltaY);
    }
    // Drag: grab & scroll
    let dragging = false, startX = 0, startScroll = 0, moved = false;
    function onMD(e) {
      if (e.button !== 0 || e.target.tagName === 'BUTTON') return;
      dragging = true; moved = false;
      startX = e.clientX; startScroll = el.scrollLeft;
      el.style.cursor = 'grabbing';
    }
    function onMM(e) {
      if (!dragging) return;
      const dx = e.clientX - startX;
      if (Math.abs(dx) > 4) { moved = true; el.scrollLeft = startScroll - dx; }
    }
    function onMU() {
      if (!dragging) return;
      dragging = false;
      el.style.cursor = 'grab';
    }
    el.style.cursor = 'grab';
    el.addEventListener('wheel', onWheel, { passive: false });
    el.addEventListener('mousedown', onMD);
    document.addEventListener('mousemove', onMM);
    document.addEventListener('mouseup', onMU);
    return () => {
      el.removeEventListener('wheel', onWheel);
      el.removeEventListener('mousedown', onMD);
      document.removeEventListener('mousemove', onMM);
      document.removeEventListener('mouseup', onMU);
      if (el) el.style.cursor = '';
    };
  }, []);

  const { fCo='', fMat='', fVend='', fCust='', fCrush='' } = activeFilters || {};

  // Raw data pull
  const allS  = Store.all('salesOrders');
  const allP  = Store.all('purchases');
  const allT  = Store.all('transportEntries');
  const allTr = Store.all('internalTransfers');

  const dayS  = allS.filter(s => s.date===date && (!fCo||s.companyId===fCo) && (!fMat||s.materialId===fMat) && (!fCust||s.customerId===fCust));
  const dayP  = allP.filter(p => p.date===date && (!fCo||p.companyId===fCo) && (!fVend||p.vendorId===fVend) && (!fMat||(p.items||[]).some(i=>i.materialId===fMat)||p.materialId===fMat) && (!fCrush||(p.items||[]).some(i=>i.crusherSite===fCrush)));
  const dayT  = allT.filter(t => t.date===date && (!fCo||t.companyId===fCo));
  const dayTr = allTr.filter(t => t.date===date && (!fCo||t.sourceCompanyId===fCo||t.destCompanyId===fCo));

  // KPI totals
  const rev       = dayS.reduce((s,o)=>s+(window.gAmt(o)), 0);
  const purchVal  = dayP.reduce((s,p)=>s+(window.gAmt(p)), 0);
  const profit    = rev - purchVal;
  const soldTons  = dayS.reduce((s,o)=>s+(parseFloat(o.quantity)||0), 0);
  const purchTons = dayP.reduce((s,p)=>s+((p.items&&p.items.length)?p.items.reduce((a,i)=>a+(parseFloat(i.quantity)||0),0):(parseFloat(p.quantity)||0)), 0);
  const trips     = dayS.length + dayP.length + dayT.length;
  const uniqVehs  = new Set([...dayS.map(s=>s.vehicleFull),...dayP.map(p=>p.vehicleFull),...dayT.map(t=>t.vehicleFull||t.vehicleNum)].filter(Boolean)).size;

  // Company map
  const coMap = {};
  dayS.forEach(s=>{ const k=Store.name('companies',s.companyId)||'—'; if(!coMap[k])coMap[k]={name:k,rev:0,purchVal:0,saleTrips:0,purchTrips:0}; coMap[k].rev+=window.gAmt(s); coMap[k].saleTrips++; });
  dayP.forEach(p=>{ const k=Store.name('companies',p.companyId)||'—'; if(!coMap[k])coMap[k]={name:k,rev:0,purchVal:0,saleTrips:0,purchTrips:0}; coMap[k].purchVal+=window.gAmt(p); coMap[k].purchTrips++; });
  const coRows = Object.values(coMap).map(r=>({...r,profit:r.rev-r.purchVal})).sort((a,b)=>b.rev-a.rev);

  // Material map
  const matMap = {};
  dayS.forEach(s=>{ const k=Store.name('materials',s.materialId)||'Unknown'; if(!matMap[k])matMap[k]={name:k,saleRev:0,saleQty:0,saleTrips:0,purchVal:0,purchQty:0,purchTrips:0}; matMap[k].saleRev+=window.gAmt(s); matMap[k].saleQty+=parseFloat(s.quantity)||0; matMap[k].saleTrips++; });
  dayP.forEach(p=>{ if(p.items&&p.items.length){p.items.forEach(item=>{ const k=Store.name('materials',item.materialId)||'Unknown'; if(!matMap[k])matMap[k]={name:k,saleRev:0,saleQty:0,saleTrips:0,purchVal:0,purchQty:0,purchTrips:0}; matMap[k].purchVal+=window.gItemAmt(item); matMap[k].purchQty+=parseFloat(item.quantity)||0; matMap[k].purchTrips++; });}else{ const k=Store.name('materials',p.materialId)||'Unknown'; if(!matMap[k])matMap[k]={name:k,saleRev:0,saleQty:0,saleTrips:0,purchVal:0,purchQty:0,purchTrips:0}; matMap[k].purchVal+=window.gAmt(p); matMap[k].purchQty+=parseFloat(p.quantity)||0; matMap[k].purchTrips++; } });
  const matRows = Object.values(matMap).sort((a,b)=>b.saleRev-a.saleRev);

  // Customer map
  const custMap = {};
  dayS.forEach(s=>{ const k=Store.name('customers',s.customerId)||'—'; if(!custMap[k])custMap[k]={name:k,rev:0,qty:0,orders:0}; custMap[k].rev+=window.gAmt(s); custMap[k].qty+=parseFloat(s.quantity)||0; custMap[k].orders++; });
  const custRows = Object.values(custMap).sort((a,b)=>b.rev-a.rev);

  // Vendor map
  const vendMap = {};
  dayP.forEach(p=>{ const k=Store.name('vendors',p.vendorId)||'—'; if(!vendMap[k])vendMap[k]={name:k,value:0,qty:0,trips:0}; vendMap[k].value+=window.gAmt(p); vendMap[k].qty+=(p.items&&p.items.length)?p.items.reduce((a,i)=>a+(parseFloat(i.quantity)||0),0):(parseFloat(p.quantity)||0); vendMap[k].trips++; });
  const vendRows = Object.values(vendMap).sort((a,b)=>b.value-a.value);

  // Crusher map
  const crMap = {};
  dayP.forEach(p=>{ (p.items||[]).forEach(item=>{ const k=item.crusherSite?Store.name('crushers',item.crusherSite)||item.crusherSite:null; if(!k)return; if(!crMap[k])crMap[k]={name:k,trips:0,qty:0,value:0}; crMap[k].trips++; crMap[k].qty+=parseFloat(item.quantity)||0; crMap[k].value+=window.gItemAmt(item); }); });
  const crRows = Object.values(crMap).sort((a,b)=>b.value-a.value);

  // Vehicle map
  const vehMap = {};
  dayS.forEach(s=>{ const k=s.vehicleFull; if(!k)return; if(!vehMap[k])vehMap[k]={name:k,trips:0,qty:0,rev:0}; vehMap[k].trips++; vehMap[k].qty+=parseFloat(s.quantity)||0; vehMap[k].rev+=window.gAmt(s); });
  dayP.forEach(p=>{ const k=p.vehicleFull; if(!k)return; if(!vehMap[k])vehMap[k]={name:k,trips:0,qty:0,rev:0}; vehMap[k].trips++; vehMap[k].qty+=(p.items&&p.items.length)?p.items.reduce((a,i)=>a+(parseFloat(i.quantity)||0),0):(parseFloat(p.quantity)||0); });
  dayT.forEach(t=>{ const k=t.vehicleFull||t.vehicleNum; if(!k)return; if(!vehMap[k])vehMap[k]={name:k,trips:0,qty:0,rev:0}; vehMap[k].trips++; vehMap[k].qty+=parseFloat(t.quantity)||0; });
  const vehRows = Object.values(vehMap).sort((a,b)=>b.trips-a.trips);

  // Transporter map
  const trspMap = {};
  const resolveTr = r => { const id=r.transporterId||''; const nm=(r.transporter&&r.transporter!=='—')?r.transporter:(id?Store.name('transportersList',id)||id:''); return nm||null; };
  [...dayS,...dayP,...dayT].forEach(r=>{ const k=resolveTr(r); if(!k)return; if(!trspMap[k])trspMap[k]={name:k,trips:0,qty:0}; trspMap[k].trips++; trspMap[k].qty+=parseFloat(r.quantity)||(r.items||[]).reduce((a,i)=>a+(parseFloat(i.quantity)||0),0); });
  const trspRows = Object.values(trspMap).sort((a,b)=>b.trips-a.trips);

  // Timeline
  const timeline = [
    ...dayS.map(s=>({type:'Sale',    tc:'#16A34A',party:Store.name('customers',s.customerId)||'—',  mat:Store.name('materials',s.materialId)||'—',    veh:s.vehicleFull||'—',co:Store.name('companies',s.companyId)||'—',  ref:s.challanNumber||'—',    qty:parseFloat(s.quantity)||0,   amt:window.gAmt(s)})),
    ...dayP.map(p=>({type:'Purchase',tc:'#EA580C',party:Store.name('vendors',p.vendorId)||'—',      mat:p.items&&p.items[0]?Store.name('materials',p.items[0].materialId||p.materialId)||'—':Store.name('materials',p.materialId)||'—',veh:p.vehicleFull||'—',co:Store.name('companies',p.companyId)||'—',ref:p.challanNumber||'—',qty:(p.items&&p.items.length)?p.items.reduce((a,i)=>a+(parseFloat(i.quantity)||0),0):(parseFloat(p.quantity)||0),amt:window.gAmt(p)})),
    ...dayTr.map(t=>({type:'Transfer',tc:'#7C3AED',party:Store.name('companies',t.destCompanyId)||'—',mat:(t.items&&t.items[0])?Store.name('materials',t.items[0].materialId)||'—':'—',veh:t.vehicleFull||t.vehicle||'—',co:Store.name('companies',t.sourceCompanyId||t.companyId)||'—',ref:t.challanNumber||t.referenceNumber||'—',qty:(t.items||[]).reduce((a,i)=>a+(parseFloat(i.quantity)||0),0),amt:t.totalValue||0})),
    ...dayT.map(t=>({type:'Transport',tc:'#2563EB',party:resolveTr(t)||'—',mat:'—',veh:t.vehicleFull||t.vehicleNum||'—',co:Store.name('companies',t.companyId)||'—',ref:t.challanNumber||'—',qty:parseFloat(t.quantity)||0,amt:0})),
  ].sort((a,b)=>a.ref.localeCompare(b.ref));

  const [yr,mo,dy_] = date.split('-');
  const shortDate   = `${CAL_DAYS[new Date(date).getDay()]}, ${CAL_MONTHS[+mo-1]} ${+dy_}`;

  function TabContent() {
    switch(tab) {
      case 'overview': return (
        <div>
          <div className="dd-2col" style={{gap:8,marginBottom:14}}>
            {[['Revenue',C(rev),'#EA580C'],['Purchase',C(purchVal),'#92400E'],
              ['Gross Profit',C(profit),profit>=0?'#16A34A':'#DC2626'],['Trips',trips,'#2563EB'],
              ['Tons Sold',window.formatQuantity(soldTons)+' T','#374151'],['Tons Purchased',window.formatQuantity(purchTons)+' T','#374151'],
              ['Vehicles',uniqVehs,'#6B7280'],['Transfers',dayTr.length,'#7C3AED'],
            ].map(([l,v,c])=>(
              <div key={l} style={{background:'#F9FAFB',borderRadius:12,padding:'12px 13px',border:'1px solid #F3F4F6'}}>
                <div style={{fontSize:14,fontWeight:800,color:c,lineHeight:1.2}}>{v}</div>
                <div style={{fontSize:10.5,color:'#9CA3AF',marginTop:4}}>{l}</div>
              </div>
            ))}
          </div>
          {rev>0&&(
            <div style={{background:'#F9FAFB',borderRadius:12,padding:'13px',border:'1px solid #F3F4F6',marginBottom:14}}>
              <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:8}}>
                <span style={{fontSize:11.5,fontWeight:600,color:'#374151'}}>Profit Margin</span>
                <span style={{fontSize:15,fontWeight:800,color:profit>=0?'#16A34A':'#DC2626'}}>{(profit/rev*100).toFixed(1)}%</span>
              </div>
              <window.PremiumProgress pct={Math.max(0,Math.min(100,profit/rev*100))} color={profit>=0?'#16A34A':'#DC2626'} height={8} />
              {soldTons>0&&<div style={{fontSize:10.5,color:'#9CA3AF',marginTop:6}}>Avg rate: {C(rev/soldTons)}/T</div>}
            </div>
          )}
          {coRows.length>0&&(
            <>
              <div style={{fontSize:12,fontWeight:700,color:'#374151',marginBottom:6,marginTop:2}}>Companies Active</div>
              <RankedTable rows={coRows} nameFn={r=>r.name} subFn={r=>`${r.saleTrips} sales · ${r.purchTrips} purchases`} valueFn={r=>r.rev} valueFmtFn={v=>C(v)}/>
            </>
          )}
        </div>
      );

      case 'companies': return (
        <div>
          {!coRows.length?<div style={{padding:'32px',textAlign:'center',color:'#9CA3AF',fontSize:12}}>No company activity this day</div>:
          coRows.map((co,i)=>{
            const RANK=['#EA580C','#C2410C','#9A3412','#78350F','#6B7280'];
            const c=RANK[Math.min(i,4)];
            return (
              <div key={co.name} style={{padding:'13px',borderRadius:12,background:'#FAFAFA',border:'1px solid #F3F4F6',marginBottom:8}}>
                <div style={{display:'flex',alignItems:'center',gap:8,marginBottom:9}}>
                  <div style={{width:28,height:28,borderRadius:8,background:c+'14',display:'flex',alignItems:'center',justifyContent:'center',fontSize:11,fontWeight:700,color:c,flexShrink:0}}>{i+1}</div>
                  <div style={{flex:1,minWidth:0}}>
                    <div style={{fontSize:13,fontWeight:700,color:'#111827',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{co.name}</div>
                    <div style={{fontSize:10.5,color:'#9CA3AF'}}>{co.saleTrips+co.purchTrips} trips · {co.saleTrips} sales · {co.purchTrips} purchases</div>
                  </div>
                  <div style={{textAlign:'right',flexShrink:0}}>
                    <div style={{fontSize:14,fontWeight:800,color:c}}>{C(co.rev)}</div>
                    <div style={{fontSize:9.5,color:'#9CA3AF'}}>Revenue</div>
                  </div>
                </div>
                <div style={{display:'grid',gridTemplateColumns:'1fr 1fr 1fr',gap:5}}>
                  {[['Purchase',C(co.purchVal),'#78350F'],['Profit',C(co.profit),co.profit>=0?'#16A34A':'#DC2626'],['Margin',co.rev>0?(co.profit/co.rev*100).toFixed(1)+'%':'—','#6B7280']].map(([l,v,vc])=>(
                    <div key={l} style={{background:'#fff',borderRadius:8,padding:'7px 9px',border:'1px solid #F3F4F6',textAlign:'center'}}>
                      <div style={{fontSize:12.5,fontWeight:700,color:vc}}>{v}</div>
                      <div style={{fontSize:9.5,color:'#9CA3AF',marginTop:2}}>{l}</div>
                    </div>
                  ))}
                </div>
              </div>
            );
          })}
        </div>
      );

      case 'materials': return (
        <RankedTable rows={matRows} nameFn={r=>r.name} subFn={r=>`${r.saleTrips} sales · ${r.purchTrips} purchases · ${window.formatQuantity(r.saleQty)} T sold`} valueFn={r=>r.saleRev} valueFmtFn={v=>C(v)} emptyText="No material activity this day"/>
      );

      case 'customers': return (
        <RankedTable rows={custRows} nameFn={r=>r.name} subFn={r=>`${r.orders} orders · ${window.formatQuantity(r.qty)} T`} valueFn={r=>r.rev} valueFmtFn={v=>C(v)} emptyText="No customer activity this day"/>
      );

      case 'vendors': return (
        <RankedTable rows={vendRows} nameFn={r=>r.name} subFn={r=>`${r.trips} trips · ${window.formatQuantity(r.qty)} T`} valueFn={r=>r.value} valueFmtFn={v=>C(v)} emptyText="No vendor activity this day"/>
      );

      case 'transporters': return (
        <RankedTable rows={trspRows} nameFn={r=>r.name} subFn={r=>`${window.formatQuantity(r.qty)} T moved`} valueFn={r=>r.trips} valueFmtFn={v=>v+' trips'} emptyText="No transporter activity this day"/>
      );

      case 'crushers': return (
        <RankedTable rows={crRows} nameFn={r=>r.name} subFn={r=>`${r.trips} trips · ${window.formatQuantity(r.qty)} T`} valueFn={r=>r.value} valueFmtFn={v=>C(v)} emptyText="No crusher activity this day"/>
      );

      case 'vehicles': return (
        <RankedTable rows={vehRows} nameFn={r=>r.name} subFn={r=>`${window.formatQuantity(r.qty)} T · ${C(r.rev)} revenue`} valueFn={r=>r.trips} valueFmtFn={v=>v+' trips'} emptyText="No vehicle activity this day"/>
      );

      case 'transfers': return (
        <div>
          {!dayTr.length
            ? <div style={{padding:'32px',textAlign:'center',color:'#9CA3AF',fontSize:12}}>No internal transfers this day</div>
            : dayTr.map((t,i)=>{
                const from = Store.name('companies',t.sourceCompanyId||t.companyId)||'—';
                const to   = Store.name('companies',t.destCompanyId)||'—';
                const mat  = (t.items&&t.items[0])?Store.name('materials',t.items[0].materialId)||'—':'—';
                const qty  = (t.items||[]).reduce((a,ii)=>a+(parseFloat(ii.quantity)||0),0);
                const val  = t.totalValue||0;
                const ref  = t.challanNumber||t.referenceNumber||'—';
                const veh  = t.vehicleFull||t.vehicle||'—';
                const tDateRaw = t.date||date;
                const [tYr,tMo,tDy] = tDateRaw.split('-');
                const tDate = tDateRaw ? `${+tDy} ${CAL_MONTHS[+tMo-1]?.slice(0,3)||''} ${tYr}` : '—';
                const detailRows = [
                  {l:'Material',  v:mat,            c:'#374151', mono:false},
                  {l:'Quantity',  v:window.formatQuantity(qty)+' T', c:'#111827', mono:false},
                  ...(val>0     ? [{l:'Transfer Value', v:C(val),   c:'#7C3AED', mono:false}] : []),
                  {l:'Date',      v:tDate,           c:'#374151', mono:false},
                  ...(veh!=='—' ? [{l:'Vehicle',    v:veh,          c:'#374151', mono:true}]  : []),
                  ...(ref!=='—' ? [{l:'Challan',    v:ref,          c:'#374151', mono:true}]  : []),
                ];
                return (
                  <div key={i} style={{borderRadius:12,background:'#F9FAFB',border:'1px solid #F3F4F6',marginBottom:10,overflow:'hidden'}}>
                    {/* Source → Destination header */}
                    <div style={{padding:'12px 14px',background:'#fff',borderBottom:'1px solid #F3F4F6'}}>
                      <div style={{display:'flex',alignItems:'center',gap:10}}>
                        {/* From */}
                        <div style={{flex:1,minWidth:0}}>
                          <div style={{fontSize:9.5,fontWeight:700,color:'#9CA3AF',textTransform:'uppercase',letterSpacing:'.07em',marginBottom:3}}>From</div>
                          <div style={{fontSize:13,fontWeight:800,color:'#111827',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{from}</div>
                        </div>
                        {/* Arrow connector */}
                        <div style={{display:'flex',flexDirection:'column',alignItems:'center',gap:0,flexShrink:0}}>
                          <div style={{width:1,height:10,background:'#DDD6FE'}}></div>
                          <div style={{width:24,height:24,borderRadius:'50%',background:'#EDE9FE',border:'1px solid #DDD6FE',display:'flex',alignItems:'center',justifyContent:'center'}}>
                            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#7C3AED" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                              <line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/>
                            </svg>
                          </div>
                          <div style={{width:1,height:10,background:'#DDD6FE'}}></div>
                        </div>
                        {/* To */}
                        <div style={{flex:1,minWidth:0,textAlign:'right'}}>
                          <div style={{fontSize:9.5,fontWeight:700,color:'#7C3AED',textTransform:'uppercase',letterSpacing:'.07em',marginBottom:3}}>To</div>
                          <div style={{fontSize:13,fontWeight:800,color:'#7C3AED',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{to}</div>
                        </div>
                      </div>
                    </div>
                    {/* Detail grid */}
                    <div style={{padding:'10px 14px',display:'grid',gridTemplateColumns:'1fr 1fr',gap:'8px 14px'}}>
                      {detailRows.map(({l,v,c,mono})=>(
                        <div key={l}>
                          <div style={{fontSize:9.5,color:'#9CA3AF',fontWeight:600,textTransform:'uppercase',letterSpacing:'.05em'}}>{l}</div>
                          <div style={{fontSize:12,fontWeight:600,color:c,marginTop:2,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',fontFamily:'var(--font)'}}>{v}</div>
                        </div>
                      ))}
                    </div>
                  </div>
                );
              })
          }
        </div>
      );

      case 'financial': return (
        <div>
          <div style={{background:'#F9FAFB',borderRadius:12,padding:'14px',border:'1px solid #F3F4F6',marginBottom:12}}>
            <div style={{fontSize:10.5,fontWeight:700,color:'#9CA3AF',textTransform:'uppercase',letterSpacing:'.06em',marginBottom:10}}>P &amp; L Summary</div>
            {[['Revenue',C(rev),'#EA580C',true],['Purchase Cost',C(purchVal),'#78350F',false],['Gross Profit',C(profit),profit>=0?'#16A34A':'#DC2626',true],['Margin',rev>0?(profit/rev*100).toFixed(2)+'%':'—',profit>=0?'#16A34A':'#DC2626',false],['Tons Sold',soldTons.toFixed(3)+' T','#374151',false],['Tons Purchased',purchTons.toFixed(3)+' T','#374151',false],['Avg Rate/Ton',soldTons>0?C(rev/soldTons)+'/T':'—','#6B7280',false]].map(([l,v,c,b],idx,arr)=>(
              <div key={l} style={{display:'flex',justifyContent:'space-between',alignItems:'center',padding:'8px 0',borderBottom:idx<arr.length-1?'1px solid #F3F4F6':'none'}}>
                <span style={{fontSize:12,color:'#6B7280'}}>{l}</span>
                <span style={{fontSize:12.5,fontWeight:b?800:600,color:c}}>{v}</span>
              </div>
            ))}
          </div>
          {rev>0&&(
            <div style={{background:'#F9FAFB',borderRadius:12,padding:'14px',border:'1px solid #F3F4F6'}}>
              <div style={{fontSize:10.5,fontWeight:700,color:'#9CA3AF',textTransform:'uppercase',letterSpacing:'.06em',marginBottom:10}}>Revenue Breakdown</div>
              <div style={{height:28,borderRadius:999,overflow:'hidden',display:'flex',background:'#EDEBE7',boxShadow:'inset 0 1px 1.5px rgba(28,20,10,.07), inset 0 0 0 0.5px rgba(28,20,10,.05)',marginBottom:8}}>
                <div style={{width:`${Math.min(100,purchVal/rev*100)}%`,background:'#FED7AA',display:'flex',alignItems:'center',justifyContent:'center',transition:'width .5s'}}>
                  {(purchVal/rev)>0.15&&<span style={{fontSize:9,fontWeight:700,color:'#78350F'}}>Cost</span>}
                </div>
                <div style={{flex:1,background:'#DCFCE7',display:'flex',alignItems:'center',justifyContent:'center'}}>
                  {(profit/rev)>0.08&&<span style={{fontSize:9,fontWeight:700,color:'#16A34A'}}>Profit</span>}
                </div>
              </div>
              <div style={{display:'flex',gap:14,justifyContent:'center'}}>
                <span style={{fontSize:10.5,color:'#78350F'}}>● Cost {(purchVal/rev*100).toFixed(1)}%</span>
                <span style={{fontSize:10.5,color:'#16A34A'}}>● Profit {Math.max(0,profit/rev*100).toFixed(1)}%</span>
              </div>
            </div>
          )}
        </div>
      );

      case 'timeline': return (
        <div>
          {!timeline.length?<div style={{padding:'32px',textAlign:'center',color:'#9CA3AF',fontSize:12}}>No activity recorded</div>:
          <div style={{display:'flex',flexDirection:'column'}}>
            {timeline.map((t,i)=>(
              <div key={i} style={{display:'flex',gap:10,padding:'9px 0',borderBottom:i<timeline.length-1?'1px solid #F9FAFB':'none'}}>
                <div style={{display:'flex',flexDirection:'column',alignItems:'center',flexShrink:0}}>
                  <div style={{width:8,height:8,borderRadius:'50%',background:t.tc,marginTop:5,flexShrink:0}}/>
                  {i<timeline.length-1&&<div style={{width:1,flex:1,background:'#F3F4F6',marginTop:2}}/>}
                </div>
                <div style={{flex:1,minWidth:0,paddingBottom:2}}>
                  <div style={{display:'flex',alignItems:'center',gap:6,marginBottom:2,flexWrap:'wrap'}}>
                    <span style={{fontSize:9.5,fontWeight:700,color:t.tc,background:t.tc+'12',padding:'1px 6px',borderRadius:4,flexShrink:0}}>{t.type.toUpperCase()}</span>
                    <span style={{fontSize:10.5,color:'#9CA3AF',fontFamily:'var(--font)',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{t.ref}</span>
                    <span style={{fontSize:10,color:'#D1D5DB',marginLeft:'auto',flexShrink:0}}>{t.co}</span>
                  </div>
                  <div style={{fontSize:12,fontWeight:600,color:'#374151',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{t.party}</div>
                  <div style={{fontSize:11,color:'#9CA3AF',marginTop:1,display:'flex',gap:6,flexWrap:'wrap'}}>
                    {t.mat!=='—'&&<span>{t.mat}</span>}
                    {t.veh!=='—'&&<><span>·</span><span>{t.veh}</span></>}
                  </div>
                  <div style={{fontSize:12,fontWeight:700,color:'#374151',marginTop:2}}>
                    {t.qty>0&&<span>{window.formatQuantity(t.qty)} T</span>}
                    {t.amt>0&&<span style={{color:'#EA580C',marginLeft:8}}>{C(t.amt)}</span>}
                  </div>
                </div>
              </div>
            ))}
          </div>}
        </div>
      );

      default: return null;
    }
  }

  const panelW = isMobile ? '100%' : '460px';

  return (
    <>
      <div style={{position:'fixed',inset:0,background:'rgba(17,24,39,.28)',zIndex:490,animation:'calBdIn .22s ease'}} onClick={onClose}/>
      <div style={{position:'fixed',right:0,top:0,bottom:0,width:panelW,background:'#fff',zIndex:491,display:'flex',flexDirection:'column',boxShadow:'-2px 0 48px rgba(0,0,0,.14)',animation:'calPanelIn .28s cubic-bezier(.25,.46,.45,.94)'}}>

        {/* Header */}
        <div style={{padding:'18px 20px 0',flexShrink:0}}>
          <div style={{display:'flex',alignItems:'flex-start',justifyContent:'space-between',marginBottom:12}}>
            <div>
              <div style={{fontSize:10.5,fontWeight:700,color:'#9CA3AF',textTransform:'uppercase',letterSpacing:'.08em',marginBottom:3}}>Daily Intelligence Report</div>
              <div style={{fontSize:22,fontWeight:800,color:'#111827',letterSpacing:'-0.025em',lineHeight:1.1}}>{shortDate}</div>
              <div style={{fontSize:11.5,color:'#9CA3AF',marginTop:3}}>{yr} · {trips} trips · {coRows.length} companies active</div>
            </div>
            <button onClick={onClose} style={{width:32,height:32,borderRadius:10,border:'1.5px solid #E5E7EB',background:'#F9FAFB',cursor:'pointer',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0,marginTop:2,transition:'all .15s'}}
              onMouseEnter={e=>{e.currentTarget.style.background='#FEE2E2';e.currentTarget.style.borderColor='#EF4444';}}
              onMouseLeave={e=>{e.currentTarget.style.background='#F9FAFB';e.currentTarget.style.borderColor='#E5E7EB';}}>
              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M18 6L6 18M6 6l12 12"/></svg>
            </button>
          </div>

          {/* Quick KPIs */}
          <div style={{display:'flex',gap:6,marginBottom:12}}>
            {[[C(rev),'Revenue','#EA580C'],[C(profit),profit>=0?'Profit':'Loss',profit>=0?'#16A34A':'#DC2626'],[trips+' trips','Activity','#2563EB']].map(([v,l,c])=>(
              <div key={l} style={{flex:1,background:'#F9FAFB',borderRadius:10,padding:'9px 10px',border:'1px solid #F3F4F6'}}>
                <div style={{fontSize:13,fontWeight:800,color:c,lineHeight:1.2}}>{v}</div>
                <div style={{fontSize:9.5,color:'#9CA3AF',marginTop:3}}>{l}</div>
              </div>
            ))}
          </div>

          {/* Tab bar */}
          <div ref={tabRef} style={{display:'flex',overflowX:'auto',scrollbarWidth:'none',marginLeft:-20,marginRight:-20,paddingLeft:20,paddingRight:20,borderBottom:'1px solid #F3F4F6'}}>
            {PANEL_TABS.map(t=>(
              <button key={t.id} onClick={()=>setTab(t.id)}
                style={{padding:'8px 13px',border:'none',background:'none',cursor:'pointer',fontSize:11.5,fontWeight:600,color:tab===t.id?'#EA580C':'#6B7280',borderBottom:tab===t.id?'2px solid #EA580C':'2px solid transparent',whiteSpace:'nowrap',fontFamily:'var(--font)',flexShrink:0,marginBottom:-1,transition:'color .15s'}}>
                {t.label}
              </button>
            ))}
          </div>
        </div>

        {/* Tab content */}
        <div style={{flex:1,overflowY:'auto',padding:'14px 20px',scrollbarWidth:'thin',scrollbarColor:'#E5E7EB transparent'}}>
          <TabContent/>
        </div>

        {/* Footer */}
        <div style={{padding:'10px 20px 14px',borderTop:'1px solid #F3F4F6',flexShrink:0,display:'flex',gap:7}}>
          <button className="btn btn-wh btn-sm" style={{flex:1,justifyContent:'center',borderRadius:9}} onClick={()=>window.exportCSV&&window.exportCSV('Daily_'+date,timeline,[{k:'type',h:'Type'},{k:'party',h:'Party'},{k:'mat',h:'Material'},{k:'co',h:'Company'},{k:'ref',h:'Ref'},{k:'veh',h:'Vehicle'},{k:'qty',h:'Qty T',r:true,f:v=>v.toFixed(3)},{k:'amt',h:'Amount',r:true,f:v=>C(v)}])}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg> Export CSV
          </button>
          <button className="btn btn-wh btn-sm" style={{flex:1,justifyContent:'center',borderRadius:9}} onClick={()=>window.print()}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="6 9 6 2 18 2 18 9"/><path d="M6 18H4a2 2 0 01-2-2v-5a2 2 0 012-2h16a2 2 0 012 2v5a2 2 0 01-2 2h-2"/><rect x="6" y="14" width="12" height="8"/></svg> Print
          </button>
        </div>
      </div>
    </>
  );
}

// ── Week View ─────────────────────────────────────────────────────────────────
function CalWeekView({ weekStart, dayMap, metric, metricDef, maxVal, todayISO, selDay, onSelectDay }) {
  const days = [];
  for (let i = 0; i < 7; i++) {
    const d = new Date(weekStart);
    d.setDate(d.getDate() + i);
    const key = d.toISOString().slice(0,10);
    days.push({ d, key, data: dayMap[key]||null, dow: d.getDay(), dn: d.getDate() });
  }
  return (
    <div style={{display:'grid',gridTemplateColumns:'repeat(7,1fr)',gap:6}}>
      {days.map(({d,key,data,dow,dn})=>{
        const val = data ? metricDef.fn(data) : 0;
        const c   = calHeat(maxVal > 0 ? val/maxVal : 0);
        const isToday = key===todayISO, isSel=key===selDay, hasData=data&&val>0;
        return (
          <div key={key} style={{background:c.bg,borderRadius:12,border:isSel?'2px solid #EA580C':isToday?'2px solid #FCA5A5':`1px solid ${c.border}`,padding:'12px 10px',minHeight:100,display:'flex',flexDirection:'column',gap:4,cursor:hasData?'pointer':'default',transition:'transform .12s,box-shadow .12s',transform:isSel?'scale(1.03)':'',boxShadow:isSel?'0 4px 18px rgba(234,88,12,.22)':''}}
            onClick={()=>hasData&&onSelectDay(isSel?null:key)}
            onMouseEnter={e=>{if(!isSel){e.currentTarget.style.transform='scale(1.03)';e.currentTarget.style.boxShadow='0 3px 12px rgba(0,0,0,.09)';}}}
            onMouseLeave={e=>{if(!isSel){e.currentTarget.style.transform='';e.currentTarget.style.boxShadow='';}}}>
            <div style={{fontSize:9.5,fontWeight:700,color:c.numC,opacity:.7,textTransform:'uppercase',letterSpacing:'.05em'}}>{CAL_DAYS[dow].slice(0,3)}</div>
            <div style={{fontSize:20,fontWeight:800,color:c.numC,lineHeight:1,display:'flex',alignItems:'center',gap:3}}>
              {dn}{isToday&&<span style={{width:5,height:5,borderRadius:'50%',background:'#EA580C',display:'inline-block',marginLeft:2}}/>}
            </div>
            {hasData&&<div style={{fontSize:11,fontWeight:700,color:c.valC,marginTop:'auto',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{fmtCompact(val,metric)}</div>}
            {data&&data.trips>0&&<div style={{fontSize:9.5,color:c.numC,opacity:.65}}>{data.trips} trips</div>}
          </div>
        );
      })}
    </div>
  );
}

// ── Day View ──────────────────────────────────────────────────────────────────
function CalDayView({ date, dayMap, todayISO, onNav, onOpenPanel }) {
  const C = window.fmtCur;
  const d = dayMap[date];
  const [yr,mo,dy_] = date.split('-');
  const dow = CAL_DAYS[new Date(date).getDay()];
  const monthName = CAL_MONTHS[+mo-1];
  const isToday = date===todayISO;
  const profit = d ? d.rev-d.purchVal : 0;
  return (
    <div style={{display:'flex',flexDirection:'column',gap:10}}>
      <div style={{display:'flex',alignItems:'center',gap:10,background:'#F9FAFB',borderRadius:12,padding:'12px 14px',border:'1px solid #F3F4F6'}}>
        <button className="btn btn-wh btn-sm" onClick={()=>onNav(-1)} style={{borderRadius:9,padding:'0 10px',height:30,flexShrink:0}}>← Prev</button>
        <div style={{flex:1,textAlign:'center'}}>
          <div style={{fontSize:18,fontWeight:800,color:'#111827',letterSpacing:'-0.02em'}}>{dow}, {monthName} {+dy_}</div>
          {isToday&&<div style={{fontSize:11,color:'#EA580C',fontWeight:600,marginTop:1}}>Today</div>}
        </div>
        <button className="btn btn-wh btn-sm" onClick={()=>onNav(1)} style={{borderRadius:9,padding:'0 10px',height:30,flexShrink:0}}>Next →</button>
      </div>
      {d ? (
        <div style={{background:'#F9FAFB',borderRadius:14,padding:'16px',border:'1px solid #F3F4F6'}}>
          <div className="dd-2col" style={{gap:8,marginBottom:12}}>
            {[['Revenue',C(d.rev),'#EA580C'],['Purchase',C(d.purchVal),'#78350F'],['Profit',C(profit),profit>=0?'#16A34A':'#DC2626'],['Trips',d.trips,'#2563EB'],['Tons Sold',window.formatQuantity(d.soldTons)+' T','#374151'],['Tons Bought',window.formatQuantity(d.purchTons)+' T','#374151'],['Transfers',d.transfers,'#7C3AED'],['Margin',d.rev>0?((profit/d.rev)*100).toFixed(1)+'%':'—','#6B7280']].map(([l,v,c])=>(
              <div key={l} style={{background:'#fff',borderRadius:10,padding:'11px 12px',border:'1px solid #F3F4F6'}}>
                <div style={{fontSize:14,fontWeight:800,color:c}}>{v}</div>
                <div style={{fontSize:10.5,color:'#9CA3AF',marginTop:3}}>{l}</div>
              </div>
            ))}
          </div>
          <button className="btn btn-or" onClick={onOpenPanel} style={{width:'100%',justifyContent:'center',height:38,borderRadius:10,fontWeight:700,fontSize:13}}>
            Open Full Daily Report →
          </button>
        </div>
      ) : (
        <div style={{background:'#F9FAFB',borderRadius:14,padding:'48px 20px',textAlign:'center',border:'1px solid #F3F4F6'}}>
          <div style={{fontSize:36,marginBottom:12,opacity:.25}}><svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg></div>
          <div style={{fontSize:14,fontWeight:600,color:'#374151',marginBottom:4}}>No Activity</div>
          <div style={{fontSize:12,color:'#9CA3AF'}}>No records found for {dow}, {monthName} {+dy_}</div>
        </div>
      )}
    </div>
  );
}

// ── Main Calendar Page ────────────────────────────────────────────────────────
function GroupCalendarPage() {
  const today    = new Date();
  const todayISO = today.toISOString().slice(0,10);
  const C        = window.fmtCur;
  const { navigate: calNav } = React.useContext(window.AppCtx) || {};

  const [viewMode,    setViewMode]    = cSt('month');
  const [year,        setYear]        = cSt(today.getFullYear());
  const [month,       setMonth]       = cSt(today.getMonth());
  const [weekStart,   setWeekStart]   = cSt(()=>{ const d=new Date(today); d.setDate(d.getDate()-d.getDay()); return d; });
  const [dayViewDate, setDayViewDate] = cSt(todayISO);
  const [selDay,      setSelDay]      = cSt(null);
  const [panelOpen,   setPanelOpen]   = cSt(false);
  const [panelDate,   setPanelDate]   = cSt(null);
  const [hovDay,      setHovDay]      = cSt(null);
  const [hovPos,      setHovPos]      = cSt({x:0,y:0,bottom:0});
  const [metric,      setMetric]      = cSt('rev');
  const [showFilters, setShowFilters] = cSt(false);
  const [,            setTick]        = cSt(0);
  const [winW,        setWinW]        = cSt(window.innerWidth);
  const [fCo,setFCo]     = cSt('');
  const [fMat,setFMat]   = cSt('');
  const [fVend,setFVend] = cSt('');
  const [fCust,setFCust] = cSt('');
  const [fCrush,setFCrush] = cSt('');

  cEf(()=>{
    const unsub = Store.on(()=>setTick(t=>t+1));
    const onR   = ()=>setWinW(window.innerWidth);
    window.addEventListener('resize',onR);
    return ()=>{ unsub(); window.removeEventListener('resize',onR); };
  },[]);

  const isMobile = winW < 640;
  const isTablet = winW < 960;
  const activeFilterCount = [fCo,fMat,fVend,fCust,fCrush].filter(Boolean).length;

  const companies = Store.all('companies');
  const materials = Store.all('materials');
  const vendors   = Store.all('vendors');
  const customers = Store.all('customers');
  const crushers  = Store.all('crushers');

  const allS  = Store.all('salesOrders');
  const allP  = Store.all('purchases');
  const allT  = Store.all('transportEntries');
  const allTr = Store.all('internalTransfers');
  const allD  = Store.all('dieselRecords');
  const allSR = Store.all('settlementRecords');
  const allVS = Store.all('vendorSettlements');
  const allSM = Store.all('stockMovements');
  const allDB = Store.all('debrisMovements');

  const filtS  = cMemo(()=>{ let d=allS; if(fCo)d=d.filter(s=>s.companyId===fCo); if(fMat)d=d.filter(s=>s.materialId===fMat); if(fCust)d=d.filter(s=>s.customerId===fCust); return d; },[allS,fCo,fMat,fCust]);
  const filtP  = cMemo(()=>{ let d=allP; if(fCo)d=d.filter(p=>p.companyId===fCo); if(fVend)d=d.filter(p=>p.vendorId===fVend); if(fMat)d=d.filter(p=>(p.items||[]).some(i=>i.materialId===fMat)||p.materialId===fMat); if(fCrush)d=d.filter(p=>(p.items||[]).some(i=>i.crusherSite===fCrush)); return d; },[allP,fCo,fVend,fMat,fCrush]);
  const filtT  = cMemo(()=>{ let d=allT; if(fCo)d=d.filter(t=>t.companyId===fCo); return d; },[allT,fCo]);
  const filtTr = cMemo(()=>{ let d=allTr; if(fCo)d=d.filter(t=>t.sourceCompanyId===fCo||t.destCompanyId===fCo); return d; },[allTr,fCo]);

  const dayMap = cMemo(()=>{
    const map={};
    const g=d=>{ if(!d)return null; if(!map[d])map[d]={rev:0,purchVal:0,soldTons:0,purchTons:0,trips:0,transfers:0,diesel:0,dieselLitres:0,dieselCount:0,dieselTransAlloc:0,dieselVendAlloc:0,transSettCount:0,transSettGross:0,transSettDiesel:0,transSettNet:0,transSettPaid:0,transSettOut:0,vendSettCount:0,vendSettGross:0,vendSettDiesel:0,vendSettNet:0,vendSettPaid:0,vendSettOut:0,stockMoveCount:0,stockMoveQty:0,stockMoveYards:0,stockMoveMats:0,debrisMovCount:0,debrisMovQty:0,debrisMovRev:0,debrisMovCusts:0}; return map[d]; };
    filtS.forEach(s =>{ const m=g(s.date);  if(!m)return; m.rev+=window.gAmt(s); m.soldTons+=parseFloat(s.quantity)||0; m.trips++; });
    filtP.forEach(p =>{ const m=g(p.date);  if(!m)return; m.purchVal+=window.gAmt(p); m.purchTons+=(p.items&&p.items.length)?p.items.reduce((a,i)=>a+(parseFloat(i.quantity)||0),0):(parseFloat(p.quantity)||0); m.trips++; });
    filtT.forEach(t =>{ const m=g(t.date);  if(!m)return; m.trips++; });
    filtTr.forEach(t=>{ const m=g(t.date);  if(!m)return; m.transfers++; });
    allD.forEach(d  =>{ const m=g(d.periodStart||d.date); if(!m)return; m.diesel+=d.amount||0; m.dieselLitres+=parseFloat(d.litres)||0; m.dieselCount++; const role=d.dieselAllocRole||''; if(role==='Vendor')m.dieselVendAlloc+=d.amount||0; else if(role==='Transport')m.dieselTransAlloc+=d.amount||0; else if(role==='Split'){m.dieselTransAlloc+=(d.transportAllocAmount||0);m.dieselVendAlloc+=(d.vendorAllocAmount||0);} });
    allSR.forEach(s =>{ const m=g(s.createdDate||s.periodFrom); if(!m)return; m.transSettCount++; m.transSettGross+=s.grossFreight||0; m.transSettDiesel+=s.dieselDeduction||0; m.transSettNet+=s.netPayable||0; m.transSettPaid+=s.amountPaid||0; m.transSettOut+=s.outstandingBalance||0; });
    allVS.forEach(s =>{ const m=g(s.createdDate||s.periodFrom); if(!m)return; m.vendSettCount++; m.vendSettGross+=s.grossPurchaseAmount||0; m.vendSettDiesel+=s.dieselDeduction||0; m.vendSettNet+=s.netPayable||0; m.vendSettPaid+=s.amountPaid||0; m.vendSettOut+=s.outstandingBalance||0; });
    allSM.forEach(s =>{ const m=g(s.date); if(!m)return; if(s.type==='Opening')return; m.stockMoveCount++; m.stockMoveQty+=parseFloat(s.quantity)||0; if(s.stockyardId&&map[s.date]){const yd=s.stockyardId;if(!m._sy)m._sy=new Set();m._sy.add(yd);m.stockMoveYards=m._sy.size;} if(s.materialId){if(!m._sm)m._sm=new Set();m._sm.add(s.materialId);m.stockMoveMats=m._sm.size;} });
    allDB.forEach(d =>{ const m=g(d.date); if(!m)return; m.debrisMovCount++; m.debrisMovQty+=parseFloat(d.quantity)||0; m.debrisMovRev+=parseFloat(d.netAmount)||0; if(d.customerName){if(!m._dc)m._dc=new Set();m._dc.add(d.customerName);m.debrisMovCusts=m._dc.size;} });
    return map;
  },[filtS,filtP,filtT,filtTr,allD,allSR,allVS,allSM,allDB]);

  const daysInMonth = new Date(year,month+1,0).getDate();
  const firstDow    = new Date(year,month,1).getDay();
  const metricDef   = CAL_METRICS.find(m=>m.id===metric)||CAL_METRICS[0];

  const monthDays = cMemo(()=>{
    const days=[];
    for(let d=1;d<=daysInMonth;d++){
      const key=`${year}-${String(month+1).padStart(2,'0')}-${String(d).padStart(2,'0')}`;
      days.push({d,key,data:dayMap[key]||null});
    }
    return days;
  },[year,month,daysInMonth,dayMap]);

  const maxVal = cMemo(()=>{
    if(viewMode==='month'){
      const vals=monthDays.map(d=>d.data?metricDef.fn(d.data):0);
      return Math.max(...vals,0.001);
    }
    if(viewMode==='week'){
      const vals=[];
      for(let i=0;i<7;i++){ const d=new Date(weekStart); d.setDate(d.getDate()+i); const data=dayMap[d.toISOString().slice(0,10)]; if(data)vals.push(metricDef.fn(data)); }
      return Math.max(...vals,0.001);
    }
    const allVals=Object.values(dayMap).map(d=>metricDef.fn(d));
    return Math.max(...allVals,0.001);
  },[viewMode,monthDays,weekStart,dayMap,metric]);

  const summary = cMemo(()=>monthDays.reduce((acc,{data:d})=>{
    if(!d)return acc;
    acc.rev+=d.rev; acc.purchVal+=d.purchVal; acc.soldTons+=d.soldTons;
    acc.purchTons+=d.purchTons; acc.trips+=d.trips; acc.transfers+=d.transfers; acc.active++;
    return acc;
  },{rev:0,purchVal:0,soldTons:0,purchTons:0,trips:0,transfers:0,active:0}),[monthDays]);

  const topDays = cMemo(()=>[...monthDays].filter(d=>d.data&&metricDef.fn(d.data)>0).sort((a,b)=>metricDef.fn(b.data)-metricDef.fn(a.data)).slice(0,5),[monthDays,metric]);

  function openPanel(key) { setPanelDate(key); setPanelOpen(true); }
  function closePanel()   { setPanelOpen(false); }

  const CAL_NAV_MAP = { transSett:'transportsettlement', vendSett:'vendorsettlement', dieselCal:'diesel', stockMov:'stockyard', debrisMov:'debris' };
  function handleDayClick(key) {
    if (!key) { setSelDay(null); closePanel(); return; }
    setSelDay(key);
    if (CAL_NAV_MAP[metric] && calNav) {
      calNav(CAL_NAV_MAP[metric], { filterDate: key });
    } else {
      openPanel(key);
    }
  }

  function goPrev() {
    if(viewMode==='month'){ if(month===0){setMonth(11);setYear(y=>y-1);}else setMonth(m=>m-1); }
    if(viewMode==='week'){ const d=new Date(weekStart); d.setDate(d.getDate()-7); setWeekStart(new Date(d)); }
    if(viewMode==='day'){ const d=new Date(dayViewDate); d.setDate(d.getDate()-1); setDayViewDate(d.toISOString().slice(0,10)); }
  }
  function goNext() {
    if(viewMode==='month'){ if(month===11){setMonth(0);setYear(y=>y+1);}else setMonth(m=>m+1); }
    if(viewMode==='week'){ const d=new Date(weekStart); d.setDate(d.getDate()+7); setWeekStart(new Date(d)); }
    if(viewMode==='day'){ const d=new Date(dayViewDate); d.setDate(d.getDate()+1); setDayViewDate(d.toISOString().slice(0,10)); }
  }
  function goToday() {
    setYear(today.getFullYear()); setMonth(today.getMonth());
    setWeekStart(()=>{ const d=new Date(today); d.setDate(d.getDate()-d.getDay()); return d; });
    setDayViewDate(todayISO);
  }
  function clearFilters(){ setFCo('');setFMat('');setFVend('');setFCust('');setFCrush(''); }

  const yearOpts=[]; for(let y=today.getFullYear()-4;y<=today.getFullYear()+2;y++) yearOpts.push(y);
  const cellH   = isMobile?46:isTablet?66:84;
  const cellPad = isMobile?'5px 4px 4px':'10px 10px 8px';
  const numSz   = isMobile?11:13;
  const valSz   = isMobile?9:11;

  const weekEndDate = new Date(weekStart); weekEndDate.setDate(weekEndDate.getDate()+6);
  const navLabel = viewMode==='month' ? `${CAL_MONTHS[month]} ${year}` :
                   viewMode==='week'  ? `${CAL_MONTHS[weekStart.getMonth()].slice(0,3)} ${weekStart.getDate()} – ${CAL_MONTHS[weekEndDate.getMonth()].slice(0,3)} ${weekEndDate.getDate()}, ${weekEndDate.getFullYear()}` :
                   (()=>{ const [yr_,mo_,dy__]=dayViewDate.split('-'); return `${CAL_MONTHS[+mo_-1]} ${+dy__}, ${yr_}`; })();

  const cardSt = {background:'#fff',borderRadius:isMobile?12:16,boxShadow:'0 1px 3px rgba(0,0,0,.05),0 4px 16px rgba(0,0,0,.04)',marginBottom:14};

  return (
    <>
      <style>{`
        @keyframes calTipIn   { from{opacity:0;transform:translateY(4px)} to{opacity:1;transform:none} }
        @keyframes calFadeIn  { from{opacity:0;transform:scale(.985)}     to{opacity:1;transform:none} }
        @keyframes calPanelIn { from{transform:translateX(100%);opacity:.5} to{transform:none;opacity:1} }
        @keyframes calBdIn    { from{opacity:0} to{opacity:1} }
        .cal-cell:hover { z-index:2; }
        .cal-fsel {
          border:1.5px solid var(--bdr2);border-radius:8px;height:32px;font-size:11.5px;
          padding:0 24px 0 10px;appearance:none;cursor:pointer;font-family:var(--font);
          color:var(--txt);outline:none;transition:border-color .15s,box-shadow .15s;
          background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 8px center;
        }
        .cal-fsel:focus { border-color:var(--or);box-shadow:0 0 0 3px rgba(249,115,22,.10); }
        .cal-fsel:hover:not(:focus) { border-color:#9CA3AF; }
        .cal-fsel.on { border-color:var(--or);background-color:#FFF7ED;color:var(--or);font-weight:600; }
        .cal-vbtn { padding:0 11px;height:28px;border:none;background:transparent;border-radius:7px;font-size:11.5px;font-weight:500;color:#6B7280;cursor:pointer;font-family:var(--font);transition:all .12s; }
        .cal-vbtn.on { background:var(--or);color:#fff;font-weight:700; }
        .cal-vbtn:hover:not(.on) { background:#F3F4F6;color:var(--txt); }
      `}</style>

      {/* ── HEADER CARD ───────────────────────────────────────────────── */}
      <div style={{...cardSt,padding:isMobile?'14px 14px 12px':'22px 26px 16px',animation:'calFadeIn .25s ease'}}>

        {/* Title row */}
        <div style={{display:'flex',alignItems:'flex-start',gap:10,marginBottom:14,flexWrap:'wrap'}}>
          <div>
            <div style={{fontSize:isMobile?16:21,fontWeight:800,color:'#111827',letterSpacing:'-0.025em',display:'flex',alignItems:'center',gap:8,lineHeight:1.1}}>
              <svg width={isMobile?18:22} height={isMobile?18:22} viewBox="0 0 24 24" fill="none" stroke="#EA580C" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/><rect x="7" y="14" width="3" height="3" rx="0.5"/><rect x="13" y="14" width="3" height="3" rx="0.5"/></svg>
              OM Group Calendar
            </div>
            <div style={{fontSize:10.5,color:'#9CA3AF',marginTop:3}}>Operational Intelligence · Click any day to open full report</div>
          </div>
          <div style={{marginLeft:'auto',display:'flex',gap:6,alignItems:'center',flexWrap:'wrap'}}>
            <div style={{display:'flex',gap:2,background:'#F3F4F6',borderRadius:9,padding:2,flexShrink:0}}>
              {['month','week','day'].map(v=>(
                <button key={v} className={`cal-vbtn${viewMode===v?' on':''}`} onClick={()=>setViewMode(v)}>
                  {v.charAt(0).toUpperCase()+v.slice(1)}
                </button>
              ))}
            </div>
            <select value={metric} onChange={e=>setMetric(e.target.value)} className="cal-fsel" style={{minWidth:135}}>
              {CAL_METRICS.map(m=><option key={m.id} value={m.id}>{m.label}</option>)}
            </select>
          </div>
        </div>

        {/* Navigation row */}
        <div style={{display:'flex',alignItems:'center',gap:7,marginBottom:12,flexWrap:'wrap'}}>
          <button className="btn btn-wh btn-sm" onClick={goPrev} style={{height:30,width:30,padding:0,display:'flex',alignItems:'center',justifyContent:'center',borderRadius:9,flexShrink:0}}>
            <svg width={10} height={10} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M15 18l-6-6 6-6"/></svg>
          </button>
          <div style={{fontSize:isMobile?16:21,fontWeight:800,color:'#111827',letterSpacing:'-0.02em',flex:1,minWidth:140}}>{navLabel}</div>
          <button className="btn btn-wh btn-sm" onClick={goNext} style={{height:30,width:30,padding:0,display:'flex',alignItems:'center',justifyContent:'center',borderRadius:9,flexShrink:0}}>
            <svg width={10} height={10} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M9 18l6-6-6-6"/></svg>
          </button>
          <button className="btn btn-wh btn-sm" onClick={goToday} style={{height:30,fontSize:11.5,borderRadius:9}}>Today</button>
          {viewMode==='month'&&<>
            <select value={month} onChange={e=>setMonth(+e.target.value)} className="cal-fsel" style={{minWidth:isMobile?90:110}}>
              {CAL_MONTHS.map((m,i)=><option key={i} value={i}>{isMobile?m.slice(0,3):m}</option>)}
            </select>
            <select value={year} onChange={e=>setYear(+e.target.value)} className="cal-fsel">
              {yearOpts.map(y=><option key={y} value={y}>{y}</option>)}
            </select>
          </>}
          <button className={`btn btn-sm${(showFilters||activeFilterCount>0)?' btn-or':' btn-wh'}`} onClick={()=>setShowFilters(f=>!f)} style={{height:30,borderRadius:9,fontSize:11.5,gap:5}}>
            <svg width={10} height={10} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>
            Filters{activeFilterCount>0?` (${activeFilterCount})`:''}
          </button>
        </div>

        {/* Filter panel */}
        {showFilters&&(
          <div style={{borderTop:'1px solid #F3F4F6',paddingTop:12,marginBottom:8}}>
            <div style={{display:'flex',gap:7,flexWrap:'wrap',alignItems:'center'}}>
              {[[fCo,setFCo,'All Companies',companies],[fMat,setFMat,'All Materials',materials],[fVend,setFVend,'All Vendors',vendors],[fCust,setFCust,'All Customers',customers],[fCrush,setFCrush,'All Crushers',crushers]].map(([val,setter,ph,opts])=>(
                <select key={ph} value={val} onChange={e=>setter(e.target.value)} className={`cal-fsel${val?' on':''}`} style={{minWidth:isMobile?'100%':140,flex:isMobile?'1 0 100%':undefined}}>
                  <option value="">{ph}</option>
                  {opts.map(o=><option key={o.id} value={o.id}>{o.name}</option>)}
                </select>
              ))}
              {activeFilterCount>0&&<button className="btn btn-sm" style={{height:30,color:'var(--err)',borderColor:'var(--err)',background:'#FFF1F1',border:'1px solid var(--err)',borderRadius:8}} onClick={clearFilters}><svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{display:'inline',verticalAlign:'-1px',marginRight:4}}><path d="M18 6L6 18M6 6l12 12"/></svg>Clear {activeFilterCount}</button>}
            </div>
            {activeFilterCount>0&&<div style={{marginTop:8,padding:'6px 10px',background:'#FFF7ED',borderRadius:8,border:'1px solid #FED7AA',fontSize:11,color:'#EA580C',fontWeight:500}}>{activeFilterCount} filter{activeFilterCount>1?'s':''} active — heatmap and drill-downs reflect filtered data only</div>}
          </div>
        )}

        {/* Monthly summary pills */}
        {viewMode==='month'&&(
          <div style={{display:'flex',gap:isMobile?4:6,flexWrap:'wrap'}}>
            {[['Rev',C(summary.rev),'#EA580C'],['Purchase',C(summary.purchVal),'#78350F'],['Profit',C(summary.rev-summary.purchVal),(summary.rev-summary.purchVal)>=0?'#16A34A':'#DC2626'],['Trips',summary.trips,'#2563EB'],['Sold',window.formatQuantity(summary.soldTons)+'T','#374151'],['Tfrs',summary.transfers,'#7C3AED'],['Days',summary.active,'#6B7280']].map(([lbl,val,col])=>(
              <div key={lbl} style={{background:'#F9FAFB',borderRadius:9,padding:isMobile?'4px 8px':'5px 12px',border:'1px solid #F3F4F6',flexShrink:0}}>
                <div style={{fontSize:isMobile?10.5:12,fontWeight:700,color:col,lineHeight:1.25}}>{val}</div>
                <div style={{fontSize:9,color:'#9CA3AF',marginTop:1}}>{lbl}</div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* ── CALENDAR VIEW CARD ────────────────────────────────────────── */}
      <div style={{...cardSt,padding:isMobile?'12px 10px 16px':'18px 22px 24px',animation:'calFadeIn .25s ease'}}>

        {viewMode==='month'&&(
          <>
            <div style={{display:'grid',gridTemplateColumns:'repeat(7,1fr)',gap:isMobile?3:5,marginBottom:isMobile?4:8}}>
              {CAL_DAYS.map(d=>(
                <div key={d} style={{textAlign:'center',fontSize:isMobile?9:10.5,fontWeight:700,color:'#94A3B8',letterSpacing:'.06em',textTransform:'uppercase',padding:'2px 0'}}>
                  {isMobile?d[0]:d}
                </div>
              ))}
            </div>
            <div style={{display:'grid',gridTemplateColumns:'repeat(7,1fr)',gap:isMobile?3:5}}>
              {Array.from({length:firstDow}).map((_,i)=><div key={`e${i}`}/>)}
              {monthDays.map(({d,key,data})=>{
                const val=data?metricDef.fn(data):0;
                const c  =calHeat(maxVal>0?val/maxVal:0);
                const isToday=key===todayISO, isSel=key===selDay, hasData=data&&val>0;
                const compact=hasData&&!isMobile?fmtCompact(val,metric):null;
                return (
                  <div key={key} className="cal-cell"
                    style={{background:c.bg,borderRadius:isMobile?8:12,border:isSel?'2px solid #EA580C':isToday?'2px solid #FCA5A5':`1px solid ${c.border}`,padding:cellPad,minHeight:cellH,display:'flex',flexDirection:'column',gap:2,cursor:hasData?'pointer':'default',transition:'transform .12s,box-shadow .12s',transform:isSel?'scale(1.05)':'',boxShadow:isSel?'0 6px 22px rgba(234,88,12,.24)':'',position:'relative',userSelect:'none'}}
                    onClick={()=>hasData&&handleDayClick(isSel?null:key)}
                    onMouseEnter={e=>{
                      if(!isSel){e.currentTarget.style.transform='scale(1.025)';e.currentTarget.style.boxShadow='0 4px 14px rgba(0,0,0,.1)';}
                      if(data&&!isMobile){const r=e.currentTarget.getBoundingClientRect();setHovPos({x:r.left+r.width/2,y:r.top,bottom:r.bottom});setHovDay(key);}
                    }}
                    onMouseLeave={e=>{if(!isSel){e.currentTarget.style.transform='';e.currentTarget.style.boxShadow='';}setHovDay(null);}}>
                    <div style={{fontSize:numSz,fontWeight:isToday?800:500,color:c.numC,lineHeight:1,display:'flex',alignItems:'center',gap:3}}>
                      {d}{isToday&&<span style={{width:5,height:5,borderRadius:'50%',background:'#EA580C',flexShrink:0,display:'inline-block',marginLeft:1}}/>}
                    </div>
                    {compact&&<div style={{fontSize:valSz,fontWeight:700,color:c.valC,lineHeight:1.25,marginTop:1,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{compact}</div>}
                    {data&&data.trips>0&&!isMobile&&<div style={{marginTop:'auto',fontSize:9,color:c.numC,opacity:.65,display:'flex',alignItems:'center',gap:2}}><span style={{width:3,height:3,borderRadius:'50%',background:c.numC,flexShrink:0,display:'inline-block'}}/>{data.trips}</div>}
                  </div>
                );
              })}
            </div>
            <div style={{display:'flex',alignItems:'center',justifyContent:'flex-end',gap:4,marginTop:14,flexWrap:'wrap'}}>
              <span style={{fontSize:9.5,color:'#9CA3AF',marginRight:2}}>Less</span>
              {[0,0.04,0.2,0.4,0.65,0.85,1].map((v,i)=>{ const hc=calHeat(v); return <div key={i} style={{width:14,height:14,borderRadius:4,background:hc.bg,border:`1px solid ${hc.border}`,flexShrink:0}}/>; })}
              <span style={{fontSize:9.5,color:'#9CA3AF',marginLeft:2}}>More</span>
            </div>
          </>
        )}

        {viewMode==='week'&&(
          <>
            <CalWeekView weekStart={weekStart} dayMap={dayMap} metric={metric} metricDef={metricDef} maxVal={maxVal} todayISO={todayISO} selDay={selDay} onSelectDay={handleDayClick}/>
            <div style={{display:'flex',alignItems:'center',justifyContent:'flex-end',gap:4,marginTop:14}}>
              <span style={{fontSize:9.5,color:'#9CA3AF',marginRight:2}}>Less</span>
              {[0,0.04,0.2,0.4,0.65,0.85,1].map((v,i)=>{ const hc=calHeat(v); return <div key={i} style={{width:14,height:14,borderRadius:4,background:hc.bg,border:`1px solid ${hc.border}`,flexShrink:0}}/>; })}
              <span style={{fontSize:9.5,color:'#9CA3AF',marginLeft:2}}>More</span>
            </div>
          </>
        )}

        {viewMode==='day'&&(
          <CalDayView
            date={dayViewDate}
            dayMap={dayMap}
            todayISO={todayISO}
            onNav={offset=>{ const d=new Date(dayViewDate); d.setDate(d.getDate()+offset); setDayViewDate(d.toISOString().slice(0,10)); }}
            onOpenPanel={()=>openPanel(dayViewDate)}
          />
        )}
      </div>

      {/* ── TOP BUSIEST DAYS ──────────────────────────────────────────── */}
      {viewMode==='month'&&topDays.length>0&&(
        <div style={{...cardSt,padding:isMobile?'12px 14px':'16px 22px',animation:'calFadeIn .25s ease'}}>
          <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:12}}>
            <div style={{fontWeight:700,fontSize:13.5,color:'#111827'}}>
              Top Busiest Days
              <span style={{fontSize:11,fontWeight:400,color:'#9CA3AF',marginLeft:7}}>by {metricDef.label}</span>
            </div>
            <span style={{fontSize:11,color:'#9CA3AF'}}>{CAL_MONTHS[month]} {year}</span>
          </div>
          <div style={{display:'flex',flexDirection:'column',gap:5}}>
            {topDays.map(({d,key,data},i)=>{
              const val=metricDef.fn(data);
              const pct=maxVal>0?val/maxVal*100:0;
              const RANK=['#EA580C','#C2410C','#9A3412','#78350F','#6B7280'];
              const c=calHeat(val/maxVal);
              return (
                <div key={key} style={{display:'grid',gridTemplateColumns:isMobile?'80px 1fr 80px':'124px 1fr 115px',gap:10,alignItems:'center',cursor:'pointer',borderRadius:10,padding:'7px 10px',transition:'background .1s'}}
                  onClick={()=>handleDayClick(key)}
                  onMouseEnter={e=>e.currentTarget.style.background='#FFF7ED'}
                  onMouseLeave={e=>e.currentTarget.style.background=''}>
                  <div style={{display:'flex',alignItems:'center',gap:8}}>
                    <div style={{width:28,height:28,borderRadius:9,background:c.bg,border:`1.5px solid ${c.border}`,display:'flex',alignItems:'center',justifyContent:'center',fontSize:12,fontWeight:800,color:c.numC,flexShrink:0}}>{d}</div>
                    <div>
                      <div style={{fontSize:12,fontWeight:600,color:'#374151'}}>{CAL_DAYS[new Date(key).getDay()]}</div>
                      {!isMobile&&<div style={{fontSize:9.5,color:'#9CA3AF'}}>{CAL_MONTHS[month].slice(0,3)} {d}</div>}
                    </div>
                  </div>
                  <window.PremiumProgress pct={Math.min(100,pct)} color={RANK[i]} height={7} />
                  <div style={{fontSize:12,fontWeight:700,color:RANK[i],textAlign:'right',whiteSpace:'nowrap'}}>{metricDef.fmt(val)}</div>
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* ── HOVER TOOLTIP ─────────────────────────────────────────────── */}
      {hovDay&&dayMap[hovDay]&&!isMobile&&!panelOpen&&(
        <CalTooltip date={hovDay} data={dayMap[hovDay]} pos={hovPos} metric={metric}/>
      )}

      {/* ── SLIDE-OVER PANEL ──────────────────────────────────────────── */}
      {panelOpen&&panelDate&&(
        <CalDayPanel
          date={panelDate}
          activeFilters={{fCo,fMat,fVend,fCust,fCrush}}
          onClose={closePanel}
          isMobile={isMobile}
        />
      )}
    </>
  );
}

window.GroupCalendarPage = GroupCalendarPage;
