/* Clear Mint — premium chart system on Apache ECharts.
   Themed to emerald / champagne gold / soft mint / graphite / slate, with gradient
   fills, rounded bars, hover tooltips, smooth animations, CAD formatting, empty
   states and loading skeletons. Exposes window.CMChart (EChart, CMArea, CMBars,
   CMDonut, ChartSkeleton, fmtCAD, fmtCompact). Requires echarts UMD loaded first. */
(function(){
  "use strict";
  const PAL = {
    emerald:'#16A34A', emeraldDeep:'#0F6B4F', mint:'#3ECF8E', mintSoft:'#9ED1AE',
    gold:'#D4AF37', goldSoft:'#E6C878', graphite:'#16241D', slate:'#94A29B',
    blue:'#3E7CC4', plum:'#8A6E9E', amber:'#C8742E', red:'#C35B5B',
    grid:'rgba(20,40,30,.07)', axis:'#9AA7A0', ink:'#16241D'
  };
  const SERIES_COLORS = [PAL.emerald, PAL.gold, PAL.blue, PAL.plum, PAL.amber, PAL.mint, PAL.slate];

  /* ---- financial formatting ---- */
  function fmtCAD(n){ n=+n||0; return (n<0?'-':'')+'$'+Math.abs(n).toLocaleString('en-CA',{minimumFractionDigits:2,maximumFractionDigits:2}); }
  function fmtCompact(n){ n=+n||0; const a=Math.abs(n), s=n<0?'-':'';
    if(a>=1e9) return s+'$'+(a/1e9).toFixed(1).replace(/\.0$/,'')+'B';
    if(a>=1e6) return s+'$'+(a/1e6).toFixed(1).replace(/\.0$/,'')+'M';
    if(a>=1e3) return s+'$'+(a/1e3).toFixed(1).replace(/\.0$/,'')+'K';
    return s+'$'+Math.round(a); }
  function fmtPct(n){ return (n>=0?'+':'')+(+n||0).toFixed(1)+'%'; }

  function grad(echarts, from, to, dir){
    dir = dir||'v';
    const c = dir==='v' ? [0,0,0,1] : [0,0,1,0];
    return new echarts.graphic.LinearGradient(c[0],c[1],c[2],c[3],[{offset:0,color:from},{offset:1,color:to}]);
  }
  function hexA(hex,a){ // hex + alpha → rgba
    const h=hex.replace('#',''); const r=parseInt(h.slice(0,2),16),g=parseInt(h.slice(2,4),16),b=parseInt(h.slice(4,6),16);
    return 'rgba('+r+','+g+','+b+','+a+')';
  }

  const tooltipBase = {
    trigger:'axis', backgroundColor:'rgba(15,40,30,.94)', borderWidth:0, padding:[9,13],
    textStyle:{ color:'#EAF1EC', fontSize:12, fontFamily:'Inter,system-ui,sans-serif' },
    extraCssText:'border-radius:10px;box-shadow:0 12px 30px -12px rgba(8,20,13,.5);',
    axisPointer:{ type:'line', lineStyle:{ color:hexA(PAL.emerald,.4), width:1, type:'dashed' } }
  };

  /* ---- React wrapper: inits ECharts into a div, handles resize + dispose ---- */
  function EChart({ option, height=240, dark=false, style, empty, emptyText='No data yet' }){
    const ref = React.useRef(null);
    const inst = React.useRef(null);
    React.useEffect(function(){
      if(!window.echarts || !ref.current || empty) return;
      const chart = window.echarts.init(ref.current, null, { renderer:'canvas' });
      inst.current = chart;
      chart.setOption(option);
      const onR = function(){ chart.resize(); };
      window.addEventListener('resize', onR);
      // resize when container width changes (sidebar collapse, etc.)
      let ro; try{ ro=new ResizeObserver(function(){ chart.resize(); }); ro.observe(ref.current); }catch(e){}
      return function(){ window.removeEventListener('resize',onR); if(ro)ro.disconnect(); chart.dispose(); };
    }, [JSON.stringify(option), empty]);
    if(!window.echarts) return React.createElement(ChartSkeleton,{height:height});
    if(empty) return React.createElement(EmptyState,{height:height,text:emptyText});
    return React.createElement('div',{ ref:ref, style:Object.assign({width:'100%',height:height},style||{}) });
  }

  function ChartSkeleton({ height=240 }){
    return React.createElement('div',{ className:'cm-chart-skel', style:{height:height,width:'100%',borderRadius:12,
      background:'linear-gradient(100deg,#EFEBE1 30%,#F6F2E8 50%,#EFEBE1 70%)',backgroundSize:'200% 100%',animation:'cmSkel 1.4s ease-in-out infinite'} });
  }
  function EmptyState({ height=240, text='No data yet' }){
    return React.createElement('div',{ style:{height:height,display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',gap:8,color:PAL.slate} },
      React.createElement('svg',{width:34,height:34,viewBox:'0 0 24 24',fill:'none',stroke:'currentColor',strokeWidth:1.4},
        React.createElement('path',{d:'M4 19V5M4 19h16M8 15l3-4 3 2 4-6',strokeLinecap:'round',strokeLinejoin:'round'})),
      React.createElement('div',{style:{fontSize:13,fontWeight:600}},text));
  }

  /* ---- Gradient area / line (cash flow, net worth, forecasts) ---- */
  function CMArea({ data, x, height=240, color, color2, name='Value', dark=false, smooth=true, fill=true, money=true, empty }){
    const e = window.echarts;
    const c1 = color||PAL.emerald, c2 = color2||PAL.mint;
    const isEmpty = empty!=null ? empty : !(data&&data.length&&data.some(v=>+v));
    const option = e ? {
      animationDuration:700, animationEasing:'cubicOut',
      grid:{ left:8, right:14, top:14, bottom:6, containLabel:true },
      tooltip:Object.assign({}, tooltipBase, { valueFormatter:v=> money?fmtCAD(v):v }),
      xAxis:{ type:'category', data:x||data.map((_,i)=>i+1), boundaryGap:false,
        axisLine:{ lineStyle:{ color:PAL.grid } }, axisTick:{ show:false },
        axisLabel:{ color:dark?'rgba(232,239,233,.6)':PAL.axis, fontSize:11 } },
      yAxis:{ type:'value', splitLine:{ lineStyle:{ color:PAL.grid } }, axisLine:{ show:false }, axisTick:{ show:false },
        axisLabel:{ color:dark?'rgba(232,239,233,.5)':PAL.axis, fontSize:11, formatter:v=> money?fmtCompact(v):v } },
      series:[{ name:name, type:'line', data:data, smooth:smooth, symbol:'circle', symbolSize:0, showSymbol:false,
        lineStyle:{ width:3, color:e?grad(e,c1,c2,'h'):c1, shadowColor:hexA(c1,.35), shadowBlur:12, shadowOffsetY:6 },
        emphasis:{ focus:'series', scale:true, itemStyle:{ borderWidth:3, borderColor:'#fff', color:c1 } },
        areaStyle: fill ? { color:e?grad(e,hexA(c1,.30),hexA(c1,0),'v'):hexA(c1,.2) } : undefined }]
    } : {};
    return React.createElement(EChart,{ option:option, height:height, empty:isEmpty, emptyText:'No data to chart yet' });
  }

  /* ---- Grouped rounded bars (income vs expenses, monthly cash flow) ---- */
  function CMBars({ series, x, height=240, dark=false, money=true, stack=false, empty }){
    const e = window.echarts;
    const isEmpty = empty!=null ? empty : !(series&&series.length&&series.some(s=>(s.data||[]).some(v=>+v)));
    const ser = (series||[]).map(function(s,i){
      const col = s.color||SERIES_COLORS[i%SERIES_COLORS.length];
      return { name:s.name, type:'bar', stack:stack?'t':undefined, data:s.data, barMaxWidth:26, barGap:'18%',
        itemStyle:{ borderRadius:[6,6,0,0], color:e?grad(e,col,hexA(col,.55),'v'):col },
        emphasis:{ itemStyle:{ color:e?grad(e,col,hexA(col,.8),'v'):col } } };
    });
    const option = e ? {
      animationDuration:700, animationEasing:'cubicOut',
      color:SERIES_COLORS,
      legend:{ show:(series||[]).length>1, top:0, right:0, icon:'roundRect', itemWidth:10, itemHeight:10,
        textStyle:{ color:dark?'rgba(232,239,233,.75)':PAL.ink, fontSize:11, fontWeight:600 } },
      grid:{ left:8, right:10, top:(series||[]).length>1?28:12, bottom:4, containLabel:true },
      tooltip:Object.assign({}, tooltipBase, { axisPointer:{type:'shadow'}, valueFormatter:v=> money?fmtCAD(v):v }),
      xAxis:{ type:'category', data:x, axisLine:{ lineStyle:{ color:PAL.grid } }, axisTick:{ show:false },
        axisLabel:{ color:dark?'rgba(232,239,233,.6)':PAL.axis, fontSize:11 } },
      yAxis:{ type:'value', splitLine:{ lineStyle:{ color:PAL.grid } }, axisLine:{ show:false }, axisTick:{ show:false },
        axisLabel:{ color:dark?'rgba(232,239,233,.5)':PAL.axis, fontSize:11, formatter:v=> money?fmtCompact(v):v } },
      series:ser
    } : {};
    return React.createElement(EChart,{ option:option, height:height, empty:isEmpty, emptyText:'No data to chart yet' });
  }

  /* ---- Premium donut (spending mix) with center label ---- */
  function CMDonut({ data, height=240, centerLabel='Total', centerValue, dark=false, money=true, empty }){
    const e = window.echarts;
    const isEmpty = empty!=null ? empty : !(data&&data.length&&data.some(d=>+d.value));
    const total = (data||[]).reduce((s,d)=>s+(+d.value||0),0);
    const seg = (data||[]).map((d,i)=>({ value:d.value, name:d.label||d.name,
      itemStyle:{ color:d.color||SERIES_COLORS[i%SERIES_COLORS.length], borderColor:dark?'#0F2A20':'#fff', borderWidth:3 } }));
    const option = e ? {
      animationDuration:700, animationEasing:'cubicOut',
      tooltip:{ trigger:'item', backgroundColor:'rgba(15,40,30,.94)', borderWidth:0, padding:[9,13],
        textStyle:{ color:'#EAF1EC', fontSize:12 }, extraCssText:'border-radius:10px;',
        formatter:p=> p.name+': <b>'+(money?fmtCAD(p.value):p.value)+'</b> ('+p.percent+'%)' },
      series:[{ type:'pie', radius:['62%','86%'], center:['50%','50%'], avoidLabelOverlap:true,
        padAngle:2, itemStyle:{ borderRadius:6 }, label:{ show:false }, labelLine:{ show:false },
        emphasis:{ scale:true, scaleSize:6, itemStyle:{ shadowBlur:16, shadowColor:'rgba(8,20,13,.25)' } },
        data:seg }]
    } : {};
    return React.createElement('div',{ style:{position:'relative',height:height} },
      React.createElement(EChart,{ option:option, height:height, empty:isEmpty, emptyText:'No spending yet' }),
      (!isEmpty) ? React.createElement('div',{ style:{position:'absolute',inset:0,display:'flex',flexDirection:'column',
        alignItems:'center',justifyContent:'center',pointerEvents:'none'} },
        React.createElement('div',{ style:{fontFamily:'var(--num,Inter),sans-serif',fontWeight:700,fontSize:22,color:dark?'#FBFAF4':PAL.ink} },
          centerValue!=null?centerValue:(money?fmtCompact(total):total)),
        React.createElement('div',{ style:{fontSize:11.5,color:PAL.slate,fontWeight:600,marginTop:2} }, centerLabel)
      ) : null
    );
  }

  // skeleton shimmer keyframes
  try{ if(!document.getElementById('cm-chart-style')){ var st=document.createElement('style'); st.id='cm-chart-style';
    st.textContent='@keyframes cmSkel{0%{background-position:200% 0}100%{background-position:-200% 0}}'; document.head.appendChild(st); } }catch(e){}

  window.CMChart = { EChart:EChart, CMArea:CMArea, CMBars:CMBars, CMDonut:CMDonut, ChartSkeleton:ChartSkeleton,
    EmptyState:EmptyState, fmtCAD:fmtCAD, fmtCompact:fmtCompact, fmtPct:fmtPct, PALETTE:PAL };
})();
