// Seção Canais (spec 2026-06-25, refinamentos v2/v3) — KPIs por canal + séries temporais.
// DRY: ChannelKpiCard e ChannelChart mapeados sobre a lista de canais do /channels.
// Direto/Logicall/Tauk/Salesbound têm dado real; Email/SMS renderizam estado vazio honesto.
// Tauk é histórica (descontinuada) — aparece p/ períodos passados, separada da Logicall.
// Layout: Direto (1 linha cheia) · Logicall+Tauk+Salesbound (1 linha) · Email+SMS (1 linha), sem rolagem.

const CHANNEL_ICON = { direct:'dollar', logicall:'cart', tauk:'cart', salesbound:'bolt', email:'mail', sms:'sms' };
const _WD = ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'];

// '2026-06-19' OU '2026-06-19T00:00:00' -> 'Seg 19/06' (parse local, robusto a datetime)
const _dayLabel = (iso) => {
  const [Y,M,D] = iso.slice(0,10).split('-').map(Number);
  return `${_WD[new Date(Y, M-1, D).getDay()]} ${String(D).padStart(2,'0')}/${String(M).padStart(2,'0')}`;
};

// Subtítulo da série conforme a granularidade (conserta "14 dias" fixo no 90d)
const GRAN_WORD = { day:'diária', week:'semanal', month:'mensal', hour:'por hora' };
const GRAN_UNIT = { day:'dias', week:'semanas', month:'meses', hour:'horas' };
const _spanSub = (prefix, gran, n) =>
  `${prefix} ${GRAN_WORD[gran] || 'diária'} · ${n} ${GRAN_UNIT[gran] || 'dias'}`;

// hex -> rgba (fundo suave do ícone)
const _soft = (hex, a=0.12) => {
  const n = parseInt(hex.slice(1), 16);
  return `rgba(${(n>>16)&255},${(n>>8)&255},${n&255},${a})`;
};

const PERIOD_TITLE_CH = { ontem:'Ontem', '7d':'Últimos 7 dias', '14d':'Últimos 14 dias',
  '30d':'Últimos 30 dias', '90d':'Últimos 90 dias',
  ytd:'Ano até hoje', custom:'Período personalizado' };

const ChannelKpiCard = ({ ch }) => {
  const meta = CH[ch.key];
  const [expanded, setExpanded] = React.useState(false);
  const head = (
    <div style={cv.cardTop}>
      <span style={cv.cardName}><span style={{...cv.dot, background:meta.color}}/>{meta.label}</span>
      <span style={{...cv.iconBox, background:_soft(meta.color)}}>
        <Icon name={CHANNEL_ICON[ch.key]} size={17} color={meta.color}/>
      </span>
    </div>
  );
  if (!ch.available) {
    return (<div style={cv.card}>{head}<div style={cv.emptyVal}>—</div><div style={cv.badge}>sem integração</div></div>);
  }
  const { value, delta } = ch.kpi;
  const up = (delta ?? 0) >= 0;
  const brk = ch.breakdown;                       // os 4 canais de receita trazem breakdown
  const clickable = !!brk;
  return (
    <div style={{...cv.card, ...(clickable ? cv.cardClickable : {})}}
      onClick={clickable ? () => setExpanded(v => !v) : undefined}
      title={clickable ? (expanded ? 'Recolher' : 'Ver bruto, refunds e líquido') : undefined}>
      {head}
      <div style={cv.value} className="fenix-num">{USD(value)}</div>
      <div style={cv.deltaRow}>
        <span style={{...cv.deltaPill,
          color: delta==null ? 'var(--fg-3)' : up ? 'var(--positive)' : 'var(--negative)',
          background: delta==null ? 'var(--gray-100)' : up ? 'var(--positive-bg)' : 'var(--negative-bg)'}}>
          {delta==null ? '—' : SIGN(delta)}
        </span>
        <span style={cv.deltaSub}>vs. semana anterior</span>
      </div>
      {brk && (
        <div style={cv.brkFoot}>
          <span style={cv.brkRefunds}>
            {brk.refundCount.toLocaleString('pt-BR')} refund{brk.refundCount===1?'':'s'}
            {brk.chargebackCount>0 && ` · ${brk.chargebackCount.toLocaleString('pt-BR')} chargeback${brk.chargebackCount===1?'':'s'}`}
          </span>
          <span style={{...cv.brkChevron, transform:expanded?'rotate(180deg)':'none'}}>
            <Icon name="arrowDown" size={13} color="var(--fg-3)"/>
          </span>
        </div>
      )}
      {brk && expanded && (
        <div style={cv.brkPanel} onClick={e => e.stopPropagation()}>
          <div style={cv.brkRow}>
            <span style={cv.brkK}>{ch.key === 'direct' ? 'Receita total bruta' : 'Bruto'}</span>
            <span style={cv.brkV} className="fenix-num">{USD(brk.gross)}</span>
          </div>
          <div style={cv.brkRow}>
            <span style={cv.brkK}>Refunds</span>
            <span style={{...cv.brkV, color:'var(--negative)'}} className="fenix-num">
              −{USD(brk.refundAmount)}
            </span>
          </div>
          {brk.chargebackAmount>0 && (
            <div style={cv.brkRow}>
              <span style={cv.brkK}>Chargebacks</span>
              <span style={{...cv.brkV, color:'var(--negative)'}} className="fenix-num">
                −{USD(brk.chargebackAmount)}
              </span>
            </div>
          )}
          <div style={{...cv.brkRow, ...cv.brkRowNet}}>
            <span style={cv.brkK}>{ch.key === 'direct' ? 'Vendas válidas (receita bruta)' : 'Líquido'}</span>
            <span style={cv.brkV} className="fenix-num">{USD(brk.net)}</span>
          </div>
          {brk.sharePct < 100 && (
            <div style={{...cv.brkRow, ...cv.brkRowShare}}>
              <span style={cv.brkShareK}>Minha parte · {brk.sharePct}%</span>
              <span style={cv.brkShareV} className="fenix-num">{USD(brk.share)}</span>
            </div>
          )}
        </div>
      )}
    </div>
  );
};

const ChannelChart = ({ ch, height=200, meta: metaProp, fmtVal=USD, fmtTot=USDk,
                        subtitle='Receita diária · 14 dias', headerKpi=null, granularity='day' }) => {
  const meta = metaProp || CH[ch.key];   // receita usa CH[key]; carrinhos passa meta próprio
  const [ref, w] = useWidth();
  const [hover, setHover] = React.useState(null);
  const series = ch.series || [];
  const data = series.map(p => p.value);

  // cabeçalho (sempre presente)
  const weekTotal = data.reduce((a,b)=>a+b, 0);
  const half = Math.floor(data.length/2) || 1;
  const prevSum = data.slice(0, half).reduce((a,b)=>a+b, 0);
  const lastSum = data.slice(half).reduce((a,b)=>a+b, 0);
  const wDelta = prevSum ? (lastSum-prevSum)/prevSum*100 : null;
  const wUp = (wDelta ?? 0) >= 0;
  // Header: se headerKpi (carrinhos), mostra o KPI do backend (ontem + Δ D-7); senão o total
  // da janela + Δ semana-sobre-semana interno (canais de receita).
  const hVal   = headerKpi ? headerKpi.value : weekTotal;
  const hDelta = headerKpi ? headerKpi.delta : wDelta;
  const hUp = (hDelta ?? 0) >= 0;
  const header = (
    <div style={cv.chartHead}>
      <div>
        <div style={cv.chartName}><span style={{...cv.sq, background:meta.color}}/>{meta.label}</div>
        <div style={cv.chartSub}>{subtitle}</div>
      </div>
      {ch.available && data.length>0 && (
        <div style={{textAlign:'right'}}>
          <div style={cv.chartTotal} className="fenix-num">{(headerKpi?fmtVal:fmtTot)(hVal)}</div>
          <div style={{...cv.chartDelta, color: hDelta==null ? 'var(--fg-3)' : hUp ? 'var(--positive)' : 'var(--negative)'}}>
            {hDelta==null ? '—' : `${hUp?'↑':'↓'} ${PCT(Math.abs(hDelta))} vs. semana anterior`}
          </div>
        </div>
      )}
    </div>
  );

  if (!ch.available || data.length === 0) {
    return (
      <div style={{...cv.chartPanel, height}}>
        {header}
        <div style={{...cv.waiting, height:height-72}}>Aguardando fonte</div>
      </div>
    );
  }

  const padL = 14, padR = 14, padT = 14, padB = 24;
  const cw = Math.max(w, 280);
  const svgH = Math.max(height - 66, 96);
  const innerW = cw - padL - padR, innerH = svgH - padT - padB;
  const max = Math.max(...data), min = Math.min(...data);
  const lo = min - (max-min)*0.45, hi = max + (max-min)*0.2;
  const x = i => padL + (data.length<=1 ? 0 : innerW*i/(data.length-1));
  const y = v => padT + innerH*(1 - (v-lo)/((hi-lo)||1));
  const pts = data.map((v,i)=>[x(i), y(v)]);
  const line = pts.map((p,i)=>(i?'L':'M')+p[0].toFixed(1)+' '+p[1].toFixed(1)).join(' ');
  const area = `M ${x(0)} ${padT+innerH} ` + pts.map(p=>'L '+p[0].toFixed(1)+' '+p[1].toFixed(1)).join(' ')
             + ` L ${x(data.length-1)} ${padT+innerH} Z`;
  const gid = 'chgrad-' + ch.key;
  const sel = hover==null ? data.length-1 : hover;          // hoje selecionado por padrão
  const lblStep = Math.max(1, Math.ceil(series.length/8));

  return (
    <div style={{...cv.chartPanel, height}}>
      {header}
      <div ref={ref} style={{width:'100%', position:'relative'}}>
        <svg width={cw} height={svgH} style={{display:'block'}} onMouseLeave={()=>setHover(null)}>
          <defs>
            <linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor={meta.color} stopOpacity="0.22"/>
              <stop offset="100%" stopColor={meta.color} stopOpacity="0"/>
            </linearGradient>
          </defs>
          <path d={area} fill={`url(#${gid})`}/>
          <path d={line} fill="none" stroke={meta.color} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
          <line x1={x(sel)} y1={padT-2} x2={x(sel)} y2={padT+innerH} stroke={meta.color} strokeWidth="1.5" strokeDasharray="3 4" opacity="0.5"/>
          {pts.map((p,i)=>(
            <g key={i} onMouseEnter={()=>setHover(i)} style={{cursor:'pointer'}}>
              <circle cx={p[0]} cy={p[1]} r="11" fill="transparent"/>
              <circle cx={p[0]} cy={p[1]} r={i===sel?5:3} fill={i===sel?meta.color:'#fff'} stroke={i===sel?'#fff':meta.color} strokeWidth="2"/>
            </g>
          ))}
          {series.map((p,i)=>( (i%lblStep===0 || i===series.length-1) &&
            <text key={i} x={x(i)} y={svgH-6} textAnchor="middle"
              fontFamily="var(--font-num)" fontSize="10"
              fontWeight={i===sel?700:400} fill={i===sel?meta.color:'#9AA3B5'}>
              {trendLabel(p.bucket, granularity)}
            </text>
          ))}
        </svg>
        <div style={{...cv.badge2, left:Math.min(Math.max(x(sel),58), cw-58), top:Math.max(y(data[sel])-50, 2)}}>
          <div style={cv.badgeDay}>{_dayLabel(series[sel].bucket)}</div>
          <div style={cv.badgeVal} className="fenix-num">{fmtVal(data[sel])}</div>
        </div>
      </div>
    </div>
  );
};

const ChannelsView = ({ data, period='ontem' }) => {
  const byKey = {};
  (data?.channels || []).forEach(c => { byKey[c.key] = c; });

  // 3 linhas (Direto / Logicall+Tauk+Salesbound / Email+SMS) cabendo na altura disponível.
  const wrapRef = React.useRef(null);
  const [rowH, setRowH] = React.useState(190);
  React.useEffect(()=>{
    const calc = ()=>{
      const top = wrapRef.current ? wrapRef.current.getBoundingClientRect().top : 380;
      const avail = window.innerHeight - top - 24;
      setRowH(Math.max(170, Math.floor((avail - 28) / 3)));
    };
    calc();
    window.addEventListener('resize', calc);
    return ()=>window.removeEventListener('resize', calc);
  },[]);

  const chans = CHANNEL_ORDER.map(k => byKey[k]).filter(Boolean);
  const gran = data?.seriesWindow?.granularity || 'day';
  // Gráfico de canal de receita: header segue o filtro (kpi do período) + Δ D-7.
  const rev = (ch) => ch && (
    <ChannelChart ch={ch} height={rowH} granularity={gran}
      headerKpi={ch.available ? ch.kpi : null}
      subtitle={_spanSub('Receita', gran, ch.series.length)}/>
  );

  return (
    <>
      <div style={cv.sectionHead}>
        <div style={cv.eye}>Receita por canal</div>
        <div style={cv.sub}>{PERIOD_TITLE_CH[period] || period} · variação vs. semana anterior</div>
      </div>
      <div className="kpi-grid" style={cv.kpiGrid}>
        {chans.map(ch => <ChannelKpiCard key={ch.key} ch={ch}/>)}
      </div>

      <div style={{...cv.sectionHead, marginTop:22}}>
        <div style={cv.eye}>Série temporal</div>
      </div>
      <div ref={wrapRef} style={cv.chartCol}>
        {rev(byKey.direct)}
        <div style={cv.chartRow3}>
          {rev(byKey.logicall)}
          {rev(byKey.tauk)}
          {rev(byKey.salesbound)}
        </div>
        <div style={cv.chartRow}>
          {rev(byKey.email)}
          {rev(byKey.sms)}
        </div>
      </div>

      {data?.abandonedCarts?.available && (
        <>
          <div style={{...cv.sectionHead, marginTop:22}}>
            <div style={cv.eye}>Carrinhos abandonados</div>
            <div style={cv.sub}>buygoods · contagem diária (não é receita)</div>
          </div>
          <ChannelChart
            ch={{ key:'abandoned', available:true, series:data.abandonedCarts.series }}
            meta={{ label:'Carrinhos abandonados', color:'#64748B' }}
            fmtVal={NUM} fmtTot={NUMk} granularity={gran}
            subtitle={_spanSub('buygoods ·', gran, data.abandonedCarts.series.length)}
            headerKpi={data.abandonedCarts.kpi}
            height={rowH}/>
        </>
      )}
    </>
  );
};

const cv = {
  sectionHead:{ marginBottom:12 },
  eye:{ font:'var(--text-label)', letterSpacing:'.05em', textTransform:'uppercase', color:'var(--fg-3)' },
  sub:{ font:'var(--text-body-sm)', color:'var(--fg-3)', marginTop:4 },

  kpiGrid:{ display:'grid', gridTemplateColumns:'repeat(6,minmax(0,1fr))', gap:16, marginBottom:8 },
  card:{ background:'#fff', border:'1px solid var(--border-1)', borderRadius:'var(--r-lg)',
    padding:16, boxShadow:'var(--shadow-sm)' },
  cardTop:{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:12 },
  cardName:{ display:'inline-flex', alignItems:'center', gap:7, font:'700 12px/1.2 var(--font-sans)',
    letterSpacing:'.04em', textTransform:'uppercase', color:'var(--fg-2)' },
  dot:{ width:9, height:9, borderRadius:'50%', flex:'none' },
  iconBox:{ width:30, height:30, borderRadius:'var(--r-sm)', display:'flex', alignItems:'center', justifyContent:'center', flex:'none' },
  value:{ font:'800 24px/1 var(--font-num)', letterSpacing:'-.02em', color:'var(--fg-1)', whiteSpace:'nowrap', fontVariantNumeric:'tabular-nums' },
  emptyVal:{ font:'800 24px/1 var(--font-sans)', color:'var(--gray-300)' },
  badge:{ display:'inline-block', marginTop:10, font:'600 10.5px/1 var(--font-sans)',
    letterSpacing:'.04em', textTransform:'uppercase', color:'var(--fg-3)',
    background:'var(--gray-100)', borderRadius:'var(--r-pill)', padding:'5px 9px' },
  deltaRow:{ display:'flex', alignItems:'center', gap:9, marginTop:10 },
  deltaPill:{ font:'700 11px/1 var(--font-mono)', padding:'4px 7px', borderRadius:'var(--r-sm)' },
  deltaSub:{ font:'var(--text-body-sm)', color:'var(--fg-3)' },

  cardClickable:{ cursor:'pointer' },
  brkFoot:{ display:'flex', alignItems:'center', justifyContent:'space-between', gap:8,
    marginTop:12, paddingTop:10, borderTop:'1px solid var(--border-1)' },
  brkRefunds:{ font:'600 11px/1 var(--font-sans)', letterSpacing:'.02em', color:'var(--fg-3)' },
  brkChevron:{ display:'inline-flex', transition:'transform .2s var(--ease)' },
  brkPanel:{ marginTop:10, display:'flex', flexDirection:'column', gap:7 },
  brkRow:{ display:'flex', alignItems:'baseline', justifyContent:'space-between', gap:10 },
  brkK:{ font:'500 12px/1.2 var(--font-sans)', color:'var(--fg-3)' },
  brkV:{ font:'700 13px/1 var(--font-mono)', color:'var(--fg-1)' },
  brkRowNet:{ marginTop:3, paddingTop:8, borderTop:'1px dashed var(--border-2)' },
  brkRowShare:{ marginTop:4, padding:'9px 11px', background:'var(--fenix-navy)', borderRadius:'var(--r-md)' },
  brkShareK:{ font:'700 11px/1.2 var(--font-sans)', letterSpacing:'.03em', textTransform:'uppercase', color:'#FFA866' },
  brkShareV:{ font:'800 15px/1 var(--font-mono)', color:'#F6E9E0' },

  chartCol:{ display:'flex', flexDirection:'column', gap:14 },
  chartRow:{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:18 },
  chartRow3:{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:18 },
  chartPanel:{ background:'#fff', border:'1px solid var(--border-1)', borderRadius:'var(--r-lg)',
    padding:'16px 20px 10px', boxShadow:'var(--shadow-sm)', overflow:'hidden' },
  chartHead:{ display:'flex', alignItems:'flex-start', justifyContent:'space-between', gap:12, marginBottom:4 },
  chartName:{ display:'inline-flex', alignItems:'center', gap:9, font:'700 16px/1.2 var(--font-sans)', color:'var(--fg-1)' },
  chartSub:{ font:'var(--text-body-sm)', color:'var(--fg-3)', marginTop:3 },
  sq:{ width:10, height:10, borderRadius:3, flex:'none' },
  chartTotal:{ font:'800 19px/1 var(--font-num)', color:'var(--fg-1)', fontVariantNumeric:'tabular-nums' },
  chartDelta:{ font:'600 11px/1 var(--font-mono)', marginTop:5 },
  waiting:{ display:'flex', alignItems:'center', justifyContent:'center',
    color:'var(--fg-3)', font:'600 13px/1 var(--font-sans)',
    border:'1px dashed var(--border-2)', borderRadius:'var(--r-md)', marginTop:6 },
  badge2:{ position:'absolute', transform:'translateX(-50%)', background:'var(--fenix-navy)',
    padding:'7px 11px', borderRadius:'var(--r-md)', boxShadow:'var(--shadow-lg)',
    pointerEvents:'none', whiteSpace:'nowrap', textAlign:'center' },
  badgeDay:{ font:'600 10px/1 var(--font-sans)', letterSpacing:'.03em', color:'#FFA866', marginBottom:4 },
  badgeVal:{ font:'700 15px/1 var(--font-mono)', color:'#F6E9E0' },
};

Object.assign(window, { ChannelsView, ChannelKpiCard, ChannelChart });
