// KPI row (5 cards) + Top-10 horizontal bars.
const marginHealth = (m) =>
  m >= 5 ? { color:'var(--positive)', bg:'var(--positive-bg)', label:'Saudável' }
  : m >= 3 ? { color:'var(--warning)', bg:'var(--warning-bg)', label:'Atenção' }
  : { color:'var(--negative)', bg:'var(--negative-bg)', label:'Crítico' };

const KpiRow = ({ rows, onKpiSelect, period, customRange, composition, products, variant = 'visao' }) => {
  const attrRows = rows.filter(a => a.name !== 'Não atribuído');
  const total  = rows.reduce((s,a)=>s+a.total,0);
  const active = attrRows.length;
  const totalOrders = rows.reduce((s,a) => s + (a.orders||0), 0);
  const wMargin = total ? rows.reduce((s,a)=>s+a.total*a.margin,0)/total : 0;
  const mh = marginHealth(wMargin);

  // Canal direto (FE+BE) a partir da composition; sem composition (mock) → fallback/'—'.
  const c = composition;
  const feRev = c ? c.directFrontend.revenue : null;
  const beRev = c ? c.directBackend.revenue : null;
  const directRev = c ? feRev + beRev : rows.reduce((s,a)=>s+(a.direct||0),0);
  const directOrders = c ? c.directFrontend.orders + c.directBackend.orders : totalOrders;
  const refC = c ? c.directFrontend.refundCount + c.directBackend.refundCount : null;
  const refundRate = (c && directOrders + refC > 0) ? refC / (directOrders + refC) * 100 : null;
  const rh = refundRate != null ? refundHealth(refundRate) : null;
  // AOV por checkout = (FE+BE) ÷ ordens FE — usa os campos *_aov (spec 2026-07-24), distintos
  // de directRev (acima), que fica bruto e serve só p/ exibição de receita.
  const feOrdersTot = c ? c.directFrontend.orders : rows.reduce((s,a)=>s+(a.feOrders||0),0);
  const aov = c
    ? (feOrdersTot ? ((c.directFrontend.revenueAov ?? 0) + (c.directBackend.revenueAov ?? 0)) / feOrdersTot : 0)
    : (feOrdersTot ? directRev / feOrdersTot : 0);

  // Consolidado bruto do período (spec 2026-07-24-consolidado-bruto-global): Completed + refunds
  // + chargebacks, sem gorduras (Logicall/Salesbound/Tauk ficam fora — ver card Recuperação).
  // Sem composition (demo mode), soma as linhas do mock (buildAffiliates já traz os 6 campos),
  // então o drawer mostra deduções coerentes com o gross em vez de zeradas.
  const consolidado = c ? {
    grossTotal: c.grossTotal ?? 0, refundAmountGross: c.refundAmountGross ?? 0,
    refundCount: c.refundCount ?? 0, chargebackAmountGross: c.chargebackAmountGross ?? 0,
    chargebackCount: c.chargebackCount ?? 0, validOrders: c.validOrders ?? 0,
    partialAmount: c.partialAmount ?? 0, partialCount: c.partialCount ?? 0,
  } : {
    grossTotal: rows.reduce((s,a)=>s+(a.grossTotal||0),0),
    refundAmountGross: rows.reduce((s,a)=>s+(a.refundAmountGross||0),0),
    chargebackAmountGross: rows.reduce((s,a)=>s+(a.chargebackAmountGross||0),0),
    refundCount: rows.reduce((s,a)=>s+(a.refundCount||0),0),
    chargebackCount: rows.reduce((s,a)=>s+(a.chargebackCount||0),0),
    validOrders: rows.reduce((s,a)=>s+(a.validOrders||0),0),
    partialAmount: rows.reduce((s,a)=>s+(a.partialAmount||0),0),
    partialCount: rows.reduce((s,a)=>s+(a.partialCount||0),0),
  };

  // Cards por variante (spec 2026-07-03). Todos clicáveis: `kind` roteia o conteúdo do drawer.
  const cVendas = { eye:'Total de Vendas', val:totalOrders.toLocaleString('pt-BR'), sub:'pedidos no período',
    icon:'cart', tint:'var(--fenix-blue-100)', fg:'var(--fenix-blue)',
    kind:'vendas', data:{ composition: c } };
  const cRefund = (eye) => ({ eye, val: refundRate != null ? PCT(refundRate) : '—',
    big: refundRate != null, fg: rh ? rh.color : 'var(--fg-1)',
    icon:'refresh', tint: rh ? rh.bg : 'var(--gray-100)', health: rh || undefined,
    sub:'canal direto · por coorte de venda',
    healthNote:'Régua: ≤13,7% saudável · ≤17% atenção · ≤20% alerta · >20% corte',
    kind:'refund-wilson', data:{ products: products || null, rows, composition: c } });
  const cMargem = { eye:'Margem Operacional', val:PCT(wMargin), big:true, fg:mh.color,
    icon:'target', tint:mh.bg, health:mh, sub:'Meta ≥ 5% · líq. de CPA e custos',
    kind:'margem', data:{ total, cpaPaid: rows.reduce((s,a)=>s+(a.cpaPaid||0),0), wMargin } };
  // demo: gorduras líquidas como aproximação do bruto (sem deduções no mock)
  const recFallback = rows.reduce((s,a)=>s+(a.logicall||0)+(a.tauk||0)+(a.salesbound||0),0);
  const rec = c?.recuperacao ?? { gross: recFallback, refundAmount: 0, chargebackAmount: 0,
    refundCount: 0, chargebackCount: 0, net: recFallback };
  const cRecuperacao = { eye:'Recuperação', val:USD(rec.gross ?? 0),
    sub:'Logicall · Salesbound · Tauk — bruto', icon:'refresh',
    tint:'var(--fenix-blue-100)', fg:'var(--fenix-blue)',
    kind:'recuperacao', data:{ rec } };

  const cConsolidado = { eye:'Receita total bruta do período', val:USD(consolidado.grossTotal),
    sub:'Completed + refunds + chargebacks · sem gorduras',
    icon:'dollar', tint:'var(--fenix-orange-100)', fg:'var(--fenix-orange-600)',
    kind:'receita-consolidada', data: consolidado, breakdown: c || null };

  const cards = variant === 'afiliados' ? [
    cConsolidado,
    { eye:'Afiliados Ativos', val:String(active), sub:'com vendas no período',
      icon:'users', tint:'var(--fenix-blue-100)', fg:'var(--fenix-blue)',
      kind:'ativos', data:{ rows: attrRows } },
    cVendas,
    { eye:'AOV', val:USD(aov), sub:'por checkout',
      icon:'chart', tint:'var(--fenix-blue-100)', fg:'var(--fenix-blue)',
      kind:'aov', data:{ composition: c } },
    cRefund('Total de Reembolso'),
  ] : [
    cConsolidado,
    cVendas,
    cRefund('% de Refund Total'),
    cMargem,
    cRecuperacao,
  ];
  return (
    <div style={kp.row} className="kpi-grid">
      {cards.map((c,i)=>(
        <div key={i} style={{...kp.card, cursor:'pointer', transition:'box-shadow .15s, transform .15s'}}
          onClick={()=>onKpiSelect&&onKpiSelect(c)}
          onMouseEnter={e=>{e.currentTarget.style.boxShadow='var(--shadow-md)';e.currentTarget.style.transform='translateY(-1px)';}}
          onMouseLeave={e=>{e.currentTarget.style.boxShadow='var(--shadow-sm)';e.currentTarget.style.transform='none';}}>
          {/* Estilo Produtos (spec 2026-07-13): quadradinho colorido + rótulo, sem chip de ícone. */}
          <div style={kp.top}>
            <span style={{...kp.dot, background:c.fg}}/>
            <span style={kp.eye}>{c.eye}</span>
          </div>
          <div style={{...kp.val, ...(c.mono?kp.valMono:{}), ...(c.big?{color:c.fg}:{})}} className="fenix-num">
            {c.big && c.pos!==undefined && <Icon name={c.pos?'arrowUp':'arrowDown'} size={22} color={c.fg} style={{marginRight:2, verticalAlign:'-3px'}}/>}
            {c.val}
          </div>
          {/* Saúde vira o sub colorido (padrão Produtos), não mais o chip. */}
          {c.health ? (
            <div style={{...kp.sub, color:c.health.color}}>{c.health.label}</div>
          ) : (
            <div style={kp.sub}>{c.sub}</div>
          )}
        </div>
      ))}
    </div>
  );
};

const TopAffiliates = ({ rows, onSelect }) => {
  // Ranking por receita total bruta (spec 2026-07-24-consolidado-bruto-global). Comportamento
  // pré-existente mantido de propósito: 1 linha por (nome, plataforma) — um afiliado presente
  // em 2 plataformas aparece 2× no ranking (já era assim antes desta mudança).
  const gross = (a) => a.grossTotal ?? a.total;
  const top = [...rows].filter(a => a.name !== 'Não atribuído').sort((a,b)=>gross(b)-gross(a)).slice(0,10);
  const max = Math.max(...top.map(gross), 1);
  return (
    <div style={kp.panel}>
      <div style={kp.panelHead}>
        <div>
          <div style={kp.panelEye}>Ranking</div>
          <div style={kp.panelTitle}>Top 10 Afiliados por Receita Total Bruta</div>
        </div>
        <span style={kp.headTag}>{rows.length} afiliados</span>
      </div>
      <div style={kp.bars}>
        {top.map((a,i)=>(
          <button key={a.id} style={kp.barRow} onClick={()=>onSelect&&onSelect(a)}
            onMouseEnter={e=>e.currentTarget.style.background='var(--gray-50)'}
            onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
            <span style={kp.barRank}>{String(i+1).padStart(2,'0')}</span>
            <span style={kp.barName}>{a.name}</span>
            <div style={kp.barTrack}>
              <div style={{...kp.barFill, width:(gross(a)/max*100)+'%'}}/>
            </div>
            <span style={kp.barVal} className="fenix-num">{USD(gross(a))}</span>
          </button>
        ))}
      </div>
    </div>
  );
};

const kp = {
  row:{ display:'grid', gridTemplateColumns:'repeat(5,minmax(0,1fr))', gap:16, marginBottom:18 },
  card:{ background:'#fff', border:'1px solid var(--border-1)', borderRadius:'var(--r-lg)', padding:'16px 18px', boxShadow:'var(--shadow-sm)', minWidth:0 },
  top:{ display:'flex', alignItems:'center', gap:8, marginBottom:11 },
  dot:{ width:9, height:9, borderRadius:2, flex:'none' },
  eye:{ font:'var(--text-label)', letterSpacing:'.05em', textTransform:'uppercase', color:'var(--fg-3)' },
  ic:{ width:32, height:32, borderRadius:'var(--r-sm)', display:'flex', alignItems:'center', justifyContent:'center', flex:'none' },
  val:{ font:'800 24px/1.05 var(--font-num)', color:'var(--fg-1)', letterSpacing:'-.015em', whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis', fontVariantNumeric:'tabular-nums' },
  valMono:{ font:'800 20px/1.05 var(--font-mono)', letterSpacing:'-.01em' },
  sub:{ font:'var(--text-caption)', color:'var(--fg-3)', marginTop:7 },
  healthWrap:{ display:'flex', flexDirection:'column', gap:7, marginTop:9 },
  healthChip:{ display:'inline-flex', alignSelf:'flex-start', alignItems:'center', gap:6, font:'700 11px/1 var(--font-sans)',
    padding:'5px 9px', borderRadius:'var(--r-pill)' },
  healthDot:{ width:7, height:7, borderRadius:'50%', flex:'none' },
  healthThresh:{ fontWeight:500, color:'var(--fg-3)', marginLeft:1 },

  panel:{ background:'#fff', border:'1px solid var(--border-1)', borderRadius:'var(--r-lg)', padding:'20px 22px', boxShadow:'var(--shadow-sm)' },
  panelHead:{ display:'flex', alignItems:'flex-start', justifyContent:'space-between', marginBottom:16, gap:16 },
  panelEye:{ font:'var(--text-label)', letterSpacing:'.05em', textTransform:'uppercase', color:'var(--fg-3)' },
  panelTitle:{ font:'var(--text-h3)', color:'var(--fg-1)', marginTop:4 },
  headTag:{ font:'600 11px/1 var(--font-mono)', color:'var(--fg-3)', background:'var(--bg-sunken)', padding:'6px 10px', borderRadius:'var(--r-pill)', whiteSpace:'nowrap' },

  bars:{ display:'flex', flexDirection:'column', gap:3 },
  barRow:{ display:'flex', alignItems:'center', gap:12, width:'100%', border:0, background:'transparent',
    borderRadius:'var(--r-sm)', padding:'7px 8px', cursor:'pointer', transition:'background .12s', textAlign:'left' },
  barRank:{ font:'700 11px/1 var(--font-mono)', color:'var(--fg-4)', width:18, flex:'none' },
  barName:{ font:'700 12.5px/1 var(--font-mono)', color:'var(--fg-1)', width:118, flex:'none', whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' },
  barTrack:{ flex:1, height:14, background:'var(--gray-100)', borderRadius:'var(--r-pill)', overflow:'hidden' },
  barFill:{ height:'100%', background:'linear-gradient(90deg, #FFA866, var(--fenix-orange))', borderRadius:'var(--r-pill)', transition:'width .5s var(--ease)' },
  barVal:{ font:'700 12.5px/1 var(--font-mono)', color:'var(--fg-1)', width:74, textAlign:'right', flex:'none' },
};

Object.assign(window, { KpiRow, TopAffiliates, marginHealth });
