// Affiliate performance table — sortable, sticky header, total-tier color, drawer.
const TrafficChip = ({ t }) => {
  const map = { fb:['FB-heavy','var(--positive-bg)','var(--positive)'], google:['Google','var(--info-bg)','var(--info)'] };
  const [l,bg,fg] = map[t] || map.fb;
  return <span style={{font:'600 10.5px/1 var(--font-sans)', padding:'4px 8px', borderRadius:'var(--r-pill)', background:bg, color:fg, whiteSpace:'nowrap'}}>{l}</span>;
};

const TIER = {
  high: { bar:'var(--positive)', label:'Alto' },
  mid:  { bar:'var(--warning)',  label:'Médio' },
  low:  { bar:'var(--negative)', label:'Baixo' },
};
function tierOf(total, t1, t2){ return total>=t2 ? 'high' : total>=t1 ? 'mid' : 'low'; }

const RateioCell = ({ matched, rateio, label, dz }) => {
  const [tipStyle, setTipStyle] = React.useState(null);
  const total = (matched ?? 0) + (rateio ?? 0);
  const TIP_H = 148;

  const onEnter = (e) => {
    if (!rateio || rateio <= 0) return;
    const rect = e.currentTarget.getBoundingClientRect();
    const right = window.innerWidth - rect.right;
    // mostra acima se houver espaço, senão abaixo
    if (rect.top >= TIP_H + 8) {
      setTipStyle({ position:'fixed', right, bottom: window.innerHeight - rect.top + 4, top:'auto' });
    } else {
      setTipStyle({ position:'fixed', right, top: rect.bottom + 4, bottom:'auto' });
    }
  };

  return (
    <td style={{...tbl.td, ...dz}} className="fenix-num"
      onMouseEnter={onEnter}
      onMouseLeave={() => setTipStyle(null)}
    >
      {USD(total)}
      {tipStyle && rateio > 0 && (
        <div style={{...tbl.rateioTip, ...tipStyle}}>
          <div style={tbl.rateioTipHeader}>{label}</div>
          <div style={tbl.rateioTipDivider}/>
          <div style={tbl.rateioTipRow}>
            <span>● Atribuído</span>
            <span>{USD(matched ?? 0)}</span>
          </div>
          <div style={tbl.rateioTipRow}>
            <span style={{color:'var(--fg-3)'}}>◌ Rateio est.</span>
            <span style={{color:'var(--fg-3)'}}>{USD(rateio)}</span>
          </div>
          <div style={tbl.rateioTipDivider}/>
          <div style={{...tbl.rateioTipRow, fontWeight:700, marginBottom:0}}>
            <span>Total</span>
            <span>{USD(total)}</span>
          </div>
        </div>
      )}
    </td>
  );
};

const AffiliateTable = ({ rows, onSelect, selectedId, dense=false, loading=false }) => {
  const dz = dense ? { paddingTop:6, paddingBottom:6 } : {};
  const [sort, setSort] = React.useState('total');
  const [dir, setDir] = React.useState(-1);
  const sorted = React.useMemo(()=>{
    const unattr = rows.filter(a => a.name === 'Não atribuído');
    const rest = rows.filter(a => a.name !== 'Não atribuído').sort((x,y)=>{
      const a = sort==='name' ? x.name : x[sort];
      const b = sort==='name' ? y.name : y[sort];
      if(a<b) return -1*dir; if(a>b) return 1*dir; return 0;
    });
    return [...unattr, ...rest];
  },[rows,sort,dir]);
  // tier thresholds from current set (terciles by total)
  const totals = [...rows].map(a=>a.total).sort((a,b)=>a-b);
  const t1 = totals[Math.floor(totals.length/3)] || 0;
  const t2 = totals[Math.floor(totals.length*2/3)] || 0;

  const click = (key)=>{ if(sort===key) setDir(-dir); else { setSort(key); setDir(-1); } };
  const Th = ({k,label,align='right',w,title}) => (
    <th style={{...tbl.th, textAlign:align, width:w}} onClick={()=>click(k)} title={title}>
      <span style={{display:'inline-flex', alignItems:'center', gap:4, cursor:'pointer', flexDirection:align==='right'?'row-reverse':'row'}}>
        {label}
        <Icon name={sort===k ? (dir<0?'sortDesc':'sortAsc') : 'sortBoth'} size={12}
          color={sort===k?'var(--fenix-orange)':'var(--gray-300)'}/>
      </span>
    </th>
  );

  return (
    <div style={{...tbl.wrap, opacity: loading ? 0.45 : 1, transition:'opacity .25s'}}>
      <div style={tbl.head}>
        <div>
          <div style={tbl.eye}>Detalhe consolidado</div>
          <div style={tbl.title}>Performance por Afiliado</div>
        </div>
        <div style={tbl.headRight}>
          <span style={tbl.smsNote}>SMS em construção — fora do total</span>
          <span style={tbl.count}>{loading ? 'Carregando…' : `${rows.length} afiliados`}</span>
          <div style={tbl.tierKey}>
            {['high','mid','low'].map(k=>(
              <span key={k} style={tbl.tierItem}><span style={{...tbl.tierDot, background:TIER[k].bar}}/>{TIER[k].label}</span>
            ))}
          </div>
        </div>
      </div>
      <div style={tbl.scroll}>
        <table style={tbl.table}>
          <thead><tr>
            <th style={{...tbl.th, ...tbl.thLeft, paddingLeft:22, width:'24%'}} onClick={()=>click('name')}>
              <span style={{display:'inline-flex', alignItems:'center', gap:4, cursor:'pointer'}}>
                Afiliado <Icon name={sort==='name'?(dir<0?'sortDesc':'sortAsc'):'sortDesc'} size={12} color={sort==='name'?'var(--fenix-orange)':'var(--gray-300)'}/>
              </span>
            </th>
            <Th k="grossTotal" label="Receita total bruta" title="Completed + refunds + chargebacks · canal direto, sem gorduras"/>
            <Th k="logicall" label="Logicall"/>
            <Th k="tauk" label="Tauk"/>
            <Th k="salesbound" label="Salesbound"/>
            <Th k="email" label="Email"/>
            <Th k="sms" label="SMS ⚠"/>
            <Th k="aov" label="AOV"/>
            <th style={{...tbl.th}} title="Taxa de refund do canal direto (buygoods, clickbank, digistore24)">Taxa Refund</th>
            <Th k="total" label="Total"/>
          </tr></thead>
          <tbody>
            {(loading ? [] : sorted).map(a=>{
              const on = a.id===selectedId;
              const isUnattr = a.name === 'Não atribuído';
              const tier = tierOf(a.total, t1, t2);
              return (
              <tr key={a.platform + '·' + a.name} onClick={()=>onSelect(a)}
                style={{...tbl.tr, ...(on?tbl.trOn:{}), ...(isUnattr&&!on?tbl.trUnattr:{})}}
                onMouseEnter={e=>{if(!on)e.currentTarget.style.background=isUnattr?'rgba(253,113,25,0.08)':'var(--gray-50)';}}
                onMouseLeave={e=>{if(!on)e.currentTarget.style.background=isUnattr?'rgba(253,113,25,0.04)':'transparent';}}>
                <td style={{...tbl.td, ...tbl.tdLeft, ...dz, paddingLeft:0}}>
                  <div style={tbl.aff}>
                    <span style={{...tbl.tierBar, background:isUnattr?'var(--fg-4)':TIER[tier].bar}}/>
                    <div style={{...tbl.av, background:isUnattr?'var(--bg-sunken)':a.avatar, color:isUnattr?'var(--fg-3)':'#F6E9E0', border:isUnattr?'1.5px dashed var(--border-2)':'none'}}>
                      {isUnattr ? '?' : initials(a.name)}
                    </div>
                    <div style={{minWidth:0}}>
                      <div style={{...tbl.name, ...(isUnattr?{color:'var(--fg-3)',fontStyle:'italic'}:{})}}>{a.name}</div>
                      <div style={tbl.idline}>
                        {isUnattr
                          ? <span style={tbl.unattrChip}>⚠ sem atribuição</span>
                          : <><span style={tbl.id}>{a.id}</span><TrafficChip t={a.traffic}/></>
                        }
                      </div>
                    </div>
                  </div>
                </td>
                <td style={{...tbl.td, ...dz}} className="fenix-num">{USD(a.grossTotal)}</td>
                <RateioCell matched={a.logicall} rateio={a.logicallRateio ?? 0} label="Logicall" dz={dz}/>
                <RateioCell matched={a.tauk} rateio={a.taukRateio ?? 0} label="Tauk" dz={dz}/>
                <RateioCell matched={a.salesbound} rateio={a.sbRateio ?? 0} label="Salesbound" dz={dz}/>
                <td style={{...tbl.td, ...dz}} className="fenix-num">{USD(a.email)}</td>
                <td style={{...tbl.td, ...dz, ...(a.sms<=0?tbl.muted:{})}} className="fenix-num">{a.sms>0?USD(a.sms):'—'}</td>
                <td style={{...tbl.td, ...dz, color:'var(--fg-2)'}} className="fenix-num">
                  <div>{USD(a.aov)}</div>
                  <div style={{...tbl.aovDelta, color:a.aovDelta>=0?'var(--positive)':'var(--negative)'}}>
                    {a.aovDelta>=0?'▲':'▼'} {Math.abs(a.aovDelta).toLocaleString('pt-BR',{minimumFractionDigits:1,maximumFractionDigits:1})}%
                  </div>
                </td>
                {(() => {
                  const dr = a.directRefunds;
                  if (!dr) return <td style={{...tbl.td, ...dz, color:'var(--fg-3)'}} className="fenix-num">—</td>;
                  const r = dr.rate;
                  const col = r <= 13.7 ? 'var(--positive)' : r <= 17 ? 'var(--warning)' : r <= 20 ? '#FD7119' : 'var(--negative)';
                  const tip = `${dr.refunds} refunds · ${dr.chargebacks} chargebacks · ${dr.cancelamentos} cancelamentos · ${USD(dr.amountReturned)} devolvido`;
                  return <td style={{...tbl.td, ...dz, color: col, fontWeight:700}} className="fenix-num" title={tip}>{PCT(r)}</td>;
                })()}
                <td style={{...tbl.tdTotal, ...dz}}>
                  <div style={tbl.totalVal} className="fenix-num">{USD(a.total)}</div>
                  <div style={{...tbl.delta, color:a.delta>=0?'var(--positive)':'var(--negative)'}}>
                    {a.delta>=0?'▲':'▼'} {Math.abs(a.delta).toLocaleString('pt-BR',{minimumFractionDigits:1,maximumFractionDigits:1})}%
                  </div>
                </td>
              </tr>);
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
};

const tbl = {
  wrap:{ background:'#fff', border:'1px solid var(--border-1)', borderRadius:'var(--r-lg)', boxShadow:'var(--shadow-sm)', overflow:'hidden' },
  head:{ display:'flex', alignItems:'center', justifyContent:'space-between', padding:'18px 22px', borderBottom:'1px solid var(--border-1)', gap:16, flexWrap:'wrap' },
  eye:{ font:'var(--text-label)', letterSpacing:'.05em', textTransform:'uppercase', color:'var(--fg-3)' },
  title:{ font:'var(--text-h3)', color:'var(--fg-1)', marginTop:4 },
  headRight:{ display:'flex', alignItems:'center', gap:16 },
  count:{ font:'600 12px/1 var(--font-mono)', color:'var(--fg-2)', background:'var(--bg-sunken)', padding:'7px 12px', borderRadius:'var(--r-pill)' },
  smsNote:{ font:'600 10.5px/1 var(--font-sans)', color:'var(--warning)', background:'var(--warning-bg)', padding:'6px 10px', borderRadius:'var(--r-pill)', whiteSpace:'nowrap' },
  tierKey:{ display:'flex', gap:13 },
  tierItem:{ display:'inline-flex', alignItems:'center', gap:6, font:'var(--text-caption)', color:'var(--fg-3)' },
  tierDot:{ width:8, height:8, borderRadius:'50%' },
  scroll:{ maxHeight:520, overflowY:'auto', overflowX:'auto' },
  table:{ width:'100%', borderCollapse:'collapse', minWidth:900 },
  th:{ font:'700 10.5px/1 var(--font-sans)', letterSpacing:'.04em', textTransform:'uppercase', color:'var(--fg-3)',
    padding:'12px 14px', background:'var(--bg-sunken)', borderBottom:'1px solid var(--border-2)', whiteSpace:'nowrap',
    userSelect:'none', position:'sticky', top:0, zIndex:2 },
  thLeft:{ textAlign:'left' },
  tr:{ cursor:'pointer', transition:'background .12s' },
  trOn:{ background:'var(--fenix-orange-100)' },
  trUnattr:{ background:'rgba(253,113,25,0.04)' },
  unattrChip:{ font:'600 10.5px/1 var(--font-sans)', padding:'4px 8px', borderRadius:'var(--r-pill)', background:'var(--warning-bg)', color:'var(--warning)', whiteSpace:'nowrap' },
  td:{ padding:'12px 14px', borderBottom:'1px solid var(--border-1)', font:'var(--text-mono-sm)', color:'var(--fg-1)', textAlign:'right', whiteSpace:'nowrap' },
  tdLeft:{ textAlign:'left' },
  muted:{ color:'var(--fg-4)' },
  aff:{ display:'flex', alignItems:'center', gap:12 },
  tierBar:{ width:4, alignSelf:'stretch', borderRadius:'0 3px 3px 0', flex:'none' },
  av:{ width:34, height:34, borderRadius:'50%', color:'#F6E9E0', font:'700 12px/1 var(--font-sans)', display:'flex', alignItems:'center', justifyContent:'center', flex:'none', marginLeft:4 },
  name:{ font:'700 13px/1.1 var(--font-mono)', color:'var(--fg-1)', letterSpacing:'-.01em' },
  idline:{ display:'flex', alignItems:'center', gap:8, marginTop:5 },
  id:{ font:'10.5px/1 var(--font-mono)', color:'var(--fg-4)' },
  tdTotal:{ padding:'12px 22px 12px 14px', borderBottom:'1px solid var(--border-1)', textAlign:'right', whiteSpace:'nowrap' },
  totalVal:{ font:'800 14px/1 var(--font-mono)', color:'var(--fg-1)' },
  delta:{ font:'600 10.5px/1 var(--font-mono)', marginTop:5 },
  aovDelta:{ font:'600 10px/1 var(--font-mono)', marginTop:4 },
  rateioTip:{ zIndex:9999,
    background:'#fff', border:'1px solid var(--border-1)',
    borderRadius:'var(--r-md)', boxShadow:'0 4px 16px rgba(0,0,0,.10)',
    padding:'10px 14px', minWidth:196,
    font:'var(--text-mono-sm)', textAlign:'left', whiteSpace:'nowrap' },
  rateioTipHeader:{ font:'700 11px/1 var(--font-sans)', color:'var(--fg-2)',
    letterSpacing:'.04em', textTransform:'uppercase', marginBottom:8 },
  rateioTipDivider:{ height:1, background:'var(--border-1)', margin:'8px 0' },
  rateioTipRow:{ display:'flex', justifyContent:'space-between', gap:24,
    font:'var(--text-mono-sm)', color:'var(--fg-1)', marginBottom:4 },
};

Object.assign(window, { AffiliateTable, RateioCell, TrafficChip, tierOf, TIER });
