// ===== Elejemais — Other screens (Mapa, Lideranças, Apoiadores, Relatório) =====

const { useState: useState_sc, useEffect: useEffect_sc } = React;

/* ─────────────── HELPERS DE PERMISSÃO ─────────────── */
// administrador → acesso total
// coordenador   → gerencia lideranças, apoiadores, vê inteligência
// lideranca     → mapa, ver lideranças, cadastrar apoiadores
// operador      → só cadastra apoiadores, dashboard básico
function canAdmin(role)  { return role === "administrador"; }
function canCoord(role)  { return role === "administrador" || role === "coordenador"; }
function canLider(role)  { return role === "administrador" || role === "coordenador" || role === "lideranca"; }

/* ─────────────── MAPA ─────────────── */
// GeoJSON dos 75 municípios de Sergipe — tbrugz/geodata-br (GitHub)
// Propriedades: { id: "2800308", name: "Aracaju" }
const IBGE_SE_URL = 'https://raw.githubusercontent.com/tbrugz/geodata-br/master/geojson/geojs-28-mun.json';

function MapaScreen({ campaign, openModal }) {
  const [layer,        setLayer]        = useState_sc("apoio");
  const [sel,          setSel]          = useState_sc(null);
  const [regioes,      setRegioes]      = useState_sc([]);
  const [features,     setFeatures]     = useState_sc([]);
  const [geoState,     setGeoState]     = useState_sc("loading"); // loading | ok | error
  const [allMunicipios, setAllMunicipios] = useState_sc([]);
  const role = campaign?.roleRaw || "operador";

  useEffect_sc(() => {
    if (!campaign?.id) return;
    window.API.getMunicipalityStats(campaign.id)
      .then(data => { setRegioes(data); setSel(null); })
      .catch(console.error);
  }, [campaign?.id]);

  useEffect_sc(() => {
    window.API.getMunicipalities().then(setAllMunicipios).catch(console.error);
  }, []);

  useEffect_sc(() => {
    const KEY = 'ibge_se_geo_v4';
    try {
      const raw = sessionStorage.getItem(KEY);
      if (raw) {
        setFeatures(window.projectGeoJSON(JSON.parse(raw)));
        setGeoState("ok");
        return;
      }
    } catch (_) {}
    fetch(IBGE_SE_URL)
      .then(r => { if (!r.ok) throw new Error(r.status); return r.json(); })
      .then(geo => {
        try { sessionStorage.setItem(KEY, JSON.stringify(geo)); } catch (_) {}
        setFeatures(window.projectGeoJSON(geo));
        setGeoState("ok");
      })
      .catch(err => { console.error('Mapa IBGE:', err); setGeoState("error"); });
  }, []);

  const statsByCode = {};
  regioes.forEach(r => { if (r.ibge_code) statsByCode[r.ibge_code] = r; });

  const getVal = (id) => { const s = statsByCode[id]; return s ? (layer === "lider" ? s.lider : s.apoio) : 0; };
  const maxVal = Math.max(1, ...features.map(f => getVal(f.id)));

  const withDataCount = regioes.filter(r => layer === "lider" ? r.lider > 0 : r.apoio > 0).length;

  const selectedFeature = sel ? features.find(f => f.id === sel) : null;
  const selectedData = sel ? (statsByCode[sel] || null) : null;

  // Proportional vote goal per municipality (by population share within campaign UF)
  const campaignUF = campaign?.uf || 'SE';
  const popByCode = {};
  let totalStatePop = 0;
  allMunicipios.forEach(m => {
    if (m.state === campaignUF && m.population && m.ibge_code) {
      popByCode[m.ibge_code] = m.population;
      totalStatePop += m.population;
    }
  });
  const calcMetaLocal = (ibgeCode) => {
    if (!campaign?.metaVotos || totalStatePop === 0 || !ibgeCode) return null;
    const pop = popByCode[ibgeCode];
    if (!pop) return null;
    return Math.round(campaign.metaVotos * pop / totalStatePop);
  };

  const centroid = (d) => {
    const ns = d.match(/[\d.]+/g)?.map(Number) || [];
    const xs = [], ys = [];
    for (let i = 0; i < ns.length - 1; i += 2) { xs.push(ns[i]); ys.push(ns[i+1]); }
    return { cx: xs.reduce((a,b)=>a+b,0)/Math.max(xs.length,1), cy: ys.reduce((a,b)=>a+b,0)/Math.max(ys.length,1) };
  };

  // Só mostra municípios com apoiadores mas sem líder
  const semLider = features
    .filter(f => { const s = statsByCode[f.id]; return s && s.apoio > 0 && s.lider === 0; })
    .slice(0, 8);

  return (
    <div className="dash">
      <div className="dash__header">
        <div>
          <div className="eyebrow">Distribuição geográfica</div>
          <h1 className="serif" style={{ fontSize: 38, lineHeight: 1.05, margin: "8px 0 4px", letterSpacing: "-0.02em" }}>
            Mapa de Sergipe
          </h1>
          <p className="dim" style={{ margin: 0, maxWidth: 540 }}>
            {withDataCount > 0
              ? `${withDataCount} município${withDataCount !== 1 ? 's' : ''} com ${layer === "lider" ? "lideranças" : "apoiadores"}. Clique para ver detalhes.`
              : layer === "lider"
                ? "Nenhum município com lideranças ainda."
                : "Nenhum apoiador vinculado a município. Cadastre apoiadores para visualizar o mapa de calor."}
          </p>
        </div>
        <div className="row" style={{ gap: 8 }}>
          {canCoord(role) && (
            <button className="btn" onClick={() => openModal && openModal("municipios")}>
              <Icon.Map size={14} /> Municípios
            </button>
          )}
          <div className="seg">
            <button className={"seg__btn " + (layer === "apoio" ? "is-active" : "")} onClick={() => setLayer("apoio")}>Apoiadores</button>
            <button className={"seg__btn " + (layer === "lider" ? "is-active" : "")} onClick={() => setLayer("lider")}>Lideranças</button>
          </div>
        </div>
      </div>

      <div className="map-layout">
        <div className="card map-stage">
          {geoState === "loading" && (
            <div className="dim" style={{ textAlign: "center", padding: "80px 0", fontSize: 13 }}>Carregando mapa…</div>
          )}
          {geoState === "error" && (
            <div className="dim" style={{ textAlign: "center", padding: "80px 0", fontSize: 13 }}>
              Erro ao carregar mapa do IBGE.<br />
              <span style={{ fontSize: 11 }}>Verifique a conexão e recarregue.</span>
            </div>
          )}
          {geoState === "ok" && (
            <>
              <svg viewBox="0 0 700 620" width="100%" height="100%">
                <defs>
                  <pattern id="dots" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
                    <circle cx="2" cy="2" r="0.7" fill="var(--line)" />
                  </pattern>
                </defs>
                <rect width="700" height="620" fill="url(#dots)" />
                {features.map(f => {
                  const v = getVal(f.id), t = v / maxVal, isSel = sel === f.id;
                  return (
                    <path key={f.id} d={f.d}
                      fill={v > 0 ? `oklch(${(0.94-t*0.52).toFixed(3)} ${(0.05+t*0.09).toFixed(3)} 155)` : "var(--surface-2)"}
                      stroke={isSel ? "var(--ink)" : "var(--line)"}
                      strokeWidth={isSel ? 2 : 1}
                      style={{ cursor: "pointer", transition: "fill 150ms" }}
                      onClick={() => setSel(isSel ? null : f.id)}
                    />
                  );
                })}
                {features.map(f => {
                  const v = getVal(f.id);
                  if (v === 0) return null;
                  const { cx, cy } = centroid(f.d);
                  return (
                    <text key={f.id + "-lbl"} x={cx} y={cy + 4}
                      textAnchor="middle" fontSize="10" fontWeight="600"
                      fill="var(--ink)" style={{ pointerEvents: "none" }}>
                      {window.fmt(v)}
                    </text>
                  );
                })}
              </svg>
              <div className="map-legend">
                <span className="dim" style={{ fontSize: 11 }}>Sem apoio</span>
                <div style={{ display: "flex", gap: 2 }}>
                  {[0.1, 0.3, 0.5, 0.7, 0.9].map(t => (
                    <div key={t} style={{ width: 22, height: 10, borderRadius: 2,
                      background: `oklch(${(0.94-t*0.52).toFixed(3)} ${(0.05+t*0.09).toFixed(3)} 155)` }} />
                  ))}
                </div>
                <span className="dim" style={{ fontSize: 11 }}>Maior concentração</span>
              </div>
            </>
          )}
        </div>

        <aside className="map-side">
          {sel && selectedData && (
            <div className="card" style={{ padding: 22 }}>
              <div className="eyebrow">Município selecionado</div>
              <h3 className="serif" style={{ fontSize: 24, margin: "6px 0 16px", letterSpacing: "-0.01em" }}>{selectedData.nome}</h3>
              <div className="kv"><span className="dim">Apoiadores</span><strong>{window.fmt(selectedData.apoio)}</strong></div>
              <div className="kv"><span className="dim">Lideranças</span><strong>{selectedData.lider}</strong></div>
              <div className="kv"><span className="dim">Apoio por líder</span><span className="mono">{window.fmt(Math.round(selectedData.apoio / Math.max(1, selectedData.lider)))}</span></div>
              <div className="kv"><span className="dim">% do total</span><span className="mono">{Math.round(selectedData.apoio / Math.max(1, campaign.apoiadores) * 100)}%</span></div>
              {calcMetaLocal(sel) != null && (
                <div className="kv" style={{ marginTop: 6, paddingTop: 6, borderTop: "1px solid var(--line)" }}>
                  <span className="dim">Meta proporcional</span>
                  <strong className="mono" style={{ color: "var(--accent)" }}>{window.fmt(calcMetaLocal(sel))} votos</strong>
                </div>
              )}
              <div style={{ height: 5, background: "var(--surface-2)", borderRadius: 999, marginTop: 14 }}>
                <div style={{ width: `${selectedData.apoio/Math.max(1,regioes[0]?.apoio)*100}%`, height:"100%", background:"var(--accent)", borderRadius:999 }} />
              </div>
              <button className="btn btn--primary btn--block" style={{ marginTop: 16 }}
                onClick={() => openModal && openModal("liderancas-regiao", { nome: selectedData.nome })}>
                Ver lideranças <Icon.Arrow size={13} />
              </button>
            </div>
          )}

          {sel && !selectedData && (
            <div className="card" style={{ padding: 22 }}>
              <div className="eyebrow">Município selecionado</div>
              <h3 className="serif" style={{ fontSize: 22, margin: "6px 0 12px" }}>{selectedFeature?.nome || "Sem dados ainda"}</h3>
              <p className="dim" style={{ fontSize: 13 }}>Nenhum apoiador cadastrado neste município.</p>
              {calcMetaLocal(sel) != null && (
                <div className="kv" style={{ marginTop: 10 }}>
                  <span className="dim">Meta proporcional</span>
                  <strong className="mono" style={{ color: "var(--accent)" }}>{window.fmt(calcMetaLocal(sel))} votos</strong>
                </div>
              )}
              {canCoord(role) && (
                <button className="btn btn--primary btn--block" style={{ marginTop: 12 }}
                  onClick={() => openModal && openModal("nova-lideranca", {})}>
                  <Icon.Plus size={13} /> Atribuir liderança
                </button>
              )}
            </div>
          )}

          <div className="card" style={{ padding: 22 }}>
            <div className="eyebrow">Cobertura</div>
            <h3 className="serif" style={{ fontSize: 20, margin: "4px 0 14px" }}>
              {semLider.length > 0
                ? `${semLider.length}${semLider.length === 8 ? "+" : ""} municípios sem líder`
                : withDataCount > 0 ? "Boa cobertura!" : "Sem dados ainda"}
            </h3>
            {semLider.length > 0 ? (
              <ul className="gaps">
                {semLider.map((f, i) => {
                  const nome = statsByCode[f.id]?.nome || f.nome;
                  return nome ? (
                    <li key={f.id}>
                      <span className="dim mono">{String(i+1).padStart(2,"0")}</span>
                      <span style={{ fontSize: 12.5 }}>{nome}</span>
                      {canCoord(role) && (
                        <button className="btn btn--ghost btn--sm"
                          onClick={() => openModal && openModal("nova-lideranca", { municipio: f.id })}>
                          Atribuir
                        </button>
                      )}
                    </li>
                  ) : null;
                })}
              </ul>
            ) : (
              <p className="dim" style={{ fontSize: 13 }}>
                {withDataCount > 0
                  ? `Todos os ${withDataCount} municípios com ${layer === "lider" ? "lideranças" : "apoiadores"} têm cobertura.`
                  : layer === "lider"
                    ? "Cadastre lideranças vinculadas a municípios."
                    : "Cadastre apoiadores vinculados a municípios para ver a cobertura."}
              </p>
            )}
          </div>
        </aside>
      </div>
    </div>
  );
}

/* ─────────────── LIDERANÇAS ─────────────── */
function LiderancasScreen({ campaign, openModal }) {
  const [filter,       setFilter]       = useState_sc("todas");
  const [lideres,      setLideres]      = useState_sc([]);
  const [loading,      setLoading]      = useState_sc(true);
  const [editingLider, setEditingLider] = useState_sc(null);
  const [copiedLider,  setCopiedLider]  = useState_sc(null);
  const [membros,      setMembros]      = useState_sc([]);
  const [copiedMembro, setCopiedMembro] = useState_sc(null);
  const role = campaign?.roleRaw || "operador";

  function buildLandingUrl(token) {
    return window.location.href.split('#')[0].split('?')[0].replace(/[^\/]*\.html.*$/, '') + 'landingpage.html?t=' + token;
  }

  async function handleCopyLiderLink(e, liderId) {
    e.stopPropagation();
    try {
      var token = await window.API.getLeaderPublicToken(liderId);
      await navigator.clipboard.writeText(buildLandingUrl(token));
      setCopiedLider(liderId);
      setTimeout(function() { setCopiedLider(null); }, 2000);
    } catch (err) { console.error('Erro ao copiar link:', err); }
  }

  async function handleCopyMembroLink(e, membro) {
    e.stopPropagation();
    if (!membro.publicToken) return;
    try {
      await navigator.clipboard.writeText(buildLandingUrl(membro.publicToken));
      setCopiedMembro(membro.userId);
      setTimeout(function() { setCopiedMembro(null); }, 2000);
    } catch (err) { console.error('Erro ao copiar link:', err); }
  }

  useEffect_sc(() => {
    if (!campaign?.id) return;
    setLoading(true);
    Promise.all([
      window.API.getLeaders(campaign.id),
      window.API.getMemberCaptors(campaign.id),
    ]).then(function([lids, mems]) {
      setLideres(lids);
      setMembros(mems);
      setLoading(false);
    }).catch(function(err) { console.error(err); setLoading(false); });
  }, [campaign?.id]);

  const handleLiderUpdate = async (id, updates) => {
    const updated = await window.API.updateLeader(id, updates);
    setLideres(prev => prev.map(l => l.id === id ? updated : l));
  };

  const filtered = lideres.filter(l => filter === "todas" || l.status === filter);

  const total        = lideres.length;
  const ativas       = lideres.filter(l => l.status === "ativa").length;
  const atencao      = lideres.filter(l => l.status === "atencao").length;
  const novas        = lideres.filter(l => l.status === "nova").length;
  const totalEstVotos = lideres.reduce((sum, l) => sum + (l.estimativaVotos || 0), 0);

  return (
    <div className="dash">
      <div className="dash__header">
        <div>
          <div className="eyebrow">Lideranças</div>
          <h1 className="serif" style={{ fontSize: 38, lineHeight: 1.05, margin: "8px 0 4px", letterSpacing: "-0.02em" }}>
            {loading ? "Carregando…" : `${total} liderança${total !== 1 ? "s" : ""} cadastrada${total !== 1 ? "s" : ""}`}
          </h1>
          <p className="dim" style={{ margin: 0 }}>
            Coordenadores e líderes responsáveis por cadastrar apoiadores em campo.
          </p>
        </div>
        {canCoord(role) && (
          <div className="row" style={{ gap: 8 }}>
            <button className="btn btn--primary" onClick={() => openModal && openModal("nova-lideranca")}>
              <Icon.Plus size={14} /> Nova liderança
            </button>
          </div>
        )}
      </div>

      <div className="dash__grid">
        <SmallStat eyebrow="Total"       value={String(total)}  foot={`${total} registros`} />
        <SmallStat eyebrow="Ativas"      value={String(ativas)} foot={total > 0 ? `${Math.round(ativas/total*100)}%` : "—"} accent="var(--accent)" />
        <SmallStat eyebrow="Em atenção"  value={String(atencao)} foot="sem cadastros recentes" accent="var(--warm)" />
        <SmallStat eyebrow="Est. votos total" value={totalEstVotos > 0 ? window.fmt(totalEstVotos) : "—"} foot="soma das estimativas" />
      </div>

      <div className="card" style={{ padding: 0, overflow: "hidden" }}>
        <div className="row" style={{ padding: "14px 18px", borderBottom: "1px solid var(--line)" }}>
          <div className="seg">
            {[["todas","Todas"],["ativa","Ativas"],["atencao","Atenção"],["nova","Novas"]].map(([k,l]) => (
              <button key={k} className={"seg__btn " + (filter === k ? "is-active" : "")} onClick={() => setFilter(k)}>{l}</button>
            ))}
          </div>
          <span className="spacer" />
          <span className="dim" style={{ fontSize: 12 }}>Mostrando {filtered.length} de {total}</span>
        </div>

        {loading ? (
          <div className="dim" style={{ textAlign: "center", padding: 40 }}>Carregando lideranças…</div>
        ) : filtered.length === 0 ? (
          <div style={{ textAlign: "center", padding: 48 }}>
            <div className="dim" style={{ fontSize: 14, marginBottom: 12 }}>
              {total === 0
                ? "Nenhuma liderança cadastrada ainda."
                : "Nenhuma liderança neste filtro."}
            </div>
            {total === 0 && canCoord(role) && (
              <button className="btn btn--primary" onClick={() => openModal && openModal("nova-lideranca")}>
                <Icon.Plus size={14} /> Cadastrar primeira liderança
              </button>
            )}
          </div>
        ) : (
          <div className="tbl-wrap"><table className="tbl">
            <thead>
              <tr>
                <th>Liderança</th>
                <th>Função</th>
                <th>Região</th>
                <th className="num">Apoiadores</th>
                <th className="num">Est. Votos</th>
                <th>Telefone</th>
                <th>Desde</th>
                <th>Status</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(l => (
                <tr key={l.id} style={{ cursor: "pointer" }} onClick={() => setEditingLider(l)}>
                  <td>
                    <div className="row" style={{ gap: 10 }}>
                      <span className="avatar avatar--sm">{l.nome.split(" ").map(x=>x[0]).slice(0,2).join("")}</span>
                      <strong>{l.nome}</strong>
                    </div>
                  </td>
                  <td className="dim">{l.funcao}</td>
                  <td>{l.regiao}</td>
                  <td className="num mono">{window.fmt(l.apoio)}</td>
                  <td className="num mono">{l.estimativaVotos != null ? window.fmt(l.estimativaVotos) : "—"}</td>
                  <td className="mono dim">{l.telefone || "—"}</td>
                  <td className="dim">{l.desde}</td>
                  <td>
                    <span className={"badge " + (l.status === "ativa" ? "badge--accent" : l.status === "atencao" ? "badge--warm" : "")}>
                      <span className="badge--dot" />{l.status}
                    </span>
                  </td>
                  <td onClick={e => e.stopPropagation()}>
                    <div className="row" style={{ gap: 4 }}>
                      <button
                        className="btn btn--ghost btn--icon"
                        title={copiedLider === l.id ? "Copiado!" : "Copiar link do líder"}
                        onClick={e => handleCopyLiderLink(e, l.id)}
                        style={{ color: copiedLider === l.id ? "var(--accent)" : undefined }}
                      >
                        <Icon.Link size={14} />
                      </button>
                      <button className="btn btn--ghost btn--icon" onClick={() => setEditingLider(l)}>
                        <Icon.Edit size={14} />
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table></div>
        )}
      </div>

      {/* ── Equipe (membros da plataforma) ── */}
      <div className="card" style={{ padding: 0, overflow: "hidden" }}>
        <div style={{ padding: "14px 18px", borderBottom: "1px solid var(--line)" }}>
          <div className="row" style={{ alignItems: "center", gap: 8 }}>
            <div>
              <div className="eyebrow" style={{ marginBottom: 2 }}>Equipe da campanha</div>
              <p className="dim" style={{ margin: 0, fontSize: 13 }}>
                Membros com acesso à plataforma — apoiadores captados pelo link pessoal de cada um.
              </p>
            </div>
          </div>
        </div>
        {loading ? (
          <div className="dim" style={{ textAlign: "center", padding: 32 }}>Carregando equipe…</div>
        ) : membros.length === 0 ? (
          <div className="dim" style={{ textAlign: "center", padding: 32, fontSize: 13 }}>Nenhum membro encontrado.</div>
        ) : (
          <div className="tbl-wrap"><table className="tbl">
            <thead>
              <tr>
                <th>Membro</th>
                <th>Papel</th>
                <th className="num">Captados</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {membros.map(function(m) {
                var iniciais = m.nome.split(" ").map(function(x){ return x[0]; }).slice(0,2).join("");
                var copied = copiedMembro === m.userId;
                return (
                  <tr key={m.userId}>
                    <td>
                      <div className="row" style={{ gap: 10 }}>
                        <span className="avatar avatar--sm">{iniciais}</span>
                        <div>
                          <strong>{m.nome}</strong>
                          <div className="dim" style={{ fontSize: 11.5 }}>{m.email}</div>
                        </div>
                      </div>
                    </td>
                    <td>
                      <span className="badge badge--accent" style={{ opacity: 0.85 }}>
                        <span className="badge--dot" />{m.roleLabel}
                      </span>
                    </td>
                    <td className="num mono">
                      <strong style={{ color: m.captados > 0 ? "var(--accent)" : undefined }}>
                        {window.fmt(m.captados)}
                      </strong>
                    </td>
                    <td>
                      {m.publicToken && (
                        <button
                          className="btn btn--ghost btn--icon"
                          title={copied ? "Copiado!" : "Copiar link pessoal"}
                          onClick={function(e){ handleCopyMembroLink(e, m); }}
                          style={{ color: copied ? "var(--accent)" : undefined }}
                        >
                          <Icon.Link size={14} />
                        </button>
                      )}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table></div>
        )}
      </div>

      {editingLider && (
        <EditarLiderancaModal
          lider={editingLider}
          onClose={() => setEditingLider(null)}
          onSave={handleLiderUpdate}
        />
      )}
    </div>
  );
}

/* ─── Modal de edição de liderança (embutido aqui pois screens.jsx carrega antes de modals.jsx) ─── */
function EditarLiderancaModal({ lider, onClose, onSave }) {
  const [municipios, setMunicipios] = useState_sc([]);
  const [nome,       setNome]       = useState_sc(lider.nome || "");
  const [telefone,   setTel]        = useState_sc(lider.telefone || "");
  const [roleRaw,    setRole]       = useState_sc(lider.roleRaw || "lideranca_municipal");
  const [munId,      setMunId]      = useState_sc(lider.municipioId || "");
  const [estVotos,   setEst]        = useState_sc(lider.estimativaVotos != null ? String(lider.estimativaVotos) : "");
  const [status,     setStatus]     = useState_sc(lider.status || "nova");
  const [loading,    setLoading]    = useState_sc(false);
  const [erro,       setErro]       = useState_sc("");

  useEffect_sc(() => {
    window.API.getMunicipalities().then(setMunicipios).catch(console.error);
  }, []);

  useEffect_sc(() => {
    const k = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", k);
    return () => window.removeEventListener("keydown", k);
  }, [onClose]);

  const handleSave = async () => {
    if (!nome.trim()) return;
    setLoading(true); setErro("");
    try {
      await onSave(lider.id, {
        name:            nome.trim(),
        phone:           telefone.trim() || null,
        role:            roleRaw || null,
        municipality_id: munId   || null,
        vote_estimate:   estVotos.trim() ? parseInt(estVotos) : null,
        status,
      });
      onClose();
    } catch (err) {
      setErro(err.message);
    } finally {
      setLoading(false);
    }
  };

  const LBL = { fontSize: 11, fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--muted)", marginBottom: 6, display: "block" };

  return (
    <div className="modal-back" onClick={onClose}>
      <div className="modal" style={{ maxWidth: 680 }} onClick={e => e.stopPropagation()}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 20 }}>
          <div>
            <div style={LBL}>Editar liderança</div>
            <h3 className="serif" style={{ fontSize: 26, margin: 0, letterSpacing: "-0.01em" }}>{lider.nome}</h3>
          </div>
          <button className="btn btn--ghost btn--icon" onClick={onClose}><Icon.X size={14} /></button>
        </div>

        <div style={{ display: "grid", gap: 14 }}>
          <div className="form-grid-2">
            <label style={{ display: "block" }}>
              <span style={LBL}>Nome completo</span>
              <input className="input" value={nome} onChange={e => { setNome(e.target.value); setErro(""); }} autoFocus />
            </label>
            <label style={{ display: "block" }}>
              <span style={LBL}>Telefone</span>
              <input className="input mono" placeholder="(79) 9 0000-0000" value={telefone} onChange={e => setTel(e.target.value)} />
            </label>
          </div>

          <div className="form-grid-2">
            <label style={{ display: "block" }}>
              <span style={LBL}>Função</span>
              <select className="input" value={roleRaw} onChange={e => setRole(e.target.value)}>
                <option value="coordenador_regional">Coordenador Regional</option>
                <option value="lideranca_municipal">Líder Municipal</option>
                <option value="lideranca_comunitaria">Líder Comunitário</option>
                <option value="coord_midia">Coord. de Mídia</option>
                <option value="coord_juventude">Coord. Juventude</option>
              </select>
            </label>
            <label style={{ display: "block" }}>
              <span style={LBL}>Município</span>
              <select className="input" value={munId} onChange={e => setMunId(e.target.value)}>
                <option value="">— Sem município —</option>
                {municipios.map(m => <option key={m.id} value={m.id}>{m.name}</option>)}
              </select>
            </label>
          </div>

          <div className="form-grid-2">
            <label style={{ display: "block" }}>
              <span style={LBL}>Estimativa de votos</span>
              <input className="input mono" type="number" min="0" placeholder="Ex: 500"
                value={estVotos} onChange={e => setEst(e.target.value)} />
            </label>
            <label style={{ display: "block" }}>
              <span style={LBL}>Status</span>
              <div className="seg" style={{ marginTop: 2 }}>
                {[["nova","Nova"],["ativa","Ativa"],["atencao","Atenção"],["inativa","Inativa"]].map(([v,l]) => (
                  <button key={v} className={"seg__btn " + (status === v ? "is-active" : "")} onClick={() => setStatus(v)}>{l}</button>
                ))}
              </div>
            </label>
          </div>

          {erro && (
            <div style={{ fontSize: 13, padding: "8px 12px", background: "oklch(0.97 0.02 30)", borderRadius: 6, color: "oklch(0.50 0.18 30)" }}>
              {erro}
            </div>
          )}
        </div>

        <div style={{ display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 20, paddingTop: 18, borderTop: "1px solid var(--line)" }}>
          <button className="btn" onClick={onClose}>Cancelar</button>
          <button className="btn btn--primary" disabled={loading || !nome.trim()} onClick={handleSave}>
            {loading ? "Salvando…" : "Salvar alterações"}
          </button>
        </div>
      </div>
    </div>
  );
}

function SmallStat({ eyebrow, value, foot, accent }) {
  return (
    <div className="card" style={{ padding: "18px 20px" }}>
      <div className="eyebrow">{eyebrow}</div>
      <div className="serif" style={{ fontSize: 38, lineHeight: 1, margin: "8px 0 4px", color: accent || "var(--ink)" }}>{value}</div>
      <div className="dim" style={{ fontSize: 12 }}>{foot}</div>
    </div>
  );
}

/* ─────────────── APOIADORES ─────────────── */
function ApoiadoresScreen({ campaign, openModal }) {
  const [apoiadores, setApoiadores] = useState_sc([]);
  const [series,     setSeries]     = useState_sc([]);
  const [regioes,    setRegioes]    = useState_sc([]);
  const [loading,    setLoading]    = useState_sc(true);
  const role = campaign?.roleRaw || "operador";

  useEffect_sc(() => {
    if (!campaign?.id) return;
    setLoading(true);
    Promise.all([
      window.API.getSupporters(campaign.id),
      window.API.getGrowthSeries(campaign.id),
      window.API.getMunicipalityStats(campaign.id),
    ]).then(([a, s, r]) => {
      setApoiadores(a);
      setSeries(s);
      setRegioes(r);
      setLoading(false);
    }).catch(err => { console.error(err); setLoading(false); });
  }, [campaign?.id]);

  const origemData = [
    { label: "Liderança",  value: apoiadores.filter(a => a.origem === "lideranca").length,     color: "oklch(0.44 0.11 155)" },
    { label: "Indicação",  value: apoiadores.filter(a => a.origem === "indicacao").length,     color: "oklch(0.62 0.16 40)" },
    { label: "Evento",     value: apoiadores.filter(a => a.origem === "evento").length,        color: "oklch(0.55 0.14 250)" },
    { label: "Redes",      value: apoiadores.filter(a => a.origem === "redes_sociais").length, color: "oklch(0.58 0.14 320)" },
  ].filter(o => o.value > 0);

  return (
    <div className="dash">
      <div className="dash__header">
        <div>
          <div className="eyebrow">Base de apoiadores</div>
          <h1 className="serif" style={{ fontSize: 38, lineHeight: 1.05, margin: "8px 0 4px", letterSpacing: "-0.02em" }}>
            {loading ? "Carregando…" : `${window.fmt(campaign.apoiadores)} apoiadores`}
          </h1>
          <p className="dim" style={{ margin: 0 }}>
            {regioes.length > 0
              ? `Distribuídos em ${regioes.length} município${regioes.length !== 1 ? "s" : ""} por ${campaign.liderancas} liderança${campaign.liderancas !== 1 ? "s" : ""}.`
              : "Cadastre apoiadores para começar a acompanhar sua base."}
          </p>
        </div>
        <div className="row" style={{ gap: 8 }}>
          {canCoord(role) && (
            <button className="btn" onClick={() => openModal && openModal("exportar")}><Icon.Download size={14} /> Exportar CSV</button>
          )}
          <button className="btn btn--primary" onClick={() => openModal && openModal("cadastrar-apoiador")}><Icon.Plus size={14} /> Cadastrar apoiador</button>
        </div>
      </div>

      <div className="dash__row">
        <div className="card dash__row__third" style={{ padding: "20px 22px" }}>
          <div className="eyebrow">Por mês</div>
          <h3 className="serif" style={{ fontSize: 22, margin: "4px 0 12px" }}>Crescimento</h3>
          {series.length > 0 ? (
            <window.Charts.LineChart data={series} keys={["apoio"]} colors={["oklch(0.44 0.11 155)"]} height={150} />
          ) : (
            <div className="dim" style={{ textAlign: "center", padding: "40px 0", fontSize: 13 }}>Sem dados ainda.</div>
          )}
        </div>
        <div className="card dash__row__third" style={{ padding: "20px 22px" }}>
          <div className="eyebrow">Concentração</div>
          <h3 className="serif" style={{ fontSize: 22, margin: "4px 0 14px" }}>Por região</h3>
          {regioes.length > 0 ? (
            <window.Charts.RankBars data={regioes.slice(0, 5)} />
          ) : (
            <div className="dim" style={{ textAlign: "center", padding: "40px 0", fontSize: 13 }}>Sem dados ainda.</div>
          )}
        </div>
        <div className="card dash__row__third" style={{ padding: "20px 22px" }}>
          <div className="eyebrow">Origem</div>
          <h3 className="serif" style={{ fontSize: 22, margin: "4px 0 14px" }}>Como conheceu</h3>
          {origemData.length > 0 ? (
            <window.Charts.Donut size={140} label="Apoiadores" data={origemData} />
          ) : (
            <div className="dim" style={{ textAlign: "center", padding: "40px 0", fontSize: 13 }}>Sem dados ainda.</div>
          )}
        </div>
      </div>

      <div className="card" style={{ padding: 0, overflow: "hidden" }}>
        <div className="row" style={{ padding: "14px 18px", borderBottom: "1px solid var(--line)" }}>
          <strong>Cadastros recentes</strong>
          <span className="spacer" />
          <span className="dim" style={{ fontSize: 12 }}>{apoiadores.length} registros carregados</span>
        </div>
        {loading ? (
          <div className="dim" style={{ textAlign: "center", padding: 40 }}>Carregando apoiadores…</div>
        ) : apoiadores.length === 0 ? (
          <div style={{ textAlign: "center", padding: 48 }}>
            <div className="dim" style={{ fontSize: 14, marginBottom: 12 }}>Nenhum apoiador cadastrado ainda.</div>
            <button className="btn btn--primary" onClick={() => openModal && openModal("cadastrar-apoiador")}>
              <Icon.Plus size={14} /> Cadastrar primeiro apoiador
            </button>
          </div>
        ) : (
          <div className="tbl-wrap"><table className="tbl">
            <thead>
              <tr>
                <th>Apoiador</th>
                <th>Município</th>
                <th>Telefone</th>
                <th>Cadastrado por</th>
                <th>Quando</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {apoiadores.map((a, i) => (
                <tr key={a.id || i}>
                  <td>
                    <div className="row" style={{ gap: 10 }}>
                      <span className="avatar avatar--sm">{a.nome.split(" ").map(x=>x[0]).slice(0,2).join("")}</span>
                      <strong>{a.nome}</strong>
                    </div>
                  </td>
                  <td>{a.bairro}</td>
                  <td className="mono dim">{a.telefone || "—"}</td>
                  <td className="dim">{a.lider}</td>
                  <td className="dim">{a.data}</td>
                  <td><button className="btn btn--ghost btn--icon"><Icon.More size={14} /></button></td>
                </tr>
              ))}
            </tbody>
          </table></div>
        )}
      </div>
    </div>
  );
}

/* ─────────────── RELATÓRIO ─────────────── */
function RelatorioScreen({ campaign, openModal }) {
  const role = campaign?.roleRaw || "operador";
  const reports = [
    { titulo: "Relatório semanal de campanha", desc: "Visão executiva: meta, crescimento, ranking de lideranças.", dataAtu: "sob demanda", formato: "PDF" },
    { titulo: "Apoiadores por município",      desc: "Tabela completa com filtros por região e período.", dataAtu: "sob demanda", formato: "CSV/XLSX" },
    { titulo: "Performance das lideranças",   desc: "Quantos apoiadores cada líder cadastrou no período.", dataAtu: "sob demanda", formato: "PDF" },
    { titulo: "Cobertura geográfica",         desc: "Municípios cobertos × sem líder, com mapa de calor.", dataAtu: "sob demanda", formato: "PDF" },
    { titulo: "Projeção de votos",            desc: "Cenários otimista, realista e conservador.", dataAtu: "sob demanda", formato: "PDF" },
    { titulo: "Auditoria de cadastros",       desc: "Possíveis duplicados, dados inconsistentes.", dataAtu: "sob demanda", formato: "CSV" },
  ];

  return (
    <div className="dash">
      <div className="dash__header">
        <div>
          <div className="eyebrow">Relatórios</div>
          <h1 className="serif" style={{ fontSize: 38, lineHeight: 1.05, margin: "8px 0 4px", letterSpacing: "-0.02em" }}>
            Documentos da campanha
          </h1>
          <p className="dim" style={{ margin: 0 }}>Exporte relatórios prontos para apresentar à coordenação.</p>
        </div>
        {canCoord(role) && (
          <button className="btn btn--primary" onClick={() => openModal && openModal("relatorio-custom")}>
            <Icon.Sparkle size={14} /> Gerar relatório customizado
          </button>
        )}
      </div>

      <div className="rep-grid">
        {reports.map((r, i) => (
          <div className="card rep-card" key={i}>
            <div className="row" style={{ justifyContent: "space-between" }}>
              <span className="badge">{r.formato}</span>
              <Icon.Report size={18} />
            </div>
            <h3 className="serif" style={{ fontSize: 22, margin: "16px 0 6px", letterSpacing: "-0.01em", lineHeight: 1.15 }}>{r.titulo}</h3>
            <p className="dim" style={{ fontSize: 13, margin: 0, flex: 1 }}>{r.desc}</p>
            <div className="row" style={{ justifyContent: "space-between", marginTop: 16 }}>
              <span className="dim mono" style={{ fontSize: 11 }}>{r.dataAtu}</span>
              {canCoord(role) && (
                <button className="btn btn--sm"><Icon.Download size={12} /> Baixar</button>
              )}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

window.Screens = { MapaScreen, LiderancasScreen, ApoiadoresScreen, RelatorioScreen };
