/* ============ HELPERS ============ */
const DATA = window.HELBAWI;
const TODAY = new Date(DATA.today + 'T00:00:00');
const CAT_COLOR = Object.fromEntries(DATA.categories.map(c => [c.id, c.color]));
const CAT_GLYPH = {
  'Nuts':'package','Dates':'layers','Dried Fruits':'sparkle','Seeds':'hash','Spices':'layers',
  'Coffee':'box','Sweets':'sparkle','Honey':'box','Tea':'box','Grains':'hash',
  'Roasted & Mixed':'package','Helbawi Specials':'store','Turkish Delight':'sparkle'
};

function stockOf(p){ return Math.round(p.batches.reduce((s,b)=>s+b.qty,0) * 10) / 10; }
function fmtQty(n, unit){
  if(unit==='pcs') return Math.round(n) + ' pcs';
  const r = Math.round(n*10)/10;
  return (Number.isInteger(r)? r : r.toFixed(1)) + ' kg';
}
function fmtNum(n){ return n.toLocaleString('en-US'); }
function money(n){ return n.toLocaleString('en-US') + ' LBP'; }
function statusOf(p){
  const cur = stockOf(p);
  if(cur <= 0) return {key:'Empty', label:'Out of Stock', cls:'pill-crit'};
  if(p.unit==='kg'){
    if(cur <= p.threshold*0.4) return {key:'Critical', label:'Critical', cls:'pill-crit'};
    if(cur <= p.threshold) return {key:'Low', label:'Low Stock', cls:'pill-low'};
  } else {
    if(cur <= 2) return {key:'Critical', label:'Critical', cls:'pill-crit'};
    if(cur < 5) return {key:'Low', label:'Low Stock', cls:'pill-low'};
  }
  return {key:'OK', label:'In Stock', cls:'pill-ok'};
}
function nearestExpiry(p){
  if(!p.batches.length) return null;
  return p.batches.map(b=>b.expiry).sort()[0];
}
function daysUntil(dateStr){
  const d = new Date(dateStr + 'T00:00:00');
  return Math.round((d - TODAY) / 86400000);
}
function expiryState(dateStr){
  const d = daysUntil(dateStr);
  if(d < 0) return {key:'expired', label:'Expired', cls:'pill-crit'};
  if(d <= 30) return {key:'soon', label:d+' days', cls:'pill-exp'};
  if(d <= 90) return {key:'watch', label:d+' days', cls:'pill-low'};
  return {key:'ok', label:d+' days', cls:'pill-ok'};
}
function fmtDate(dateStr){
  const d = new Date(dateStr + 'T00:00:00');
  return d.toLocaleDateString('en-GB', {day:'2-digit', month:'short', year:'numeric'});
}
function relTime(dateStr, time){
  const d = new Date(dateStr + 'T' + (time||'12:00') + ':00');
  const diff = (TODAY.getTime() + (new Date().getHours()*3600000) - d.getTime());
  const mins = Math.max(1, Math.round(diff/60000));
  if(mins < 60) return mins+'m ago';
  const hrs = Math.round(mins/60);
  if(hrs < 24) return hrs+'h ago';
  const days = Math.round(hrs/24);
  return days+'d ago';
}

/* ============ PRIMITIVES ============ */
function ProductThumb({p, size=42}){
  const color = CAT_COLOR[p.category] || '#D70059';
  return (
    <div className="thumb" style={{width:size, height:size, background:color+'1A', color}}>
      <Icon name={CAT_GLYPH[p.category]||'box'} size={size*0.52} strokeWidth={2.1}/>
    </div>
  );
}
function PName({p, hideAr}){
  const showAr = !hideAr && p.nameAr && p.nameAr !== p.nameEn;
  return (
    <div className="pcell">
      <ProductThumb p={p}/>
      <div className="col">
        <span className="nm">{p.nameEn || p.nameAr}</span>
        {showAr && <span className="nm-ar ar">{p.nameAr}</span>}
      </div>
    </div>
  );
}
function StatusPill({p}){
  const s = statusOf(p);
  return <span className={'pill '+s.cls}>{s.label}</span>;
}
function Pill({cls, children, dot=true}){
  return <span className={'pill '+(dot?'':'np ')+cls}>{children}</span>;
}
function Card({children, className='', style}){
  return <div className={'card '+className} style={style}>{children}</div>;
}
function CardHead({title, sub, right}){
  return (
    <div className="card-head">
      <div><h2>{title}</h2>{sub && <div className="sub">{sub}</div>}</div>
      {right}
    </div>
  );
}

/* ============ KPI ============ */
function KPICard({icon, label, value, sub, color, tint, accent}){
  return (
    <div className="kpi">
      <div className="top">
        <div className="chip" style={{background:tint, color}}><Icon name={icon} size={26}/></div>
        <div className="col">
          <span className="klabel">{label}</span>
          <span className="kval num">{value}</span>
        </div>
      </div>
      <div className="ksub">{sub}</div>
      <div className="accent" style={{background:accent||color}}></div>
    </div>
  );
}

/* ============ MEASURE HOOK ============ */
function useWidth(){
  const ref = React.useRef(null);
  const [w, setW] = React.useState(0);
  React.useEffect(()=>{
    if(!ref.current) return;
    const ro = new ResizeObserver(e=>{ setW(e[0].contentRect.width); });
    ro.observe(ref.current);
    return ()=>ro.disconnect();
  },[]);
  return [ref, w];
}

/* ============ AREA CHART ============ */
function AreaChart({data, labels, height=230, color='#D70059'}){
  const [ref, w] = useWidth();
  const padL=36, padR=14, padT=16, padB=26;
  const iw = Math.max(120, w - padL - padR);
  const ih = height - padT - padB;
  const max = Math.max(...data) * 1.12;
  const min = 0;
  const xs = i => padL + (i/(data.length-1)) * iw;
  const ys = v => padT + ih - ((v-min)/(max-min)) * ih;
  const pts = data.map((v,i)=>[xs(i), ys(v)]);
  // smooth path
  function smooth(points){
    if(points.length<2) return '';
    let d = `M ${points[0][0]} ${points[0][1]}`;
    for(let i=0;i<points.length-1;i++){
      const [x0,y0]=points[i], [x1,y1]=points[i+1];
      const cx=(x0+x1)/2;
      d += ` C ${cx} ${y0} ${cx} ${y1} ${x1} ${y1}`;
    }
    return d;
  }
  const line = smooth(pts);
  const area = line + ` L ${xs(data.length-1)} ${padT+ih} L ${padL} ${padT+ih} Z`;
  const gridY = [0,0.25,0.5,0.75,1].map(f=>padT+ih*f);
  const gid = 'ag'+color.replace('#','');
  return (
    <div ref={ref} style={{width:'100%'}}>
      <svg width="100%" height={height} style={{display:'block'}}>
        <defs>
          <linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={color} stopOpacity="0.26"/>
            <stop offset="100%" stopColor={color} stopOpacity="0.01"/>
          </linearGradient>
        </defs>
        {gridY.map((y,i)=><line key={i} x1={padL} y1={y} x2={w-padR} y2={y} stroke="#F0EEF2" strokeWidth="1"/>)}
        {[max,max*0.75,max*0.5,max*0.25,0].map((v,i)=>(
          <text key={i} x={padL-9} y={gridY[i]+4} textAnchor="end" fontSize="11" fill="#A9A2B0" fontWeight="600">
            {v>=1000? (v/1000).toFixed(v>=10000?0:1)+'k' : Math.round(v)}
          </text>
        ))}
        <path d={area} fill={`url(#${gid})`}/>
        <path d={line} fill="none" stroke={color} strokeWidth="2.6" strokeLinecap="round"/>
        {pts.map(([x,y],i)=> (i%Math.ceil(data.length/7)===0||i===data.length-1) &&
          <circle key={i} cx={x} cy={y} r="3.6" fill="#fff" stroke={color} strokeWidth="2.4"/>)}
        {labels.map((l,i)=> (i%Math.ceil(labels.length/6)===0||i===labels.length-1) &&
          <text key={i} x={xs(i)} y={height-7} textAnchor="middle" fontSize="11" fill="#A9A2B0" fontWeight="600">{l}</text>)}
      </svg>
    </div>
  );
}

/* ============ DONUT ============ */
function Donut({segments, total, size=200, thickness=30, centerLabel, centerSub}){
  const r = (size - thickness)/2;
  const cx = size/2, cy = size/2;
  const circ = 2*Math.PI*r;
  let offset = 0;
  const sum = segments.reduce((s,x)=>s+x.value,0) || 1;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <circle cx={cx} cy={cy} r={r} fill="none" stroke="#F2EFF4" strokeWidth={thickness}/>
      {segments.map((s,i)=>{
        const frac = s.value/sum;
        const len = frac*circ;
        const el = (
          <circle key={i} cx={cx} cy={cy} r={r} fill="none" stroke={s.color} strokeWidth={thickness}
            strokeDasharray={`${len} ${circ-len}`} strokeDashoffset={-offset}
            strokeLinecap="butt" transform={`rotate(-90 ${cx} ${cy})`}/>
        );
        offset += len;
        return el;
      })}
      <text x={cx} y={cy-2} textAnchor="middle" fontSize="26" fontWeight="800" fill="#1C1320">{centerLabel}</text>
      <text x={cx} y={cy+18} textAnchor="middle" fontSize="12" fontWeight="600" fill="#8B8392">{centerSub}</text>
    </svg>
  );
}

/* ============ BARS ============ */
function BarChart({data, height=240, color='#D70059'}){
  const [ref, w] = useWidth();
  const padL=40, padR=10, padT=14, padB=30;
  const iw = Math.max(120, w-padL-padR), ih=height-padT-padB;
  const max = Math.max(...data.map(d=>d.value))*1.12 || 1;
  const bw = iw/data.length;
  const barW = Math.min(46, bw*0.56);
  const gridY=[0,0.25,0.5,0.75,1].map(f=>padT+ih*f);
  return (
    <div ref={ref} style={{width:'100%'}}>
      <svg width="100%" height={height} style={{display:'block'}}>
        {gridY.map((y,i)=><line key={i} x1={padL} y1={y} x2={w-padR} y2={y} stroke="#F0EEF2"/>)}
        {[max,max*0.75,max*0.5,max*0.25,0].map((v,i)=>(
          <text key={i} x={padL-8} y={gridY[i]+4} textAnchor="end" fontSize="11" fill="#A9A2B0" fontWeight="600">
            {v>=1000?(v/1000).toFixed(0)+'k':Math.round(v)}</text>))}
        {data.map((d,i)=>{
          const h = ((d.value)/max)*ih;
          const x = padL + i*bw + (bw-barW)/2;
          const y = padT+ih-h;
          return (<g key={i}>
            <rect x={x} y={y} width={barW} height={h} rx="6" fill={d.color||color} opacity={d.dim?0.4:1}/>
            <text x={x+barW/2} y={height-10} textAnchor="middle" fontSize="11" fill="#8B8392" fontWeight="600">{d.label}</text>
          </g>);
        })}
      </svg>
    </div>
  );
}

window.H = {stockOf,fmtQty,fmtNum,money,statusOf,nearestExpiry,daysUntil,expiryState,fmtDate,relTime,CAT_COLOR,CAT_GLYPH,DATA,TODAY};
Object.assign(window,{ProductThumb,PName,StatusPill,Pill,Card,CardHead,KPICard,useWidth,AreaChart,Donut,BarChart});
