// ═══════════════════════════════════════════════════════
// BAUKO CRM — Mapa Territorial (carteira por município)
// ═══════════════════════════════════════════════════════
//
// Pinta cada município pela cor do vendedor oficial atribuído na
// Lista SP "Regioes". Cobre as UFs onde temos dados (ES/RJ/BA/SP).
// Municípios fora dessas UFs ou sem mapeamento ficam cinza.
//
// Fonte GeoJSON: https://github.com/tbrugz/geodata-br (MIT, por UF)
//   - geojs-32-mun.json (ES, código IBGE 32)
//   - geojs-33-mun.json (RJ, código IBGE 33)
//   - geojs-29-mun.json (BA, código IBGE 29)
//   - geojs-35-mun.json (SP, código IBGE 35)
//
// Fonte da pintura: CRM_DATA.getRegiaoPorCidadeUF(cidade, uf)
//   alimentado por CRM_API.loadRegioes (Lista SP "Regioes").
//
// Cache: localStorage por UF. ~100-500KB cada. Carregamento lazy
// (só quando a tab "Território" é selecionada na 1ª vez).
//
/* global React, CRM_DATA, BAUKO_AUTH */

const { useState: useTerrState, useEffect: useTerrEffect, useMemo: useTerrMemo } = React;

// ── UFs cobertas e URLs dos GeoJSONs ──────────────────
const UFS_COBERTAS = ['ES', 'RJ', 'BA', 'SP'];
const UF_CODIGO_IBGE = { ES: 32, RJ: 33, BA: 29, SP: 35 };
const URL_GEOJSON_UF = function(uf) {
  var cod = UF_CODIGO_IBGE[uf];
  if (!cod) return null;
  return 'https://raw.githubusercontent.com/tbrugz/geodata-br/master/geojson/geojs-' + cod + '-mun.json';
};
const CACHE_KEY_GEO_MUN = 'bauko_geo_mun_';   // prefixo por UF, ex.: bauko_geo_mun_ES

// ── Helpers ───────────────────────────────────────────
function _escHtml(s) {
  return String(s || '').replace(/[&<>"']/g, function(c) {
    return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
  });
}
function normMun(s) {
  return String(s || '')
    .normalize('NFD')
    .replace(/[̀-ͯ]/g, '')
    .toLowerCase()
    .trim();
}

// Resolve info de vendedor — agora usa BAUKO_AUTH.VENDEDORES (fonte única do Hub).
// Backward-compatible: aceita 2º arg legado mas ignora.
function resolveVendedorInfo(email /*, _ignoredLegacy */) {
  if (!email) return null;
  if (window.BAUKO_AUTH && window.BAUKO_AUTH.VENDEDORES) {
    return window.BAUKO_AUTH.VENDEDORES.getById(email);
  }
  // Fallback degradado (BAUKO_AUTH não carregado)
  return { id: email, email: email, nome: email, cor: '#9ca3af', inativo: true };
}

// ════════════════════════════════════════════════════════════
// COMPONENTE — MapaTerritorial
// ════════════════════════════════════════════════════════════
function MapaTerritorial({ clientes }) {
  const containerRef     = React.useRef(null);
  const mapRef           = React.useRef(null);
  const polygonsLayerRef = React.useRef(null);

  const [status, setStatus] = useTerrState('loading'); // 'loading' | 'ready' | 'error'
  const [statusMsg, setStatusMsg] = useTerrState('');
  const [geoUFs, setGeoUFs] = useTerrState({});  // { ES: geojson, RJ: geojson, BA: geojson }
  const [progresso, setProgresso] = useTerrState(0); // 0..UFS_COBERTAS.length
  const [vendedorFiltro, setVendedorFiltro] = useTerrState(''); // '' = todos · senão email do vendedor

  // Marker pra force re-render quando BAUKO_AUTH for repopulado. A info real
  // vem de BAUKO_AUTH.VENDEDORES via resolveVendedorInfo() (centralizado).
  const vendedoresInfo = useTerrMemo(function() {
    if (window.BAUKO_AUTH && window.BAUKO_AUTH.VENDEDORES) {
      window.BAUKO_AUTH.VENDEDORES.refresh();
    }
    return { _v: Date.now() };  // sentinela só pra dep ser estável por render
  }, []);

  // Pré-calcula clientes por município (cidade|UF normalizado) pra tooltip
  const clientesPorMun = useTerrMemo(function() {
    var m = {};
    (clientes || []).forEach(function(c) {
      var uf = (c.uf || '').toUpperCase().slice(0, 2);
      var cidade = (c.cidade || '').trim();
      if (!uf || !cidade) return;
      var k = normMun(cidade) + '|' + uf;
      if (!m[k]) m[k] = [];
      m[k].push(c);
    });
    return m;
  }, [clientes]);

  // ── Carrega GeoJSON de cada UF (paralelo, com cache) ──
  useTerrEffect(function() {
    var cancel = false;
    if (typeof window.L === 'undefined') {
      setStatus('error');
      setStatusMsg('Leaflet não carregou. Recarregue a página.');
      return;
    }
    setStatus('loading');
    setProgresso(0);

    function carregarUF(uf) {
      // Tenta cache primeiro
      try {
        var raw = localStorage.getItem(CACHE_KEY_GEO_MUN + uf);
        if (raw) {
          var parsed = JSON.parse(raw);
          if (parsed && parsed.features) return Promise.resolve(parsed);
        }
      } catch (e) { /* cache corrompido — ignora */ }

      // Fetch externo
      var url = URL_GEOJSON_UF(uf);
      if (!url) return Promise.reject(new Error('UF não suportada: ' + uf));
      return fetch(url).then(function(r) {
        if (!r.ok) throw new Error('HTTP ' + r.status + ' ao buscar ' + uf);
        return r.json();
      }).then(function(data) {
        try { localStorage.setItem(CACHE_KEY_GEO_MUN + uf, JSON.stringify(data)); } catch (e) {}
        return data;
      });
    }

    var acumulado = {};
    var promises = UFS_COBERTAS.map(function(uf) {
      return carregarUF(uf).then(function(data) {
        if (cancel) return;
        acumulado[uf] = data;
        setProgresso(function(p) { return p + 1; });
      });
    });

    Promise.all(promises).then(function() {
      if (cancel) return;
      setGeoUFs(acumulado);
      setStatus('ready');
    }).catch(function(e) {
      if (cancel) return;
      console.error('[MapaTerritorial] erro:', e);
      setStatus('error');
      setStatusMsg('Erro ao carregar GeoJSON: ' + (e.message || e));
    });

    return function() { cancel = true; };
  }, []);

  // ── Inicializa o mapa Leaflet ──────────────────────────
  useTerrEffect(function() {
    if (status !== 'ready' || mapRef.current || !containerRef.current) return;
    var L = window.L;
    var map = L.map(containerRef.current, {
      center: [-19, -43],   // centroide aproximado do bloco ES/RJ/BA/SP
      zoom: 5,
      minZoom: 4,
      zoomControl: true,
    });
    L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
      attribution: '© OpenStreetMap, © CARTO',
      subdomains: 'abcd',
      maxZoom: 19,
    }).addTo(map);
    mapRef.current = map;
    setTimeout(function() { try { map.invalidateSize(); } catch (e) {} }, 100);
  }, [status]);

  // ── Renderiza polígonos dos municípios ─────────────────
  useTerrEffect(function() {
    if (status !== 'ready' || !mapRef.current || !Object.keys(geoUFs).length) return;
    var L = window.L;
    var map = mapRef.current;

    // Limpa camada anterior
    if (polygonsLayerRef.current) {
      map.removeLayer(polygonsLayerRef.current);
      polygonsLayerRef.current = null;
    }

    // Combina todos os GeoJSONs num único FeatureCollection
    // Adiciona _uf em cada feature pra facilitar lookup depois
    var allFeatures = [];
    Object.keys(geoUFs).forEach(function(uf) {
      var gj = geoUFs[uf];
      if (!gj || !gj.features) return;
      gj.features.forEach(function(f) {
        // Clone leve só pra anexar _uf sem corromper o cache
        var clone = Object.assign({}, f, { properties: Object.assign({ _uf: uf }, f.properties) });
        allFeatures.push(clone);
      });
    });

    function styleFeature(feature) {
      var nome = (feature.properties && feature.properties.name) || '';
      var uf   = feature.properties._uf;
      var r = (window.CRM_DATA && CRM_DATA.getRegiaoPorCidadeUF)
        ? CRM_DATA.getRegiaoPorCidadeUF(nome, uf)
        : null;
      var info = (r && r.vendedor_atual) ? resolveVendedorInfo(r.vendedor_atual, vendedoresInfo) : null;
      // Aplica filtro: se vendedorFiltro setado, só pinta colorido o vendedor selecionado
      var corPintura = info ? info.cor : '#e5e7eb';
      var opacidade  = r ? 0.78 : 0.35;
      if (vendedorFiltro) {
        var ehVendedorSelecionado = info && info.email && info.email.toLowerCase() === vendedorFiltro.toLowerCase();
        if (!ehVendedorSelecionado) {
          corPintura = '#e5e7eb';
          opacidade  = 0.30;
        } else {
          opacidade = 0.85;  // realça o selecionado
        }
      }
      return {
        fillColor:   corPintura,
        fillOpacity: opacidade,
        weight:      0.5,
        color:       '#fff',
      };
    }

    function buildTooltip(feature) {
      var nome = (feature.properties && feature.properties.name) || '';
      var uf   = feature.properties._uf;
      var r = (window.CRM_DATA && CRM_DATA.getRegiaoPorCidadeUF)
        ? CRM_DATA.getRegiaoPorCidadeUF(nome, uf)
        : null;
      var k = normMun(nome) + '|' + uf;
      var qtdClientes = (clientesPorMun[k] || []).length;
      var html = '<div style="font-weight:600;margin-bottom:4px">' + _escHtml(nome) + '/' + _escHtml(uf) + '</div>';
      if (r && r.vendedor_atual) {
        var info = resolveVendedorInfo(r.vendedor_atual, vendedoresInfo);
        var nomeVend = info ? info.nome : r.vendedor_atual;
        var cor      = info ? info.cor  : '#9ca3af';
        var sufixInativo = (info && info.inativo) ? ' <span style="font-size:10px;color:#999">(não está na whitelist)</span>' : '';
        html += '<div style="display:flex;align-items:center;gap:6px;line-height:1.4">'
              + '<span style="width:8px;height:8px;border-radius:50%;background:' + cor + ';display:inline-block;flex-shrink:0"></span>'
              + '<span>' + _escHtml(nomeVend) + sufixInativo + '</span></div>';
        html += '<div style="font-size:11px;color:#666;margin-top:3px">Região: ' + _escHtml(r.regiao_nome || '—') + '</div>';
      } else {
        html += '<div style="color:#999;font-style:italic">Sem vendedor atribuído</div>';
      }
      html += '<div style="font-size:11px;color:#666;margin-top:4px">'
            + (qtdClientes ? qtdClientes + ' cliente' + (qtdClientes > 1 ? 's' : '') + ' cadastrado' + (qtdClientes > 1 ? 's' : '') : 'Sem clientes cadastrados')
            + '</div>';
      return html;
    }

    var fc = { type: 'FeatureCollection', features: allFeatures };
    var layer = L.geoJSON(fc, {
      style: styleFeature,
      onEachFeature: function(feature, lyr) {
        lyr.bindTooltip(buildTooltip(feature), { sticky: true, direction: 'top' });
        lyr.on('mouseover', function(e) { e.target.setStyle({ fillOpacity: 0.95, weight: 1.2 }); });
        lyr.on('mouseout',  function(e) {
          var orig = styleFeature(feature);
          e.target.setStyle({ fillOpacity: orig.fillOpacity, weight: orig.weight });
        });
      },
    }).addTo(map);
    polygonsLayerRef.current = layer;
    try { map.fitBounds(layer.getBounds(), { padding: [10, 10] }); } catch (e) {}
  }, [status, geoUFs, clientesPorMun, vendedoresInfo, vendedorFiltro]);

  // ── Cleanup ao unmount ─────────────────────────────────
  useTerrEffect(function() {
    return function() {
      if (mapRef.current) {
        try { mapRef.current.remove(); } catch (e) {}
        mapRef.current = null;
      }
    };
  }, []);

  // Sempre re-renderizar lucide após render
  useTerrEffect(function() {
    try { window.lucide && window.lucide.createIcons({ attrs: { 'stroke-width': 1.75 } }); } catch (e) {}
  });

  // ── Legenda: vendedores no território (com fallback p/ históricos) ─────
  const legenda = useTerrMemo(function() {
    if (!window.CRM_DATA || !CRM_DATA.regioes) return [];
    var totais = {};
    CRM_DATA.regioes.forEach(function(r) {
      var v = (r.vendedor_atual || '').toLowerCase();
      if (v) totais[v] = (totais[v] || 0) + 1;
    });
    return Object.keys(totais)
      .map(function(email) {
        var info = resolveVendedorInfo(email, vendedoresInfo);
        return { email: email, qtd: totais[email], info: info, cor: info ? info.cor : '#9ca3af' };
      })
      .sort(function(a, b) { return b.qtd - a.qtd; });
  }, [vendedoresInfo]);

  var totalMunicipios = (CRM_DATA && CRM_DATA.regioes) ? CRM_DATA.regioes.length : 0;
  var pctProgresso = Math.round((progresso / UFS_COBERTAS.length) * 100);

  return (
    <div className="panel">
      <div className="panel__hd" style={{ flexWrap: 'wrap', gap: 10 }}>
        <h3 style={{ margin: 0 }}>Mapa Territorial — carteira oficial por município</h3>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginLeft: 'auto', flexWrap: 'wrap' }}>
          <select value={vendedorFiltro}
            onChange={function(e){ setVendedorFiltro(e.target.value); }}
            style={{
              padding: '5px 10px', font: '500 12px/1 var(--ff-body)',
              border: '1px solid var(--border)', borderRadius: 'var(--r-sm)',
              background: vendedorFiltro ? 'var(--grn-050, #ecfdf5)' : 'var(--surface)',
              color: 'var(--tx)', cursor: 'pointer', minWidth: 200, maxWidth: 280,
            }}
            title="Filtrar mapa por vendedor">
            <option value="">Todos os vendedores ({legenda.length})</option>
            {legenda.map(function(t) {
              return (
                <option key={t.email} value={t.email}>
                  {t.info ? t.info.nome : t.email.split('@')[0]} ({t.qtd} mun.)
                </option>
              );
            })}
          </select>
          {vendedorFiltro && (
            <button onClick={function(){ setVendedorFiltro(''); }}
              style={{
                padding: '5px 10px', font: '500 11px/1 var(--ff-body)',
                background: 'transparent', border: '1px solid var(--border)',
                borderRadius: 'var(--r-sm)', cursor: 'pointer', color: 'var(--tx-3)',
              }}
              title="Limpar filtro">
              ✕ limpar
            </button>
          )}
          <div className="meta">
            {totalMunicipios.toLocaleString('pt-BR')} municípios mapeados ({UFS_COBERTAS.join(', ')})
          </div>
        </div>
      </div>
      <div style={{ position: 'relative' }}>
        <div ref={containerRef} style={{ height: 560, width: '100%' }}></div>
        {status === 'loading' && (
          <div style={{
            position: 'absolute', inset: 0, background: 'rgba(255,255,255,.95)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            zIndex: 999, flexDirection: 'column', gap: 12,
          }}>
            <div style={{ font: '600 14px/1 var(--ff-body)', color: 'var(--tx-2)' }}>
              Carregando mapa territorial... ({progresso}/{UFS_COBERTAS.length} UFs)
            </div>
            <div style={{ width: 220, height: 4, background: 'var(--border)', borderRadius: 2, overflow: 'hidden' }}>
              <div style={{
                height: '100%',
                background: 'var(--grn)',
                borderRadius: 2,
                width: pctProgresso + '%',
                transition: 'width 200ms ease',
              }}></div>
            </div>
            <div style={{ font: '400 11px/1 var(--ff-mono)', color: 'var(--tx-3)' }}>
              {progresso === 0 ? 'Buscando GeoJSON do GitHub...' : 'Quase lá...'}
            </div>
          </div>
        )}
        {status === 'error' && (
          <div style={{
            position: 'absolute', inset: 0, background: 'rgba(255,255,255,.95)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            zIndex: 999, flexDirection: 'column', gap: 10, padding: 20,
          }}>
            <i data-lucide="alert-triangle" style={{ width: 24, height: 24, color: 'var(--danger)' }}></i>
            <div style={{ font: '600 13px/1.4 var(--ff-body)', color: 'var(--tx)', textAlign: 'center', maxWidth: 400 }}>
              {statusMsg || 'Erro ao carregar o mapa territorial'}
            </div>
            <div style={{ font: '400 11px/1.4 var(--ff-body)', color: 'var(--tx-3)', textAlign: 'center', maxWidth: 400 }}>
              Verifique a conexão. Os GeoJSONs vêm de raw.githubusercontent.com.
            </div>
          </div>
        )}
      </div>
      {/* Legenda */}
      <div style={{
        padding: '10px 18px', borderTop: '1px solid var(--border)',
        display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap',
        background: 'var(--surface-2)',
      }}>
        <span style={{ font: '600 10px/1 var(--ff-body)', textTransform: 'uppercase', letterSpacing: '.08em', color: 'var(--tx-3)' }}>
          Vendedores no território
        </span>
        {legenda.length === 0 ? (
          <span style={{ font: '400 12px/1 var(--ff-body)', color: 'var(--tx-3)' }}>—</span>
        ) : legenda.map(function(t) {
          var sel = vendedorFiltro && t.email.toLowerCase() === vendedorFiltro.toLowerCase();
          var apagado = !!(vendedorFiltro && !sel);
          return (
            <div key={t.email}
              onClick={function(){ setVendedorFiltro(sel ? '' : t.email); }}
              style={{
                display: 'flex', alignItems: 'center', gap: 5,
                font: '400 12px/1 var(--ff-body)', color: apagado ? 'var(--tx-3)' : 'var(--tx-2)',
                cursor: 'pointer', padding: '3px 6px', borderRadius: 'var(--r-xs)',
                background: sel ? 'var(--grn-050, #ecfdf5)' : 'transparent',
                border: sel ? '1px solid var(--grn)' : '1px solid transparent',
                opacity: apagado ? 0.4 : 1,
                transition: 'all 120ms',
              }}
              title={sel ? 'Click para limpar filtro' : 'Click para filtrar mapa por este vendedor'}>
              <span style={{ width: 12, height: 12, borderRadius: 3, background: t.cor, display: 'inline-block', border: '1px solid rgba(0,0,0,.1)' }}></span>
              <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 130 }}>
                {t.info ? t.info.nome : t.email.split('@')[0]}
                {t.info && t.info.inativo && <span style={{ fontSize: 10, color: 'var(--tx-3)' }}> ⚠</span>}
              </span>
              <span style={{ color: 'var(--tx-3)', fontFamily: 'var(--ff-mono)' }}>· {t.qtd} mun.</span>
            </div>
          );
        })}
        <span style={{ display: 'flex', alignItems: 'center', gap: 5, font: '400 12px/1 var(--ff-body)', color: 'var(--tx-3)', marginLeft: 'auto' }}>
          <span style={{ width: 12, height: 12, borderRadius: 3, background: '#e5e7eb', display: 'inline-block', border: '1px solid rgba(0,0,0,.1)' }}></span>
          Sem mapeamento
        </span>
      </div>
    </div>
  );
}

window.MapaTerritorial = MapaTerritorial;
