/* global React, LITIO */
const { useRef, useEffect, useState, useCallback } = React;

/* ---------- formatters ---------- */
const T = window.T;
function nfCur(){ return new Intl.NumberFormat(window.CURLANG==='en'?'en-US':'es-AR'); }
function decSep(s){ return window.CURLANG==='en' ? s : s.replace('.',','); }
const rLabel = (k)=> window.CURLANG==='en' ? k.replace('A','Y') : k;
function fmtFull(v){
  return 'US$ ' + nfCur().format(Math.round(v));
}
function fmtAxis(v){
  if (v >= 1000) return decSep((v/1000).toFixed(v>=10000?0:1)) + 'k';
  return Math.round(v);
}
const MES_ES = ['ene','feb','mar','abr','may','jun','jul','ago','sep','oct','nov','dic'];
const MES_EN = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
function fmtDate(ms, withDay){
  const d = new Date(ms);
  const M = window.CURLANG==='en'?MES_EN:MES_ES;
  return (withDay ? d.getUTCDate()+' ' : '') + M[d.getUTCMonth()] + " '" + String(d.getUTCFullYear()).slice(2);
}

const RANGES = [
  {k:'1M', w:22}, {k:'6M', w:130}, {k:'1A', w:252},
  {k:'2A', w:504}, {k:'MAX', w:9999}
];

/* ================= Canvas chart ================= */
function ChartCanvas({ seriesList, mode, rangeW, onHover, hoverIdx }){
  const ref = useRef(null);
  const wrapRef = useRef(null);
  const [w, setW] = useState(800);
  const H = 420;

  useEffect(() => {
    const el = wrapRef.current;
    if (!el) return;
    const ro = new ResizeObserver(() => setW(el.clientWidth));
    ro.observe(el);
    setW(el.clientWidth);
    return () => ro.disconnect();
  }, []);

  const weeks = LITIO.weeks;
  const total = weeks.length;
  const start = rangeW >= total ? 0 : Math.max(0, total - rangeW);
  const N = total - start;

  const conv = useCallback((val) => val, []);

  // geometry
  const padL = 8, padR = seriesList.some(s=>s.axis==='right') ? 56 : 14, padT = 16, padB = 30;
  const plotW = Math.max(10, w - padL - padR);
  const plotH = H - padT - padB;

  // axis ranges
  function axisRange(axis){
    let mn = Infinity, mx = -Infinity;
    seriesList.filter(s=>s.axis===axis).forEach(s=>{
      for (let i=start;i<total;i++){
        const p = s.data[i];
        const lo = conv(mode==='candle'?p.l:Math.min(p.c, p.o), i);
        const hi = conv(mode==='candle'?p.h:Math.max(p.c, p.o), i);
        if (lo<mn) mn=lo; if (hi>mx) mx=hi;
      }
    });
    if (!isFinite(mn)){ mn=0; mx=1; }
    const pad = (mx-mn)*0.10 || mx*0.1;
    mn = Math.max(0, mn - pad); mx = mx + pad;
    return [mn, mx];
  }
  const leftHas = seriesList.some(s=>s.axis==='left');
  const rightHas = seriesList.some(s=>s.axis==='right');
  const [lMin,lMax] = leftHas ? axisRange('left') : [0,1];
  const [rMin,rMax] = rightHas ? axisRange('right') : [0,1];

  const xAt = (vi) => padL + (N<=1?plotW/2:(vi/(N-1))*plotW);
  const yAtL = (val) => padT + plotH - ((val-lMin)/(lMax-lMin))*plotH;
  const yAtR = (val) => padT + plotH - ((val-rMin)/(rMax-rMin))*plotH;
  const yAt = (val, axis) => axis==='right' ? yAtR(val) : yAtL(val);

  useEffect(() => {
    const cv = ref.current; if (!cv) return;
    const dpr = window.devicePixelRatio || 1;
    cv.width = w*dpr; cv.height = H*dpr;
    cv.style.width = w+'px'; cv.style.height = H+'px';
    const ctx = cv.getContext('2d');
    ctx.setTransform(dpr,0,0,dpr,0,0);
    ctx.clearRect(0,0,w,H);

    // grid
    const rows = 5;
    ctx.font = "11px 'IBM Plex Mono', monospace";
    ctx.textBaseline = 'middle';
    for (let r=0;r<=rows;r++){
      const y = padT + (r/rows)*plotH;
      ctx.strokeStyle = 'rgba(20,36,43,0.09)';
      ctx.lineWidth = 1;
      ctx.beginPath(); ctx.moveTo(padL, y+0.5); ctx.lineTo(padL+plotW, y+0.5); ctx.stroke();
      if (leftHas){
        const val = lMax - (r/rows)*(lMax-lMin);
        ctx.fillStyle = '#869198'; ctx.textAlign = 'left';
        ctx.fillText(fmtAxis(val), padL+4, y-8);
      }
      if (rightHas){
        const val = rMax - (r/rows)*(rMax-rMin);
        ctx.fillStyle = '#8A93A0'; ctx.textAlign = 'right';
        ctx.fillText(fmtAxis(val), w-6, y-8);
      }
    }
    // x labels
    ctx.fillStyle = '#869198'; ctx.textAlign = 'center'; ctx.textBaseline='top';
    const ticks = Math.min(7, N);
    for (let t=0;t<ticks;t++){
      const vi = Math.round((t/(ticks-1))*(N-1));
      const idx = start+vi;
      ctx.fillText(fmtDate(weeks[idx], rangeW<=140), xAt(vi), H-padB+9);
    }

    // draw each series
    seriesList.forEach(s=>{
      const dense = N > 110;
      if (mode === 'candle'){
        const slotW = plotW/N;
        const bw = Math.max(1, Math.min(11, slotW*0.62));
        for (let vi=0; vi<N; vi++){
          const idx = start+vi; const p = s.data[idx];
          const x = xAt(vi);
          const o=conv(p.o,idx),c=conv(p.c,idx),hi=conv(p.h,idx),lo=conv(p.l,idx);
          const up = c>=o;
          const col = up ? '#2E9E8C' : '#C05A45';
          ctx.strokeStyle = col; ctx.fillStyle = col; ctx.lineWidth = 1;
          ctx.beginPath(); ctx.moveTo(x, yAt(hi,s.axis)); ctx.lineTo(x, yAt(lo,s.axis)); ctx.stroke();
          if (!dense){
            const yo=yAt(o,s.axis), yc=yAt(c,s.axis);
            const top=Math.min(yo,yc), bh=Math.max(1.4,Math.abs(yc-yo));
            ctx.globalAlpha = up?1:.95;
            ctx.fillRect(x-bw/2, top, bw, bh);
            ctx.globalAlpha = 1;
          }
        }
      } else {
        // line / area
        ctx.beginPath();
        for (let vi=0; vi<N; vi++){
          const idx = start+vi; const v = conv(s.data[idx].c, idx);
          const x = xAt(vi), y = yAt(v, s.axis);
          vi===0 ? ctx.moveTo(x,y) : ctx.lineTo(x,y);
        }
        if (mode === 'area'){
          const grad = ctx.createLinearGradient(0,padT,0,padT+plotH);
          grad.addColorStop(0, s.color+'55');
          grad.addColorStop(1, s.color+'05');
          ctx.lineTo(xAt(N-1), padT+plotH);
          ctx.lineTo(xAt(0), padT+plotH);
          ctx.closePath();
          ctx.fillStyle = grad; ctx.fill();
          // redraw stroke
          ctx.beginPath();
          for (let vi=0; vi<N; vi++){
            const idx = start+vi; const v = conv(s.data[idx].c, idx);
            const x = xAt(vi), y = yAt(v, s.axis);
            vi===0 ? ctx.moveTo(x,y) : ctx.lineTo(x,y);
          }
        }
        ctx.strokeStyle = s.color; ctx.lineWidth = mode==='area'?2:2.2;
        ctx.lineJoin='round'; ctx.stroke();
      }
    });

    // crosshair + markers
    if (hoverIdx != null && hoverIdx>=0 && hoverIdx<N){
      const x = xAt(hoverIdx);
      ctx.strokeStyle = 'rgba(20,36,43,0.30)'; ctx.lineWidth=1;
      ctx.setLineDash([3,4]);
      ctx.beginPath(); ctx.moveTo(x, padT); ctx.lineTo(x, padT+plotH); ctx.stroke();
      ctx.setLineDash([]);
      if (mode!=='candle'){
        seriesList.forEach(s=>{
          const idx = start+hoverIdx; const v = conv(s.data[idx].c, idx);
          const y = yAt(v, s.axis);
          ctx.fillStyle = '#fff'; ctx.strokeStyle = s.color; ctx.lineWidth=2;
          ctx.beginPath(); ctx.arc(x,y,4.2,0,7); ctx.fill(); ctx.stroke();
        });
      }
    }
  }, [w, seriesList, mode, rangeW, hoverIdx, lMin, lMax, rMin, rMax, N, start]);

  const move = (e) => {
    const rect = ref.current.getBoundingClientRect();
    const x = e.clientX - rect.left;
    let vi = Math.round(((x-padL)/plotW)*(N-1));
    vi = Math.max(0, Math.min(N-1, vi));
    onHover(vi);
  };

  return (
    <div ref={wrapRef} style={{position:'relative', width:'100%'}}>
      <canvas ref={ref} onMouseMove={move} onMouseLeave={()=>onHover(null)}
        style={{display:'block', cursor:'crosshair'}} />
      {hoverIdx!=null && hoverIdx>=0 && hoverIdx<N &&
        <HoverTip seriesList={seriesList} idx={start+hoverIdx} vi={hoverIdx} N={N}
          xAt={xAt} conv={conv} />}
    </div>
  );
}

function HoverTip({ seriesList, idx, vi, N, xAt, conv }){
  const left = xAt(vi);
  const side = vi > N*0.6 ? 'right' : 'left';
  return (
    <div className="chart-tip" style={{
      left: side==='left' ? left+14 : 'auto',
      right: side==='right' ? `calc(100% - ${left-14}px)` : 'auto',
      top: 14
    }}>
      <div className="tip-date">{fmtDate(LITIO.weeks[idx], true)}</div>
      {seriesList.map(s=>(
        <div className="tip-row" key={s.key}>
          <span className="tip-dot" style={{background:s.color}}></span>
          <span className="tip-name">{s.short}</span>
          <span className="tip-val">{fmtFull(conv(s.data[idx].c, idx))}</span>
        </div>
      ))}
    </div>
  );
}

/* ================= Section ================= */
function PriceSection(){
  const [sel, setSel] = useState(['carb']);
  const [mode, setMode] = useState('area');
  const [rangeK, setRangeK] = useState('1A');
  const [hoverIdx, setHoverIdx] = useState(null);

  const rangeW = RANGES.find(r=>r.k===rangeK).w;
  const seriesList = sel.map(k=>LITIO.SERIES[k]);

  // single-select: choosing a series replaces the previous one (no overlap)
  const toggle = (k) => setSel([k]);

  // readout (primary = first selected)
  const prim = seriesList[0];
  const weeks = LITIO.weeks, total = weeks.length;
  const start = rangeW>=total?0:Math.max(0,total-rangeW);
  const conv = (v)=> v;
  const lastV = conv(prim.data[total-1].c, total-1);
  const firstV = conv(prim.data[start].c, start);
  const chg = ((lastV-firstV)/firstV*100);
  let hi=-Infinity, lo=Infinity;
  for(let i=start;i<total;i++){const v=conv(prim.data[i].c,i); if(v>hi)hi=v; if(v<lo)lo=v;}

  return (
    <section id="precios" className="sec-pad">
      <div className="container">
        <div className="sec-head">
          <div>
            <div className="eyebrow">{T('s.precios.ey')}</div>
            <h2>{T('s.precios.h')}</h2>
            <p>{T('s.precios.p')}</p>
          </div>
          <div className="price-now">
            <div className="pn-lbl">{prim.short} · {T('price.close')}</div>
            <div className="pn-val">{fmtFull(lastV)}<span className="pn-unit">/t</span></div>
            <div className={'pn-chg '+(chg>=0?'up':'down')}>
              {chg>=0?'▲':'▼'} {Math.abs(chg).toFixed(1)}% <span>{T('price.in')} {rLabel(rangeK)}</span>
            </div>
          </div>
        </div>

        <div className="panel chart-panel">
          <div className="chart-toolbar">
            <div className="tb-controls">
              <div className="tb-group">
                <span className="field-lbl">{T('price.chart')}</span>
                <div className="seg">
                  {[['area',T('price.area')],['line',T('price.line')],['candle',T('price.candle')]].map(([k,l])=>(
                    <button key={k} className={mode===k?'on':''} onClick={()=>setMode(k)}>{l}</button>
                  ))}
                </div>
              </div>
            </div>
          </div>

          <ChartCanvas seriesList={seriesList} mode={mode}
            rangeW={rangeW} onHover={setHoverIdx} hoverIdx={hoverIdx} />

          <div className="chart-foot">
            <div className="seg range-seg">
              {RANGES.map(r=>(
                <button key={r.k} className={rangeK===r.k?'on':''} onClick={()=>setRangeK(r.k)}>{rLabel(r.k)}</button>
              ))}
            </div>
            <div className="chart-stats">
              <div className="cstat"><span>{T('price.max')} {rLabel(rangeK)}</span><b>{fmtFull(hi)}</b></div>
              <div className="cstat"><span>{T('price.min')} {rLabel(rangeK)}</span><b>{fmtFull(lo)}</b></div>
            </div>
          </div>
        </div>

        <p className="chart-disclaimer mono">
          {T('price.disclaimer')}
        </p>
      </div>
    </section>
  );
}

window.PriceSection = PriceSection;
