/* Growth OS — helpers de formatação, matemática (spec §12) e gráficos */
(function(){
"use strict";
const R=window.React,h=R.createElement;
const G=window.GOS;
const monthName=k=>{const m=k.split("-")[1];const f=G.MONTHS.find(x=>x[0]===m);return f?f[1]:m;};
const monthLong=k=>{const[y,m]=k.split("-");const f=G.MONTHS.find(x=>x[0]===m);return`${f?f[1]:m}/${y.slice(2)}`;};

// aggregation mode per indicator
const LAST=new Set(["ativos","frota","projAtivos","dividas"]);
const AVG_TYPES=new Set(["percentual","indice","tempo"]);
const AVG_KEYS=new Set(["cpl","cac","ticket","valorLoc","diariaMedia"]);
function aggMode(ind){
  if(LAST.has(ind.key))return"last";
  if(AVG_TYPES.has(ind.type)||AVG_KEYS.has(ind.key))return"avg";
  return"sum";
}
function seriesVals(ind,months){
  return months.map(k=>ind.series[k]).filter(v=>v!=null&&!isNaN(v));
}
function agg(ind,months){
  const vals=seriesVals(ind,months);
  if(!vals.length)return null;
  const m=aggMode(ind);
  if(m==="last")return vals[vals.length-1];
  if(m==="avg")return round(vals.reduce((a,b)=>a+b,0)/vals.length, decs(ind));
  return round(vals.reduce((a,b)=>a+b,0), decs(ind));
}
function decs(ind){
  if(ind.type==="percentual")return 1;
  if(ind.type==="indice")return ind.unit==="x"?1:0;
  if(ind.unit==="R$ mi")return 1;
  return 0;
}
function round(n,d=0){if(n==null)return null;const f=Math.pow(10,d);return Math.round(n*f)/f;}

// spec §12 math
function varAbs(cur,prev){if(cur==null||prev==null)return null;return cur-prev;}
function varPct(cur,prev){if(cur==null||prev==null||prev===0)return null;return round((cur-prev)/prev*100,1);}
function isPP(ind){return ind.type==="percentual";} // difference in pontos percentuais
function delta(ind,cur,prev){
  if(cur==null||prev==null)return{ok:false};
  const abs=varAbs(cur,prev);
  if(prev===0)return{ok:true,abs,pct:null,nc:true};
  if(isPP(ind))return{ok:true,abs:round(abs,1),pp:round(abs,1),pct:round((cur-prev)/prev*100,1)};
  return{ok:true,abs,pct:varPct(cur,prev)};
}
// direction goodness: is this delta good for the business?
function goodness(ind,cur,prev){
  const d=varAbs(cur,prev);
  if(d==null||d===0)return"flat";
  const up=d>0;
  if(ind.dir==="maior")return up?"up":"down";
  if(ind.dir==="menor")return up?"down":"up";
  if(ind.dir==="faixa"&&ind.faixa){const[lo,hi]=ind.faixa;const inRange=cur>=lo&&cur<=hi;return inRange?"up":"warn";}
  return up?"up":"down";
}
// trend over last N comparable months (spec §17)
function trend(ind,months){
  const vals=seriesVals(ind,months);
  if(vals.length<3)return{cls:"Sem dados",dir:"flat"};
  const last3=vals.slice(-3);
  const diffs=[];for(let i=1;i<last3.length;i++)diffs.push(last3[i]-last3[i-1]);
  const allUp=diffs.every(d=>d>0),allDown=diffs.every(d=>d<0);
  const avg=last3.reduce((a,b)=>a+b,0)/3;
  const vol=Math.sqrt(last3.reduce((a,b)=>a+Math.pow(b-avg,2),0)/3)/(avg||1);
  if(allUp)return{cls:"Crescente",dir:"up"};
  if(allDown)return{cls:"Decrescente",dir:"down"};
  if(vol>0.18)return{cls:"Volátil",dir:"warn"};
  return{cls:"Estável",dir:"flat"};
}

// value formatting
function fmtNum(n,d=0){if(n==null)return"—";return n.toLocaleString("pt-BR",{minimumFractionDigits:d,maximumFractionDigits:d});}
function fmtMoneyBRL(n,compact=false){
  if(n==null)return"—";
  if(compact&&Math.abs(n)>=1000000)return"R$ "+round(n/1000000,2).toLocaleString("pt-BR",{maximumFractionDigits:2})+" mi";
  if(compact&&Math.abs(n)>=1000)return"R$ "+round(n/1000,1).toLocaleString("pt-BR",{maximumFractionDigits:1})+" mil";
  return"R$ "+fmtNum(n,0);
}
function fmtVal(ind,v,compact=false){
  if(v==null)return"—";
  switch(ind.type){
    case"moeda": if(ind.unit==="R$ mi")return"R$ "+fmtNum(v,1)+" mi"; return fmtMoneyBRL(v,compact);
    case"percentual":return fmtNum(v,1)+"%";
    case"indice":return ind.unit==="x"?fmtNum(v,1)+"×":fmtNum(v,0)+"%";
    case"tempo":return fmtNum(v,0)+" "+(ind.unit||"dias");
    default:return fmtNum(v,0);
  }
}
function unitLabel(ind){
  if(ind.type==="moeda")return"";
  if(ind.type==="percentual"||ind.unit==="%")return"";
  if(ind.unit==="x")return"";
  return ind.unit||"";
}

/* ============ CHART: line ============ */
function LineChart(props){
  const{months,values,goal,color="#f86537",h:H=220,cmpValues}=props;
  const W=680,pad={t:18,r:16,b:28,l:46};
  const all=values.filter(v=>v!=null).concat(cmpValues?cmpValues.filter(v=>v!=null):[]).concat(goal!=null?[goal]:[]);
  const min=Math.min(...all),max=Math.max(...all);
  const range=(max-min)||1,lo=min-range*0.12,hi=max+range*0.12,span=hi-lo;
  const iw=W-pad.l-pad.r,ih=H-pad.t-pad.b;
  const x=i=>pad.l+(months.length<=1?iw/2:i/(months.length-1)*iw);
  const y=v=>pad.t+ih-((v-lo)/span)*ih;
  const [hover,setHover]=R.useState(null);
  const path=v=>v.map((val,i)=>val==null?null:`${i===0||v[i-1]==null?"M":"L"}${x(i).toFixed(1)},${y(val).toFixed(1)}`).filter(Boolean).join(" ");
  const area=(()=>{const pts=values.map((val,i)=>val==null?null:`${x(i).toFixed(1)},${y(val).toFixed(1)}`).filter(Boolean);if(!pts.length)return"";return`M${pts[0].split(",")[0]},${y(lo)} L`+pts.join(" L ")+` L${x(values.length-1).toFixed(1)},${y(lo)} Z`;})();
  const ticks=4;
  return h("div",{className:"chart-wrap"},
    h("svg",{viewBox:`0 0 ${W} ${H}`,style:{width:"100%",height:H},onMouseLeave:()=>setHover(null)},
      // grid + y labels
      Array.from({length:ticks+1}).map((_,i)=>{const val=lo+span*(i/ticks);const yy=y(val);return h("g",{key:i},
        h("line",{x1:pad.l,x2:W-pad.r,y1:yy,y2:yy,stroke:"rgba(0,0,0,.08)",strokeWidth:1}),
        h("text",{x:pad.l-8,y:yy+3,textAnchor:"end",fontSize:9,fill:"#86868b",fontFamily:"var(--mono)"},fmtCompactAxis(val)));}),
      goal!=null&&h("line",{x1:pad.l,x2:W-pad.r,y1:y(goal),y2:y(goal),stroke:"#c1c1c6",strokeWidth:1,strokeDasharray:"4 4"}),
      goal!=null&&h("text",{x:W-pad.r,y:y(goal)-5,textAnchor:"end",fontSize:8.5,fill:"#86868b",fontFamily:"var(--mono)"},"meta"),
      cmpValues&&h("path",{d:path(cmpValues),fill:"none",stroke:"#c1c1c6",strokeWidth:1.6,strokeDasharray:"3 3",opacity:.8}),
      area&&h("path",{d:area,fill:color,opacity:.08}),
      h("path",{d:path(values),fill:"none",stroke:color,strokeWidth:2.4,strokeLinejoin:"round",strokeLinecap:"round"}),
      values.map((val,i)=>val==null?null:h("circle",{key:i,cx:x(i),cy:y(val),r:hover===i?5:3.2,fill:hover===i?color:"#ffffff",stroke:color,strokeWidth:2,style:{cursor:"pointer",transition:"r .12s"},onMouseEnter:()=>setHover(i)})),
      months.map((k,i)=>h("text",{key:k,x:x(i),y:H-9,textAnchor:"middle",fontSize:9.5,fill:hover===i?"#1d1d1f":"#86868b",fontFamily:"var(--mono)"},monthName(k)))
    ),
    hover!=null&&values[hover]!=null&&h("div",{className:"chart-tip",style:{left:`${x(hover)/W*100}%`,top:`${y(values[hover])/H*100}%`,opacity:1}},
      `${monthLong(months[hover])} · ${props.tipFmt?props.tipFmt(values[hover]):fmtNum(values[hover])}`)
  );
}
function fmtCompactAxis(v){
  if(Math.abs(v)>=1000000)return round(v/1000000,1)+"M";
  if(Math.abs(v)>=1000)return round(v/1000,0)+"k";
  return round(v,Math.abs(v)<10?1:0);
}

/* ============ CHART: sparkline ============ */
function Spark(props){
  const{values,color="#f86537",good}=props;
  const clean=values.filter(v=>v!=null);
  if(clean.length<2)return null;
  const W=180,H=34,min=Math.min(...clean),max=Math.max(...clean),range=(max-min)||1;
  const x=i=>i/(values.length-1)*W;
  const y=v=>H-4-((v-min)/range)*(H-8);
  const col=good==="down"?"#E5837A":good==="up"?"#8FE07A":color;
  const d=values.map((v,i)=>v==null?null:`${i===0?"M":"L"}${x(i).toFixed(1)},${y(v).toFixed(1)}`).filter(Boolean).join(" ");
  return h("svg",{viewBox:`0 0 ${W} ${H}`,preserveAspectRatio:"none",style:{width:"100%",height:34}},
    h("path",{d,fill:"none",stroke:col,strokeWidth:2,strokeLinejoin:"round",strokeLinecap:"round"}),
    h("circle",{cx:x(values.length-1),cy:y(clean[clean.length-1]),r:2.6,fill:col})
  );
}

window.GOSlib={
  monthName,monthLong,agg,aggMode,seriesVals,decs,round,
  varAbs,varPct,delta,goodness,trend,isPP,
  fmtNum,fmtMoneyBRL,fmtVal,unitLabel,
  LineChart,Spark
};
})();
