// js/components/widgets/clientes/ClientRiskTable.jsx
// [v224.250 20260817] Busca + filtros + export (admin-only) nos painéis de risco da aba Insights.
// UI PURA — não recalcula LTV/ticket/daysSince. Consome `rows` (fatia de clientLTV) já pronta.
// Props: rows, visibleClients, user, onOpen360, title, accent, bandSet ('churn'|'inativos'),
//        headers (4 labels), emptyMsg, maxHeight, exportSlug, semCompraLabel (bool)
// Deps runtime: window.fmt, window.nid, window.Sentry (opcional)
// PROIBIDO localStorage aqui (AUDM3_4_LOCALSTORAGE) — todo estado é local ao componente.
(function(){
  'use strict';

  // Faixas de inatividade por painel. Módulo-level = identidade estável (não churna useMemo).
  const BAND_SETS = {
    churn: [
      { key:'31-45',   label:'31-45d',   min:31,  max:45 },
      { key:'46-60',   label:'46-60d',   min:46,  max:60 },
      { key:'61-90',   label:'61-90d',   min:61,  max:90 }
    ],
    inativos: [
      { key:'91-180',  label:'91-180d',  min:91,  max:180 },
      { key:'181-365', label:'181-365d', min:181, max:365 },
      { key:'365+',    label:'+365d',    min:366, max:Infinity }
    ]
  };

  const LTV_PRESETS = [
    { key:'',      label:'Todos'  },
    { key:'5000',  label:'≥ 5k'   },
    { key:'10000', label:'≥ 10k'  },
    { key:'20000', label:'≥ 20k'  }
  ];

  // acento-insensível + case-insensível (base tem "Lucileia", "laercio", "essencia decor")
  function norm(s){
    return String(s == null ? '' : s).normalize('NFD').replace(/[\u0300-\u036f]/g,'').toLowerCase().trim();
  }

  // daysSince sentinela do computeClientLTV quando o cliente não tem data de venda
  function isSemCompra(d){ return Number(d||0) > 9000; }

  function ClientRiskTable(props){
    // Defensive coalesce (regra_destructure_data_props_com_default v223.42.2)
    const rows = props.rows || [];
    const visibleClients = props.visibleClients || [];
    const user = props.user || {};
    const onOpen360 = props.onOpen360 || function(){};
    const title = props.title || '';
    const accent = props.accent || '#EA580C';
    const bands = BAND_SETS[props.bandSet] || BAND_SETS.churn;
    const headers = props.headers || ['Cliente','Inativo','LTV','Ticket'];
    const emptyMsg = props.emptyMsg || '✅ Nenhum cliente em risco.';
    const maxHeight = Number(props.maxHeight || 480);
    const exportSlug = props.exportSlug || 'clientes';
    const semCompraLabel = !!props.semCompraLabel;

    const fmt = (typeof window.fmt === 'function') ? window.fmt : function(v){ return 'R$ '+Number(v||0).toFixed(2); };
    const nid = (typeof window.nid === 'function') ? window.nid : function(a,b){ return String(a) === String(b); };
    const dateKey = (typeof window.dateKey === 'function') ? window.dateKey
      : function(d){ const x=d||new Date(); return x.getFullYear()+'-'+String(x.getMonth()+1).padStart(2,'0')+'-'+String(x.getDate()).padStart(2,'0'); };

    // Gate do export — mesmo padrão da casa (Relatorio.jsx). Ausente do DOM, não `disabled`.
    const isAdmin = user.role === 'admin';

    const [q, setQ] = React.useState('');
    const [qDeb, setQDeb] = React.useState('');
    const [band, setBand] = React.useState('');       // '' = Todos
    const [minLtv, setMinLtv] = React.useState('');
    const [minTicket, setMinTicket] = React.useState('');
    const [sortKey, setSortKey] = React.useState(null); // null = ordem original do clientLTV
    const [sortDir, setSortDir] = React.useState('desc');

    // debounce 200ms — a lista pode passar de 500 linhas
    React.useEffect(function(){
      const t = setTimeout(function(){ setQDeb(q); }, 200);
      return function(){ clearTimeout(t); };
    }, [q]);

    const hasFilter = !!(q || band || minLtv || minTicket || sortKey);

    function clearAll(){
      setQ(''); setQDeb(''); setBand(''); setMinLtv(''); setMinTicket('');
      setSortKey(null); setSortDir('desc');
    }

    function toggleSort(key){
      if (sortKey === key) { setSortDir(function(d){ return d === 'asc' ? 'desc' : 'asc'; }); }
      else { setSortKey(key); setSortDir(key === 'name' ? 'asc' : 'desc'); }
    }

    // UMA passada de filtro + (opcional) ordenação. Nada de filter() dentro do map do render.
    const view = React.useMemo(function(){
      const nq = norm(qDeb);
      const b = bands.filter(function(x){ return x.key === band; })[0] || null;
      const lv = Number(minLtv) || 0;
      const tk = Number(minTicket) || 0;
      const out = [];
      for (let i = 0; i < rows.length; i++){
        const c = rows[i];
        if (nq && norm(c.name).indexOf(nq) === -1) continue;
        if (b){
          const d = Number(c.daysSince || 0);
          if (d < b.min || d > b.max) continue;
        }
        if (lv > 0 && Number(c.total || 0) < lv) continue;
        if (tk > 0 && Number(c.ticket || 0) < tk) continue;
        out.push(c);
      }
      if (sortKey){
        const dir = sortDir === 'asc' ? 1 : -1;
        out.sort(function(a, b2){
          if (sortKey === 'name') return norm(a.name).localeCompare(norm(b2.name)) * dir;
          return (Number(a[sortKey] || 0) - Number(b2[sortKey] || 0)) * dir;
        });
      }
      return out;
    }, [rows, qDeb, band, minLtv, minTicket, sortKey, sortDir, bands]);

    // ── Export CSV-BR (padrão provado em js/lib/relatorio/exportCsv.js) ──
    function doExport(){
      const hoje = new Date();
      const linhas = [
        ['Cliente','Telefone','Dias inativo','LTV (R$)','Ticket médio (R$)','Última compra'].join(';')
      ];
      view.forEach(function(c){
        const cli = visibleClients.filter(function(x){ return nid(x.id, c.id); })[0];
        const tel = String((cli && (cli.phone || cli.whatsapp)) || '');
        const d = Number(c.daysSince || 0);
        // `clientLTV` não carrega lastDate → data DERIVADA de daysSince (hoje - daysSince)
        let ultima = '';
        if (!isSemCompra(d)){
          const dt = new Date(hoje.getTime() - d * 86400000);
          ultima = String(dt.getDate()).padStart(2,'0') + '/' +
                   String(dt.getMonth()+1).padStart(2,'0') + '/' + dt.getFullYear();
        }
        linhas.push([
          String(c.name || '').replace(/;/g,','),
          tel.replace(/;/g,','),
          isSemCompra(d) ? 'Sem compra' : String(d),
          Number(c.total || 0).toFixed(2).replace('.',','),
          Number(c.ticket || 0).toFixed(2).replace('.',','),
          ultima
        ].join(';'));
      });
      const csv = linhas.join('\r\n');
      const bom = '﻿'; // UTF-8 BOM pro Excel BR abrir certo
      const blob = new Blob([bom + csv], { type:'text/csv;charset=utf-8' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      // dia LOCAL — toISOString().slice(0,10) devolve AMANHÃ depois das 21h BRT (v224.233)
      a.download = 'zaynex_' + exportSlug + '_' + (band || 'todos') + '_' + dateKey(hoje) + '.csv';
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
      // Rastro: não existe tabela de auditoria de export no projeto → breadcrumb Sentry
      window.Sentry?.addBreadcrumb?.({
        category:'export',
        message:'churn_export',
        data:{ rows:view.length, painel:exportSlug, faixa:band || 'todos', role:user.role, user:user.name }
      });
    }

    const chip = function(active){
      return {
        padding:'3px 9px', fontSize:11, fontWeight:600, borderRadius:12, cursor:'pointer',
        border:'1px solid ' + (active ? accent : '#E5E7EB'),
        background: active ? accent : '#fff',
        color: active ? '#fff' : '#6B7280'
      };
    };

    const sortArrow = function(key){
      if (sortKey !== key) return '';
      return sortDir === 'asc' ? ' ▲' : ' ▼';
    };
    const th = { cursor:'pointer', userSelect:'none', whiteSpace:'nowrap' };

    return (
      <div className="card">
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',gap:8,marginBottom:12}}>
          <div style={{fontSize:13,fontWeight:700,color:accent,textTransform:'uppercase',letterSpacing:1}}>{title}</div>
          {isAdmin && view.length > 0 && (
            <button className="btn-outline" onClick={doExport} title="Exportar o que está na tela (busca + filtros aplicados)"
              style={{fontSize:11,padding:'4px 10px',whiteSpace:'nowrap'}}>⬇️ Exportar</button>
          )}
        </div>

        {rows.length === 0
          ? <div style={{color:'#16A34A',fontSize:13,padding:14,textAlign:'center'}}>{emptyMsg}</div>
          : <>
              {/* ── Barra busca + filtros ── */}
              <div style={{display:'flex',flexWrap:'wrap',alignItems:'center',gap:8,marginBottom:8}}>
                <div style={{position:'relative',display:'inline-flex',alignItems:'center'}}>
                  <input value={q} onChange={function(e){ setQ(e.target.value); }}
                    placeholder="🔍 Buscar cliente..."
                    style={{width:180,fontSize:12,paddingRight:q?22:8}}/>
                  {q && (
                    <button onClick={function(){ setQ(''); }} title="Limpar busca"
                      style={{position:'absolute',right:4,border:'none',background:'transparent',cursor:'pointer',color:'#9CA3AF',fontSize:12,lineHeight:1,padding:2}}>✕</button>
                  )}
                </div>

                <div style={{display:'flex',gap:4,flexWrap:'wrap'}}>
                  <span onClick={function(){ setBand(''); }} style={chip(band === '')}>Todos</span>
                  {bands.map(function(b){
                    return <span key={b.key} onClick={function(){ setBand(b.key); }} style={chip(band === b.key)}>{b.label}</span>;
                  })}
                </div>

                <div style={{display:'flex',alignItems:'center',gap:4}}>
                  <span style={{fontSize:11,color:'#6B7280'}}>LTV ≥</span>
                  <input type="number" min="0" value={minLtv} onChange={function(e){ setMinLtv(e.target.value); }}
                    placeholder="0" style={{width:74,fontSize:12}}/>
                  {LTV_PRESETS.map(function(p){
                    return <span key={p.label} onClick={function(){ setMinLtv(p.key); }} style={chip(minLtv === p.key)}>{p.label}</span>;
                  })}
                </div>

                <div style={{display:'flex',alignItems:'center',gap:4}}>
                  <span style={{fontSize:11,color:'#6B7280'}}>Ticket ≥</span>
                  <input type="number" min="0" value={minTicket} onChange={function(e){ setMinTicket(e.target.value); }}
                    placeholder="0" style={{width:74,fontSize:12}}/>
                </div>
              </div>

              <div style={{display:'flex',alignItems:'center',gap:8,marginBottom:8}}>
                <span style={{fontSize:11,color:'#6B7280'}}>Mostrando <strong style={{color:'#374151'}}>{view.length}</strong> de {rows.length} clientes</span>
                {hasFilter && (
                  <button onClick={clearAll} className="btn-outline" style={{fontSize:11,padding:'2px 8px'}}>Limpar filtros</button>
                )}
              </div>

              {view.length === 0
                ? <div style={{color:'#6B7280',fontSize:13,padding:14,textAlign:'center'}}>
                    {qDeb
                      ? <>Nenhum cliente encontrado para "{qDeb}".{' '}
                          <button onClick={function(){ setQ(''); }} className="btn-outline" style={{fontSize:11,padding:'2px 8px',marginLeft:6}}>limpar busca</button>
                        </>
                      : <>Nenhum cliente nos filtros atuais.{' '}
                          <button onClick={clearAll} className="btn-outline" style={{fontSize:11,padding:'2px 8px',marginLeft:6}}>limpar filtros</button>
                        </>}
                  </div>
                : <div style={{maxHeight:maxHeight,overflowY:'auto'}}>
                    <table style={{fontSize:12}}>
                      <thead>
                        <tr>
                          <th style={th} onClick={function(){ toggleSort('name'); }}>{headers[0]}{sortArrow('name')}</th>
                          <th style={th} onClick={function(){ toggleSort('daysSince'); }}>{headers[1]}{sortArrow('daysSince')}</th>
                          <th style={th} onClick={function(){ toggleSort('total'); }}>{headers[2]}{sortArrow('total')}</th>
                          <th style={th} onClick={function(){ toggleSort('ticket'); }}>{headers[3]}{sortArrow('ticket')}</th>
                        </tr>
                      </thead>
                      <tbody>
                        {view.map(function(c){
                          const cli = visibleClients.filter(function(x){ return nid(x.id, c.id); })[0];
                          return (
                            <tr key={c.id} style={{cursor:cli?'pointer':'default'}} onClick={function(){ if(cli) onOpen360(cli); }}>
                              <td style={{fontWeight:600}}>{c.name}</td>
                              <td style={{color:accent,fontWeight:700}}>{semCompraLabel && isSemCompra(c.daysSince) ? 'Sem compra' : c.daysSince+'d'}</td>
                              <td className="gold">{fmt(c.total)}</td>
                              <td className="dim">{fmt(c.ticket)}</td>
                            </tr>
                          );
                        })}
                      </tbody>
                    </table>
                  </div>
              }
            </>
        }
      </div>
    );
  }

  window.ZNX = window.ZNX || {};
  window.ZNX.widgets = window.ZNX.widgets || {};
  window.ZNX.widgets.clientes = window.ZNX.widgets.clientes || {};
  window.ZNX.widgets.clientes.ClientRiskTable = ClientRiskTable;
})();
