// js/components/widgets/RegioesAnalytics.jsx
// [Wave 20 v224.2 NUCLEAR EXTRACT 2026-05-23] 991L → ~430L
// 5 widgets extraídos:
//   - js/lib/regioes/calcs.js (17 factories + 9 helpers + 4 constantes — PURO JS)
//   - widgets/regioes/BrazilMapPanel.jsx (SVG tile map + drill-down)
//   - widgets/regioes/RankingsPanel.jsx (ranking estados + cidades + crescimento + sazonalidade)
//   - widgets/regioes/OportunidadesPanel.jsx (concentração + gaps + reativar + premium + vendedoras)
//   - widgets/regioes/MetricasUFPanel.jsx (mix + logística + clientes + tempo + devoluções + disclaimer)
//
// Este arquivo agora é ORQUESTRADOR: hooks (useMemo wrappers) + render dos 4 panels.
// ZERO mudança lógica nos useMemo bodies — todos delegam pra calcs.computeXxx.
//
// [REWRITE v26.5.108 — 2026-05-08] histórico features intactas
// PRIVACY: vendedora vê só clientes/vendas dela; admin vê tudo (regra #28)
// Deps: fmt (global), window.ZNX.regioes.calcs + window.ZNX.widgets.regioes.* + SectionHeader + KpiCard
(function() {
  'use strict';
  const {useState, useMemo} = React;

  // Paleta cores local (pra header + busca + SmartSelect fallback)
  const C = {
    navy:'#1B2A4A', gold:'#B89840',
    blue:'#2563EB',
    gray:'#6B7280', grayBorder:'#E4E7EC',
    text:'#1C1C28'
  };

  // [Wave 20 v224.2 + v224.55 2026-05-28] vars+check MOVED to component body (preventivo)
  // regra_validacao_helpers_runtime_quando_ordem_scripts_uncertain

  function RegioesAnalytics({sales, clients, user, products, allUsers, quotes}){
    // [v224.55 FIX-PREV-15 2026-05-28] vars+check em render time
    // regra_estender_bloco_refs_fail_loud — 1 bloco agregado
    const calcs = window.ZNX && window.ZNX.regioes && window.ZNX.regioes.calcs;
    const widgets = window.ZNX && window.ZNX.widgets;
    const regiosW = widgets && widgets.regioes;
    const SectionHeader = widgets && widgets.SectionHeader;
    const KpiCard = widgets && widgets.KpiCard;
    const _missing = [];
    if (!calcs) _missing.push('regioes.calcs');
    if (!regiosW || !regiosW.BrazilMapPanel) _missing.push('BrazilMapPanel');
    if (!regiosW || !regiosW.RankingsPanel) _missing.push('RankingsPanel');
    if (!regiosW || !regiosW.OportunidadesPanel) _missing.push('OportunidadesPanel');
    if (!regiosW || !regiosW.MetricasUFPanel) _missing.push('MetricasUFPanel');
    if (!SectionHeader) _missing.push('SectionHeader');
    if (!KpiCard) _missing.push('KpiCard');
    if (_missing.length) {
      const _msg = '[RegioesAnalytics] widgets faltando: ' + _missing.join(', ');
      console.error(_msg);
      if (window.Sentry && typeof window.Sentry.captureMessage === 'function') {
        window.Sentry.captureMessage(_msg, 'error');
      }
    }
    const now = new Date();
    const [mes, setMes] = useState(now.getFullYear()+'-'+String(now.getMonth()+1).padStart(2,'0'));
    const [selectedUf, setSelectedUf] = useState(null);
    const [busca, setBusca] = useState('');
    // [v224.108] custom range pra mes==='custom'
    const [customFrom, setCustomFrom] = useState('');
    const [customTo, setCustomTo] = useState('');

    const isAdmin = user && (user.role==='admin' || user.role==='financeiro');
    const myName = user && user.name;

    // ── PRIVACY (regra #28) — vendedora vê só clientes/vendas dela ──
    const myClientsSet = useMemo(function(){
      if(isAdmin) return null;
      const set = new Set();
      (sales||[]).forEach(function(s){
        if(s.sellerName===myName && s.clientId) set.add(String(s.clientId));
      });
      return set;
    },[sales,isAdmin,myName]);

    const visibleSales = useMemo(function(){
      if(isAdmin) return sales||[];
      return (sales||[]).filter(function(s){return s.sellerName===myName;});
    },[sales,isAdmin,myName]);

    const visibleClients = useMemo(function(){
      if(isAdmin) return clients||[];
      return (clients||[]).filter(function(c){return myClientsSet&&myClientsSet.has(String(c.id));});
    },[clients,isAdmin,myClientsSet]);

    // ── DATASETS BÁSICOS ─────────────────────────────────────────────
    // [v224.108] periodRange: mes = 'YYYY-MM' (específico) | 'all' | token relativo (today/week/30d/90d/year/custom)
    const periodRange = useMemo(function(){
      var today = now.toISOString().slice(0,10);
      if(mes==='all') return {from:null,to:null};
      if(mes==='today') return {from:today,to:today};
      if(mes==='week'){ var dw=now.getDay()||7; var mon=new Date(now); mon.setDate(now.getDate()-(dw-1)); return {from:mon.toISOString().slice(0,10),to:today}; }
      if(mes==='30d'){ var d30=new Date(now); d30.setDate(d30.getDate()-30); return {from:d30.toISOString().slice(0,10),to:today}; }
      if(mes==='90d'){ var d90=new Date(now); d90.setDate(d90.getDate()-90); return {from:d90.toISOString().slice(0,10),to:today}; }
      if(mes==='year') return {from:now.getFullYear()+'-01-01',to:today};
      if(mes==='custom') return {from:customFrom||null,to:customTo||null};
      if(/^\d{4}-\d{2}$/.test(mes)){ var pp=mes.split('-').map(Number); var last=new Date(pp[0],pp[1],0).toISOString().slice(0,10); return {from:mes+'-01',to:last}; }
      return {from:null,to:null};
    },[mes,customFrom,customTo]);
    // [v224.108] comparação "vs mês anterior" só em mês específico ('YYYY-MM')
    const enableComparison = useMemo(function(){ return /^\d{4}-\d{2}$/.test(mes); },[mes]);
    const salesDoMes = useMemo(function(){
      // [v224.108] filtra por periodRange (8 períodos) · null/null = todo o tempo
      var f=periodRange.from, t=periodRange.to;
      if(!f && !t) return visibleSales.filter(function(s){return calcs.isFaturadaSafe(s);});
      return visibleSales.filter(function(s){
        if(!calcs.isFaturadaSafe(s) || !s.date) return false;
        var d=s.date.slice(0,10);
        if(f && d<f) return false;
        if(t && d>t) return false;
        return true;
      });
    },[visibleSales,periodRange]);

    const salesMesAnterior = useMemo(function(){
      // [v224.108] comparação "vs mês anterior" SÓ em mês específico (enableComparison) · senão []
      if(!enableComparison) return [];
      const prev = calcs.previousMonth(mes);
      return visibleSales.filter(function(s){return s.date&&s.date.slice(0,7)===prev&&calcs.isFaturadaSafe(s);});
    },[visibleSales,mes,enableComparison]);

    // ── HOOKS WRAPPERS (todos delegam pra calcs.computeXxx — ZERO lógica nova) ──
    const statsByUf = useMemo(function(){return calcs.computeStatsByUf(salesDoMes,clients);},[salesDoMes,clients]);
    const statsByUfPrev = useMemo(function(){return calcs.computeStatsByUfPrev(salesMesAnterior,clients);},[salesMesAnterior,clients]);
    const ufRanking = useMemo(function(){return calcs.computeUFRanking(statsByUf);},[statsByUf]);

    // KPIs (inline — simples reduce sobre stats)
    const totalReceita = ufRanking.reduce(function(s,u){return s+u.receita;},0);
    const totalReceitaPrev = Object.values(statsByUfPrev).reduce(function(s,u){return s+u.receita;},0);
    const totalVendas = salesDoMes.length;
    const estadosAtendidos = ufRanking.length;
    const cidadesAtendidas = useMemo(function(){return calcs.computeCidadesAtendidas(salesDoMes,clients);},[salesDoMes,clients]);
    const totalClientes = visibleClients.length;

    const concentracao = useMemo(function(){return calcs.computeConcentracao(ufRanking,totalReceita);},[ufRanking,totalReceita]);
    const ufsSemCobertura = useMemo(function(){return calcs.computeUFsSemCobertura(visibleClients);},[visibleClients]);
    const cidadesGrandesSemCliente = useMemo(function(){return calcs.computeCidadesGrandesSemCliente(visibleClients);},[visibleClients]);
    const estadosCrescimento = useMemo(function(){return calcs.computeEstadosCrescimento(statsByUf,statsByUfPrev);},[statsByUf,statsByUfPrev]);
    const mixMarcasPorUf = useMemo(function(){return calcs.computeMixMarcasPorUf(salesDoMes,products,ufRanking,clients);},[salesDoMes,products,ufRanking,clients]);
    const margemPorUf = useMemo(function(){return calcs.computeMargemPorUf(salesDoMes,products,ufRanking,clients);},[salesDoMes,products,ufRanking,clients]);
    const logisticaPorUf = useMemo(function(){return calcs.computeLogisticaPorUf(salesDoMes,ufRanking,clients);},[salesDoMes,ufRanking,clients]);
    const clientesPorUf = useMemo(function(){return calcs.computeClientesPorUf(visibleSales,visibleClients,ufRanking);},[visibleSales,visibleClients,ufRanking]);
    const cidadesParaReativar = useMemo(function(){return calcs.computeCidadesParaReativar(visibleSales,visibleClients);},[visibleSales,visibleClients]);
    const cidadesPremium = useMemo(function(){return calcs.computeCidadesPremium(salesDoMes,clients,totalReceita,totalVendas);},[salesDoMes,clients,totalReceita,totalVendas]);
    const vendedorasPorUf = useMemo(function(){return calcs.computeVendedorasPorUf(salesDoMes,ufRanking,isAdmin,allUsers,clients);},[salesDoMes,ufRanking,isAdmin,allUsers,clients]);
    const tempoRetiradaPorUf = useMemo(function(){return calcs.computeTempoRetiradaPorUf(salesDoMes,ufRanking,clients);},[salesDoMes,ufRanking,clients]);
    const sazonalidadeTop5 = useMemo(function(){return calcs.computeSazonalidadeTop5(visibleSales,ufRanking,now.getFullYear(),now.getMonth(),clients);},[visibleSales,ufRanking,now.getFullYear(),now.getMonth(),clients]);
    const topCidades = useMemo(function(){return calcs.computeTopCidades(salesDoMes,clients);},[salesDoMes,clients]);

    // Meses disponíveis pra filtro
    const mesesDisp = useMemo(function(){
      const set = new Set(visibleSales.map(function(s){return s.date && s.date.slice(0,7);}).filter(Boolean));
      const curr = now.getFullYear()+'-'+String(now.getMonth()+1).padStart(2,'0');
      set.add(curr);
      // [v224.108] meses específicos do histórico (períodos relativos vão em PERIOD_OPTIONS)
      return Array.from(set).sort().reverse();
    },[visibleSales]);

    // [v224.108] períodos relativos (flat · SmartSelect não tem optgroup)
    const PERIOD_OPTIONS = [
      {value:'all',label:'⭐ Todo o tempo'},
      {value:'today',label:'Hoje'},
      {value:'week',label:'Esta semana'},
      {value:'30d',label:'Últimos 30 dias'},
      {value:'90d',label:'Últimos 90 dias'},
      {value:'year',label:'Ano atual'},
      {value:'custom',label:'📅 Personalizado'}
    ];
    var _periodLabelMap = {all:'⭐ Todo o tempo',today:'Hoje',week:'Esta semana','30d':'Últimos 30 dias','90d':'Últimos 90 dias',year:'Ano atual',custom:'📅 Personalizado'};
    const mesLabel = function(m){ return _periodLabelMap[m] || calcs.fmtMes(m); };
    // frase pro indicador/subtitle
    const periodFrase = (mes==='custom')
      ? ((customFrom&&customTo) ? (customFrom+' a '+customTo) : 'período personalizado')
      : ({all:'todo o tempo',today:'hoje',week:'esta semana','30d':'últimos 30 dias','90d':'últimos 90 dias',year:'ano atual'}[mes] || calcs.fmtMes(mes));

    // Drill-down do UF selecionado
    const ufDrilldown = selectedUf ? {
      stats: statsByUf[selectedUf],
      mix: mixMarcasPorUf[selectedUf],
      margem: margemPorUf[selectedUf],
      logistica: logisticaPorUf[selectedUf],
      clientes: clientesPorUf[selectedUf],
      tempo: tempoRetiradaPorUf[selectedUf],
      vendedoras: vendedorasPorUf ? vendedorasPorUf[selectedUf] : null
    } : null;

    // ══════════════════════════════════════════════════════════════════
    // RENDER (orquestração dos 4 panels + header + KPIs)
    // ══════════════════════════════════════════════════════════════════
    return(
      <div>
        {/* HEADER (L568-585) */}
        <div className="page-header" style={{flexWrap:'wrap',gap:12}}>
          <div>
            <div className="page-title">📍 Análise Regional</div>
            <div style={{fontSize:12,color:C.gray,marginTop:2}}>
              Geografia de vendas · {mesLabel(mes)}
              {!isAdmin&&<span style={{marginLeft:8,fontStyle:'italic'}}>· seus clientes apenas</span>}
            </div>
          </div>
          <div style={{display:'flex',gap:10,alignItems:'center',flexWrap:'wrap'}}>
            <input value={busca} onChange={function(e){setBusca(e.target.value);}} placeholder="🔍 Buscar cidade ou estado..." style={{width:240,paddingLeft:12,paddingRight:12,fontSize:13,background:'#fff',border:'1px solid '+C.blue+'66',borderRadius:8,color:C.text,height:38}}/>
            {typeof SmartSelect!=='undefined'?
              <SmartSelect width={170} value={mes} onChange={setMes} options={PERIOD_OPTIONS.concat(mesesDisp.map(function(m){return {value:m,label:calcs.fmtMes(m)};}))}/>:
              <select value={mes} onChange={function(e){setMes(e.target.value);}} style={{padding:'8px 12px',border:'1px solid '+C.grayBorder,borderRadius:8,fontSize:13}}>
                {PERIOD_OPTIONS.map(function(o){return <option key={o.value} value={o.value}>{o.label}</option>;})}
                {mesesDisp.map(function(m){return <option key={m} value={m}>{calcs.fmtMes(m)}</option>;})}
              </select>
            }
            {mes==='custom' && (
              <span style={{display:'flex',gap:6,alignItems:'center'}}>
                <input type="date" value={customFrom} onChange={function(e){setCustomFrom(e.target.value);}} style={{padding:'6px 8px',border:'1px solid '+C.grayBorder,borderRadius:6,fontSize:12}}/>
                <span style={{fontSize:12,color:C.gray}}>até</span>
                <input type="date" value={customTo} onChange={function(e){setCustomTo(e.target.value);}} style={{padding:'6px 8px',border:'1px solid '+C.grayBorder,borderRadius:6,fontSize:12}}/>
              </span>
            )}
          </div>
        </div>

        {/* [v224.108] banner quando período não-mensal · comparações vs mês anterior ocultas */}
        {!enableComparison && (
          <div style={{padding:'8px 12px',background:'#FEF3C7',borderRadius:6,fontSize:12,color:'#92400E',marginBottom:12}}>
            ℹ️ Período: <strong>{periodFrase}</strong> · comparações "vs mês anterior" e sazonalidade aparecem só em mês específico.
          </div>
        )}
        {/* KPIs (L588-593) */}
        <div style={{display:'grid',gridTemplateColumns:'repeat(4,1fr)',gap:14,marginBottom:18}}>
          <KpiCard label="Estados Atendidos" value={estadosAtendidos} subtitle={(calcs.UFS_BR.length-estadosAtendidos)+' estados sem cobertura'}/>
          <KpiCard label="Cidades Atendidas" value={cidadesAtendidas} subtitle={"com vendas · "+periodFrase}/>
          <KpiCard label="Clientes Cadastrados" value={totalClientes} subtitle={isAdmin?'total empresa':'seus clientes'}/>
          <KpiCard label="Receita Total" value={totalReceita} prev={totalReceitaPrev} isCurrency compactCurrency/>
        </div>

        {/* OportunidadesPanel — concentração (B2) + gaps (B1+H3) + reativar (B3) + premium (H1) + vendedoras (F1+F2) */}
        {regiosW && regiosW.OportunidadesPanel && (
          <regiosW.OportunidadesPanel
            concentracao={concentracao}
            ufsSemCobertura={ufsSemCobertura}
            cidadesGrandesSemCliente={cidadesGrandesSemCliente}
            cidadesParaReativar={cidadesParaReativar}
            cidadesPremium={cidadesPremium}
            vendedorasPorUf={vendedorasPorUf}
            isAdmin={isAdmin}
          />
        )}

        {/* BrazilMapPanel — A1 mapa tile-grid + drill-down */}
        <SectionHeader icon="🗺️" title="Mapa de Calor — Estados" subtitle="Clique num estado pra ver detalhes · cor = intensidade da receita"/>
        {regiosW && regiosW.BrazilMapPanel && (
          <regiosW.BrazilMapPanel
            statsByUf={statsByUf}
            selectedUf={selectedUf}
            setSelectedUf={setSelectedUf}
            ufDrilldown={ufDrilldown}
            mes={mes}
            isAdmin={isAdmin}
          />
        )}

        {/* RankingsPanel — ranking estados + cidades + crescimento/queda + sazonalidade */}
        {regiosW && regiosW.RankingsPanel && (
          <regiosW.RankingsPanel
            ufRanking={ufRanking}
            statsByUfPrev={statsByUfPrev}
            margemPorUf={margemPorUf}
            topCidades={topCidades}
            cidadesAtendidas={cidadesAtendidas}
            estadosCrescimento={estadosCrescimento}
            sazonalidadeTop5={sazonalidadeTop5}
            mes={mes}
          />
        )}

        {/* MetricasUFPanel — mix marcas (C2) + logística (D2+D4) + clientes (E1-4) + tempo (C4) + devoluções placeholder (D3) + disclaimer */}
        {regiosW && regiosW.MetricasUFPanel && (
          <regiosW.MetricasUFPanel
            mixMarcasPorUf={mixMarcasPorUf}
            logisticaPorUf={logisticaPorUf}
            clientesPorUf={clientesPorUf}
            tempoRetiradaPorUf={tempoRetiradaPorUf}
            isAdmin={isAdmin}
          />
        )}
      </div>
    );
  }

  // ── EXPORT ─────────────────────────────────────────────────────────
  window.ZNX = window.ZNX || {};
  window.ZNX.components = window.ZNX.components || {};
  window.ZNX.components.RegioesAnalytics = RegioesAnalytics;
  window.RegioesAnalytics = RegioesAnalytics;
  window.ZNX.refactor_phase_5_loaded = window.ZNX.refactor_phase_5_loaded || {};
  window.ZNX.refactor_phase_5_loaded.RegioesAnalytics = true;
  // [Wave 20 marker v224.2] confirma extract executado
  window.RegioesAnalytics_v224_2_wave20 = true;
})();
