// Relatório — Diagnóstico completo (orçamento, patrimônio, proteção, sucessão) — imprimível

// ===== Diagnóstico do consultor: inconsistências e insights gerados dos dados =====
function gerarDiagnostico(state, year, month) {
  const out = [];
  const add = (nivel, titulo, texto) => out.push({ nivel, titulo, texto });
  const fmt = window.fmtBRLString;
  const hoje = new Date().toISOString().slice(0, 10);

  const plano = window.computePlano(state.transactions, state.aggregates, year, month);
  const tot = window.patrimonioTotais(state.patrimonio, state.dividas);
  const custo = window.custoFixoDetalhe(state.transactions, 3, (state.reserva || {}).base || "todos");
  const mesLabel = window.MESES_FULL[month] + "/" + year;

  // --- Orçamento / plano 70·10·10·10 ---
  if (plano.income === 0) {
    add("atencao", "Sem receita lançada em " + mesLabel, "O plano 70·10·10·10 só funciona com a receita do mês registrada. Lance as entradas no Checklist para ativar os tetos e metas.");
  } else {
    const g = plano.gastos;
    if (g.over) {
      add("alerta", "Gastos " + fmt(g.overBy) + " acima do teto de 70%",
        "Em " + mesLabel + " os gastos comprometidos somam " + fmt(g.used) + " para um teto de " + fmt(g.target) + ". Há " + fmt(g.redutivelPendente) + " em despesas redutíveis ainda não pagas — é onde o corte não afeta o essencial.");
    } else {
      add("ok", "Gastos dentro do teto de 70%", "Folga de " + fmt(g.target - g.used) + " em " + mesLabel + ". Manter os gastos abaixo do teto é o que libera os 30% para caridade, projetos e investimentos.");
    }
    for (const b of plano.buckets) {
      if (b.key === "gastos") continue;
      if (b.used + 0.5 < b.target) {
        add("atencao", b.icon + " " + b.label + " abaixo da meta de 10%",
          "Lançado " + fmt(b.used) + " de " + fmt(b.target) + ". Faltam " + fmt(b.target - b.used) + " para cumprir o balde em " + mesLabel + ".");
      }
    }
    const sobra = plano.income - plano.gastos.used - plano.buckets.filter(b => b.key !== "gastos").reduce((s, b) => s + b.used, 0);
    if (sobra < 0) add("alerta", "Mês fechando no vermelho", "As saídas de " + mesLabel + " superam a receita em " + fmt(-sobra) + ". Priorize os cortes em redutíveis antes de comprometer a reserva.");
  }

  // --- Reserva de emergência ---
  const saldosReserva = (state.patrimonio.saldos || []).filter(s => s.reserva);
  const reservaSaldo = state.reserva && state.reserva.saldoManual != null ? state.reserva.saldoManual : saldosReserva.reduce((s, x) => s + Number(x.valor || 0), 0);
  const mesesAlvo = (state.reserva || {}).mesesAlvo || 6;
  if (custo.media > 0) {
    const meses = reservaSaldo / custo.media;
    if (reservaSaldo <= 0) add("alerta", "Sem reserva de emergência", "Com custo mensal de " + fmt(custo.media) + ", o alvo de " + mesesAlvo + " meses é " + fmt(custo.media * mesesAlvo) + ". Marque ativos líquidos como reserva ou comece um aporte mensal dedicado.");
    else if (meses < mesesAlvo) add("atencao", "Reserva cobre " + meses.toFixed(1) + " de " + mesesAlvo + " meses", "Faltam " + fmt(custo.media * mesesAlvo - reservaSaldo) + " para o colchão completo. Reserva vem antes de investimentos de maior risco.");
    else add("ok", "Reserva de emergência completa", meses.toFixed(1) + " meses de custo cobertos (" + fmt(reservaSaldo) + "). Excedentes podem migrar para objetivos e aposentadoria.");
  }

  // --- Dívidas ---
  const dividas = state.dividas || [];
  const vencidas = dividas.filter(d => d.status !== "Finalizado" && d.vencimento && d.vencimento < hoje);
  if (vencidas.length) add("alerta", vencidas.length + " dívida(s) com vencimento estourado", vencidas.map(d => d.descricao + " (venceu " + d.vencimento.split("-").reverse().join("/") + ")").join(" · ") + ". Renegociar evita juros e restrições.");
  const semNeg = dividas.filter(d => d.status === "Sem Negociação");
  if (semNeg.length) add("atencao", "Dívida sem negociação", semNeg.map(d => d.descricao + " — " + fmt(d.saldoDevedor)).join(" · ") + ". Sem acordo formal, o passivo tende a crescer e a travar o planejamento.");
  if (tot.totalDividas > 0 && tot.total > 0) {
    const pctDiv = (tot.totalDividas / tot.total) * 100;
    add(pctDiv > 30 ? "atencao" : "insight", "Dívidas equivalem a " + pctDiv.toFixed(0) + "% do patrimônio",
      fmt(tot.totalDividas) + " devidos contra " + fmt(tot.total) + " de patrimônio bruto — patrimônio líquido de " + fmt(tot.liquido) + ".");
  }

  // --- Proteção ---
  const seguros = state.seguros || [];
  const vidas = seguros.filter(s => s.tipo === "Vida");
  const temFilhos = (state.familia.filhos || []).length > 0;
  if (!vidas.length && temFilhos) add("alerta", "Família com filhos e sem seguro de vida", "Uma referência didática: capital segurado de 3 a 5 anos do custo da família" + (custo.media > 0 ? " (entre " + fmt(custo.media * 36) + " e " + fmt(custo.media * 60) + ")" : "") + " protege a transição em caso de perda do provedor.");
  else if (vidas.length && custo.media > 0) {
    const capital = vidas.reduce((s, v) => s + Number(v.capital || 0), 0);
    const anos = capital / (custo.media * 12);
    if (anos < 3) add("atencao", "Capital de vida cobre " + anos.toFixed(1) + " ano(s) de custo", "Capital segurado de " + fmt(capital) + " ante um custo anual de " + fmt(custo.media * 12) + ". Referência usual: 3 a 5 anos.");
    else add("ok", "Seguro de vida em patamar adequado", "Capital de " + fmt(capital) + " cobre " + anos.toFixed(1) + " anos do custo da família.");
  }
  const segVencidos = seguros.filter(s => s.vigencia && s.vigencia < hoje);
  if (segVencidos.length) add("alerta", "Apólice(s) com vigência vencida", segVencidos.map(s => s.nome + " (até " + s.vigencia.split("-").reverse().join("/") + ")").join(" · ") + ". Confirme a renovação para não ficar descoberto.");
  const naoSegurados = [...(state.patrimonio.imoveis || []), ...(state.patrimonio.veiculos || [])].filter(a => !a.segurado);
  if (naoSegurados.length) add("atencao", "Bens sem seguro", naoSegurados.map(a => a.nome + " (" + window.fmtCompact(a.valor) + ")").join(" · ") + ". Avalie o custo do seguro contra o impacto de uma perda total.");

  // --- Aposentadoria ---
  const apos = window.calcAposentadoria(state.aposentadoria, tot.financeiro);
  if ((state.aposentadoria.rendaMensalDesejada || 0) > 0) {
    const aporteAtual = Number(state.aposentadoria.aporteMensal || 0);
    if (apos.aporteNecessario > aporteAtual + 1) add("atencao", "Aporte de aposentadoria abaixo do necessário",
      "Para " + fmt(state.aposentadoria.rendaMensalDesejada) + "/mês aos " + state.aposentadoria.idadeAlvo + " anos, o aporte estimado é " + fmt(apos.aporteNecessario) + "/mês — hoje são " + fmt(aporteAtual) + ".");
    else add("ok", "Plano de aposentadoria no ritmo", "Aporte atual de " + fmt(aporteAtual) + "/mês projeta " + window.fmtCompact(apos.projecao) + " aos " + state.aposentadoria.idadeAlvo + " anos, para um alvo de " + window.fmtCompact(apos.alvo) + ".");
  }

  // --- Sucessão / liquidez ---
  const suc = window.calcSucessao(state);
  const capitalVidaSuc = seguros.filter(s => s.tipo === "Vida" || s.tipo === "Invalidez").reduce((s, v) => s + Number(v.capital || 0), 0);
  if (suc.custoExtrajudicial > 0 && tot.total > 0) {
    const cob = capitalVidaSuc / suc.custoExtrajudicial;
    if (cob >= 1) add("ok", "Custo do inventário coberto pelo seguro", "O capital segurado de " + fmt(capitalVidaSuc) + " cobre integralmente o custo estimado do inventário extrajudicial (" + fmt(suc.custoExtrajudicial) + ").");
    else add("alerta", "Seguro cobre " + Math.round(cob * 100) + "% do custo do inventário", "O inventário extrajudicial custa ~" + fmt(suc.custoExtrajudicial) + " e o capital segurado é " + fmt(capitalVidaSuc) + ". Sugestão: aumentar a proteção em " + fmt(suc.custoExtrajudicial - capitalVidaSuc) + " para dar liquidez imediata aos herdeiros (na via judicial o custo sobe para " + fmt(suc.custoJudicial) + ").");
  }
  if (suc.custoExtrajudicial > tot.financeiro + capitalVidaSuc && tot.total > 0) add("atencao", "Custo sucessório maior que a liquidez disponível",
    "Somando patrimônio financeiro (" + fmt(tot.financeiro) + ") e seguro (" + fmt(capitalVidaSuc) + "), ainda falta caixa para os ~" + fmt(suc.custoExtrajudicial) + " do inventário. Sem liquidez, herdeiros podem ter que vender bens às pressas.");
  if (tot.previdencia === 0 && tot.total > 0) add("insight", "Nenhum recurso livre de inventário", "Previdência (PGBL/VGBL) não passa por inventário e dá liquidez imediata aos beneficiários — instrumento útil no planejamento sucessório.");
  if (tot.total > 0 && tot.naoFinanceiro / tot.total > 0.8) add("insight", "Patrimônio concentrado em bens ilíquidos", ((tot.naoFinanceiro / tot.total) * 100).toFixed(0) + "% do patrimônio está em imóveis, veículos e participações. Diversificar em ativos financeiros dá flexibilidade para emergências e oportunidades.");

  // --- Objetivos ---
  for (const o of state.objetivos || []) {
    if (o.prazo && o.prazo < hoje && Number(o.acumulado || 0) < Number(o.alvo || 0)) {
      add("atencao", "Objetivo \"" + o.nome + "\" com prazo vencido", "Acumulado " + fmt(o.acumulado) + " de " + fmt(o.alvo) + " até " + o.prazo.split("-").reverse().join("/") + ". Redefina o prazo ou o aporte mensal.");
    }
  }
  return out;
}

const DIAG_NIVEIS = {
  alerta:  { icon: "🚨", label: "Alerta" },
  atencao: { icon: "⚠️", label: "Atenção" },
  ok:      { icon: "✅", label: "Em ordem" },
  insight: { icon: "💡", label: "Insight" },
};

function RelatorioPage({ state, year, month = 0 }) {
  const [atualizadoEm, setAtualizadoEm] = React.useState(() => new Date());
  const [flash, setFlash] = React.useState(false);
  function atualizar() {
    setAtualizadoEm(new Date());
    setFlash(true);
    setTimeout(() => setFlash(false), 1200);
  }
  const p = state.patrimonio;
  const fam = state.familia;
  const tot = window.patrimonioTotais(p, state.dividas);
  const suc = window.calcSucessao(state);
  const saldosClasse = window.saldosPorClasse(p.saldos);
  const fmt = window.fmtBRLString;
  const mesLabel = window.MESES_FULL[month] + "/" + year;

  const plano = window.computePlano(state.transactions, state.aggregates, year, month);
  const classesMes = window.byClasse(window.txByMonth(state.transactions, year, month));
  const totalClasses = classesMes.reduce((s, c) => s + c.value, 0);
  const custo = window.custoFixoDetalhe(state.transactions, 3, (state.reserva || {}).base || "todos");
  const saldosReserva = (p.saldos || []).filter(s => s.reserva);
  const reservaSaldo = state.reserva && state.reserva.saldoManual != null ? state.reserva.saldoManual : saldosReserva.reduce((s, x) => s + Number(x.valor || 0), 0);
  const mesesAlvo = (state.reserva || {}).mesesAlvo || 6;
  const apos = window.calcAposentadoria(state.aposentadoria, tot.financeiro);
  const diag = gerarDiagnostico(state, year, month);
  const DIAG_ORDEM = { alerta: 0, atencao: 1, insight: 2, ok: 3 };
  const diagOrdenado = [...diag].sort((a, b) => DIAG_ORDEM[a.nivel] - DIAG_ORDEM[b.nivel]);
  const diagCriticos = diagOrdenado.filter(d => d.nivel === "alerta");
  const diagResto = diagOrdenado.filter(d => d.nivel !== "alerta");

  const catItems = [
    { label: "Imóveis", valor: tot.imoveis, color: "#311131" },
    { label: "Veículos", valor: tot.veiculos, color: "#0663AA" },
    { label: "Participações societárias", valor: tot.participacoes, color: "#7fb8e0" },
    { label: "Saldos e Investimentos", valor: tot.financeiro, color: "#EA404D" },
    { label: "Outros bens", valor: tot.outros, color: "#bcdcf3" },
  ];
  const maxCat = Math.max(...catItems.map(c => c.valor), 1);

  function Sec({ title, scope, explain, children }) {
    return (
      <section className="rel-sec">
        <div className="rel-sec-head">
          <h3>{title}</h3>
          {scope && <span className="rel-scope">{scope}</span>}
        </div>
        {explain && <p className="rel-explain">{explain}</p>}
        {children}
      </section>
    );
  }

  return (
    <div className="page rel-page" data-screen-label="Relatório">
      <div className="page-head no-print">
        <div><h2>📄 Relatório</h2><span className="page-hint">Diagnóstico financeiro, patrimonial e sucessório — pronto para imprimir/salvar em PDF.</span></div>
        <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
          {flash && <span className="rel-flash">✓ Relatório atualizado</span>}
          <button className="btn-green" onClick={atualizar}>🔄 Atualizar relatório</button>
          <button className="btn-ghost" onClick={() => window.print()}>🖨️ Imprimir / PDF</button>
        </div>
      </div>

      <div className="rel-doc">
        {/* Capa */}
        <div className="rel-capa">
          <h1>Relatório</h1>
          <p className="rel-sub">Diagnóstico Financeiro, Patrimonial e Familiar · {mesLabel}</p>
          <p className="rel-stamp">Gerado com os dados de {atualizadoEm.toLocaleDateString("pt-BR")} às {atualizadoEm.toLocaleTimeString("pt-BR", { hour: "2-digit", minute: "2-digit" })} — o relatório reflete automaticamente tudo que foi lançado no app.</p>
          <div className="rel-hr"></div>
          <h4>Informações do cliente</h4>
          <div className="rel-info-grid">
            <div><span>Nome completo do cliente</span><strong>{fam.cliente.nome}</strong></div>
            <div><span>Data de nascimento</span><strong>{fam.cliente.nascimento ? fam.cliente.nascimento.split("-").reverse().join("/") : "—"}</strong></div>
            <div><span>E-mail</span><strong>{fam.cliente.email || "—"}</strong></div>
            <div><span>Estado civil</span><strong>{fam.cliente.estadoCivil || "—"}</strong></div>
            <div><span>Nome do(a) cônjuge</span><strong>{fam.conjuge?.nome || "—"}</strong></div>
            <div><span>Nascimento do(a) cônjuge</span><strong>{fam.conjuge?.nascimento ? fam.conjuge.nascimento.split("-").reverse().join("/") : "—"}</strong></div>
            <div><span>Regime de bens</span><strong>{fam.cliente.regimeBens || "—"}</strong></div>
          </div>
        </div>

        <Sec title="Diagnóstico do consultor" explain="Leitura automática dos seus dados, do mais crítico ao menos crítico: alertas primeiro, depois pontos de atenção e, por fim, insights e itens em ordem.">
          {diagCriticos.length > 0 && (
            <div className="rel-diag-crit">
              {diagCriticos.map((d, i) => (
                <div className="rel-diag-line d-alerta" key={i}>
                  <span className="rel-diag-icon">{DIAG_NIVEIS[d.nivel].icon}</span>
                  <strong>{d.titulo}</strong>
                  <span className="rel-diag-line-txt">{d.texto}</span>
                </div>
              ))}
            </div>
          )}
          <div className="rel-diag">
            {diagResto.map((d, i) => (
              <div className={`rel-diag-item d-${d.nivel}`} key={i}>
                <span className="rel-diag-icon">{DIAG_NIVEIS[d.nivel].icon}</span>
                <div><strong>{d.titulo}</strong><p>{d.texto}</p></div>
              </div>
            ))}
            {diag.length === 0 && <p className="rel-empty">Sem dados suficientes para o diagnóstico. Lance receitas e gastos no Checklist.</p>}
          </div>
        </Sec>

        <Sec title={"Orçamento do mês · " + mesLabel} explain="O plano 70·10·10·10 divide a receita em: até 70% para o custo de vida, 10% caridade, 10% capital ativo (projetos) e 10% capital passivo (investimentos).">
          <div className="rel-kpi-row">
            <div className="rel-kpi big"><span>Receita do mês</span><strong>{fmt(plano.income)}</strong></div>
          </div>
          <div className="rel-bars">
            {plano.buckets.map(b => (
              <div className="rel-bar-row" key={b.key}>
                <span>{b.icon} {b.label} ({Math.round(b.pct * 100)}%)</span>
                <div className="rel-bar-track">
                  <div style={{ width: Math.min(b.target > 0 ? (b.used / b.target) * 100 : 0, 100) + "%", background: b.over ? "#EA404D" : "#0663AA" }}></div>
                </div>
                <strong className={b.over ? "rel-neg" : ""}>{fmt(b.used)} <em className="rel-de">de {fmt(b.target)}</em></strong>
              </div>
            ))}
          </div>
          {totalClasses > 0 && (
            <table className="rel-table">
              <thead><tr><th>Gastos por classe</th><th>Valor</th><th>% do total</th></tr></thead>
              <tbody>
                {classesMes.map(c => (
                  <tr key={c.id}><td>{c.icon} {c.label}</td><td>{fmt(c.value)}</td><td>{Math.round((c.value / totalClasses) * 100)}%</td></tr>
                ))}
              </tbody>
            </table>
          )}
        </Sec>

        <Sec title="Estrutura familiar" scope="Casal">
          <div className="rel-fam">
            <div className="rel-fam-node"><span>Cliente</span><strong>{fam.cliente.nome}</strong><em>{window.idade(fam.cliente.nascimento) != null ? window.idade(fam.cliente.nascimento) + " anos" : ""}</em></div>
            {fam.conjuge?.nome && <div className="rel-fam-node"><span>Cônjuge</span><strong>{fam.conjuge.nome}</strong><em>{window.idade(fam.conjuge.nascimento) != null ? window.idade(fam.conjuge.nascimento) + " anos" : ""}</em></div>}
            {(fam.filhos || []).map((f, i) => (
              <div className="rel-fam-node child" key={i}><span>Filho(a)</span><strong>{f.nome}</strong><em>{window.idade(f.nascimento) != null ? window.idade(f.nascimento) + " anos" : ""}</em></div>
            ))}
          </div>
        </Sec>

        <Sec title="Patrimônio" scope="Casal" explain="Visão consolidada dos bens do casal por categoria e por titularidade. O patrimônio líquido desconta as dívidas em aberto.">
          <div className="rel-kpi-row">
            <div className="rel-kpi big"><span>Patrimônio total</span><strong>{fmt(tot.total)}</strong>
              <em>Comum {fmt(tot.porTitularidade.Comum)} · Cliente {fmt(tot.porTitularidade.Cliente)} · Cônjuge {fmt(tot.porTitularidade["Cônjuge"])}</em>
            </div>
            <div className="rel-kpi big"><span>Patrimônio líquido</span><strong>{fmt(tot.liquido)}</strong><em>descontadas dívidas de {fmt(tot.totalDividas)}</em></div>
          </div>
          <div className="rel-bars">
            {catItems.map(c => (
              <div className="rel-bar-row" key={c.label}>
                <span>{c.label}</span>
                <div className="rel-bar-track"><div style={{ width: (c.valor / maxCat) * 100 + "%", background: c.color }}></div></div>
                <strong>{fmt(c.valor)}</strong>
              </div>
            ))}
          </div>
          <div className="rel-kpi-row">
            <div className="rel-kpi"><span>Patrimônio não financeiro</span><strong>{fmt(tot.naoFinanceiro)}</strong>
              <em>{p.imoveis.length} imóveis · {p.veiculos.length} veículos · {p.participacoes.length} participações · {p.outros.length} outros</em>
            </div>
            <div className="rel-kpi"><span>Patrimônio financeiro</span><strong>{fmt(tot.financeiro)}</strong>
              <em>{p.saldos.length} saldos e investimentos</em>
            </div>
          </div>
          {saldosClasse.length > 0 && (
            <table className="rel-table">
              <thead><tr><th>Saldos e Investimentos</th><th>Valor</th></tr></thead>
              <tbody>
                {saldosClasse.map(s => <tr key={s.classe}><td>{s.classe}</td><td>{fmt(s.valor)}</td></tr>)}
              </tbody>
            </table>
          )}
          <div className="rel-kpi-row">
            <div className="rel-kpi"><span>Patrimônio livre de inventário</span><strong>{fmt(tot.previdencia)}</strong><em>Previdência</em></div>
            <div className="rel-kpi"><span>Bens com restrições</span><strong>{fmt(tot.comRestricao)}</strong></div>
            <div className="rel-kpi"><span>Dívida total</span><strong>{fmt(tot.totalDividas)}</strong></div>
          </div>
        </Sec>

        <Sec title="Dívidas" scope="Casal" explain="Passivos em aberto, com saldo devedor e situação de negociação.">
          {(state.dividas || []).length > 0 ? (
            <table className="rel-table">
              <thead><tr><th>Descrição</th><th>Credor</th><th>Saldo devedor</th><th>Vencimento</th><th>Status</th></tr></thead>
              <tbody>
                {state.dividas.map(d => (
                  <tr key={d.id}><td>{d.descricao}</td><td>{d.credor || "—"}</td><td>{fmt(d.saldoDevedor)}</td><td>{d.vencimento ? d.vencimento.split("-").reverse().join("/") : "—"}</td><td>{d.status}</td></tr>
                ))}
              </tbody>
            </table>
          ) : <p className="rel-empty">Nenhuma dívida cadastrada.</p>}
        </Sec>

        <Sec title="Proteção" scope="Família" explain="Seguros contratados. A referência didática para seguro de vida é um capital entre 3 e 5 anos do custo anual da família.">
          {(state.seguros || []).length > 0 ? (
            <table className="rel-table">
              <thead><tr><th>Tipo</th><th>Apólice</th><th>Seguradora</th><th>Capital</th><th>Prêmio/mês</th><th>Vigência</th></tr></thead>
              <tbody>
                {state.seguros.map(s => (
                  <tr key={s.id}><td>{s.tipo}</td><td>{s.nome}</td><td>{s.seguradora || "—"}</td><td>{fmt(s.capital)}</td><td>{fmt(s.premioMensal)}</td><td>{s.vigencia ? s.vigencia.split("-").reverse().join("/") : "—"}</td></tr>
                ))}
              </tbody>
            </table>
          ) : <p className="rel-empty">Nenhum seguro cadastrado.</p>}
        </Sec>

        <Sec title="Reserva de emergência" scope="Família" explain={"Colchão de liquidez para imprevistos, dimensionado em meses do custo mensal (média dos últimos meses lançados: " + fmt(custo.media) + ")."}>
          <div className="rel-kpi-row">
            <div className="rel-kpi"><span>Reserva atual</span><strong>{fmt(reservaSaldo)}</strong></div>
            <div className="rel-kpi"><span>Alvo ({mesesAlvo} meses)</span><strong>{fmt(custo.media * mesesAlvo)}</strong></div>
            <div className="rel-kpi"><span>Meses cobertos</span><strong>{custo.media > 0 ? (reservaSaldo / custo.media).toFixed(1) : "—"}</strong></div>
            <div className="rel-kpi"><span>{custo.media * mesesAlvo - reservaSaldo > 0 ? "Faltam" : "Excedente"}</span><strong>{fmt(Math.abs(custo.media * mesesAlvo - reservaSaldo))}</strong></div>
          </div>
          {custo.media > 0 && (
            <div className="rel-res-bar-wrap">
              <div className="rel-res-bar">
                <div className="rel-res-fill" style={{ width: Math.min(reservaSaldo / (custo.media * mesesAlvo), 1) * 100 + "%" }}></div>
                {[...Array(mesesAlvo)].map((_, i) => (
                  <span className="rel-res-tick" key={i} style={{ left: ((i + 1) / mesesAlvo) * 100 + "%" }}></span>
                ))}
              </div>
              <div className="rel-res-legend">
                <span>{(reservaSaldo / custo.media).toFixed(1)} de {mesesAlvo} meses de custo cobertos</span>
                <span>{Math.round(Math.min(reservaSaldo / (custo.media * mesesAlvo), 1) * 100)}% do alvo</span>
              </div>
            </div>
          )}
          {custo.porClasse.length > 0 && (
            <table className="rel-table">
              <thead><tr><th>Custo mensal por classe (média)</th><th>Valor</th></tr></thead>
              <tbody>
                {custo.porClasse.map(c => (
                  <tr key={c.id}><td>{c.icon} {c.label}</td><td>{fmt(c.valor)}</td></tr>
                ))}
                <tr><td><strong>Total</strong></td><td><strong>{fmt(custo.media)}</strong></td></tr>
              </tbody>
            </table>
          )}
          {saldosReserva.length > 0 ? (
            <table className="rel-table">
              <thead><tr><th>Ativos que compõem a reserva</th><th>Classe</th><th>Instituição</th><th>Valor</th></tr></thead>
              <tbody>
                {saldosReserva.map(s => (
                  <tr key={s.id}><td>{s.nome}</td><td>{s.classe}</td><td>{s.instituicao || "—"}</td><td>{fmt(window.valorBRL(s))}</td></tr>
                ))}
              </tbody>
            </table>
          ) : <p className="rel-empty">Nenhum ativo marcado como reserva de emergência.</p>}
        </Sec>

        <Sec title="Aposentadoria" scope="Cliente" explain={"Projeção pela regra do capital perpétuo: o alvo é o capital cujo rendimento real (" + (state.aposentadoria.taxaRealAA || 4) + "% a.a.) paga a renda desejada sem consumir o principal."}>
          <div className="rel-kpi-row">
            <div className="rel-kpi"><span>Renda desejada</span><strong>{fmt(state.aposentadoria.rendaMensalDesejada)}/mês</strong><em>aos {state.aposentadoria.idadeAlvo} anos</em></div>
            <div className="rel-kpi"><span>Capital alvo</span><strong>{window.fmtCompact(apos.alvo)}</strong></div>
            <div className="rel-kpi"><span>Projeção atual</span><strong>{window.fmtCompact(apos.projecao)}</strong><em>com aporte de {fmt(state.aposentadoria.aporteMensal)}/mês</em></div>
            <div className="rel-kpi"><span>Aporte necessário</span><strong>{fmt(apos.aporteNecessario)}/mês</strong></div>
          </div>
        </Sec>

        <Sec title="Objetivos" scope="Família">
          {(state.objetivos || []).length > 0 ? (
            <table className="rel-table">
              <thead><tr><th>Objetivo</th><th>Acumulado</th><th>Alvo</th><th>Progresso</th><th>Prazo</th></tr></thead>
              <tbody>
                {state.objetivos.map(o => (
                  <tr key={o.id}><td>{o.icone} {o.nome}</td><td>{fmt(o.acumulado)}</td><td>{fmt(o.alvo)}</td><td>{o.alvo > 0 ? Math.round((o.acumulado / o.alvo) * 100) : 0}%</td><td>{o.prazo ? o.prazo.split("-").reverse().join("/") : "—"}</td></tr>
                ))}
              </tbody>
            </table>
          ) : <p className="rel-empty">Nenhum objetivo cadastrado.</p>}
        </Sec>

        <Sec title="Participações societárias" scope="Cliente">
          {p.participacoes.length > 0 ? (
            <table className="rel-table">
              <thead><tr><th>Entidade</th><th>CNPJ</th><th>%</th><th>Capital social</th><th>Valor patrimonial</th></tr></thead>
              <tbody>
                {p.participacoes.map(e => (
                  <tr key={e.id}><td>{e.nome}</td><td>{e.cnpj || "—"}</td><td>{e.pct}%</td><td>{fmt(e.capitalSocial)}</td><td>{fmt(e.valorPatrimonial)}</td></tr>
                ))}
              </tbody>
            </table>
          ) : <p className="rel-empty">Nenhuma participação societária.</p>}
        </Sec>

        <Sec title="Sucessão — Composição dos custos" scope="Cliente" explain="Estimativa do custo de transmitir o patrimônio nas duas vias possíveis. O extrajudicial (cartório) é mais rápido e barato, mas exige consenso entre herdeiros maiores e capazes.">
          <div className="rel-kpi-row">
            <div className="rel-kpi"><span>Inventário Extrajudicial</span><strong>{fmt(suc.custoExtrajudicial)}</strong>
              <em>Registro {fmt(suc.registro)} · Escritura {fmt(suc.escritura)} · ITCMD {fmt(suc.itcmd)} · Honorários {fmt(suc.honorariosExtra)}</em>
            </div>
            <div className="rel-kpi"><span>Inventário Judicial</span><strong>{fmt(suc.custoJudicial)}</strong>
              <em>Registro {fmt(suc.registro)} · Custas {fmt(suc.custasJudiciais)} · ITCMD {fmt(suc.itcmd)} · Honorários {fmt(suc.honorariosJud)}</em>
            </div>
          </div>
          <p className="rel-note">*O valor do honorário é sugerido conforme a recomendação da tabela OAB de cada estado.</p>
        </Sec>

        <Sec title="ITCMD" scope="Cliente" explain={"Imposto estadual sobre a herança. " + suc.notaRegime + " Previdência é isenta. Alíquota configurável — com a reforma tributária (EC 132/2023) o ITCMD será progressivo; confirme a tabela vigente do seu estado."}>
          <div className="rel-info-grid">
            <div><span>Patrimônio transmissível</span><strong>{fmt(suc.transmissivel)}</strong></div>
            <div><span>Meação</span><strong>{fmt(suc.meacao)}</strong></div>
            <div><span>Previdência isenta</span><strong>{fmt(suc.previdenciaIsenta)}</strong></div>
            <div><span>Valor tributável</span><strong>{fmt(suc.valorTributavel)}</strong></div>
            <div><span>ITCMD estimado ({suc.estado})</span><strong>{fmt(suc.itcmd)}</strong></div>
            <div><span>Alíquota média</span><strong>{suc.aliquota}%</strong></div>
          </div>
        </Sec>

        <Sec title="Partilha" scope="Cliente" explain={"Regime de bens: " + suc.regime + ". " + suc.notaRegime}>
          <div className="rel-kpi-row">
            <div className="rel-kpi"><span>Total</span><strong>{fmt(suc.transmissivel)}</strong></div>
            <div className="rel-kpi"><span>Meação</span><strong>{suc.meacao > 0 ? fmt(suc.meacao) : "— (sem meação)"}</strong></div>
            <div className="rel-kpi"><span>Herança</span><strong>{fmt(suc.heranca)}</strong></div>
            <div className="rel-kpi"><span>Legítima</span><strong>{fmt(suc.legitima)}</strong></div>
            {suc.quinhaoConjuge > 0 && <div className="rel-kpi"><span>Quinhão do cônjuge (herança)</span><strong>{fmt(suc.quinhaoConjuge)}</strong></div>}
          </div>
          <div className="rel-partilha-bar">
            <div style={{ width: suc.transmissivel > 0 ? (suc.meacao / suc.transmissivel) * 100 + "%" : "50%", background: "#311131" }}></div>
            <div style={{ width: suc.transmissivel > 0 ? (suc.heranca / suc.transmissivel) * 100 + "%" : "50%", background: "#EA404D" }}></div>
          </div>
          <div className="rel-partilha-legend">
            <span><i style={{ background: "#311131" }}></i> Meação {suc.transmissivel > 0 ? Math.round((suc.meacao / suc.transmissivel) * 100) : 0}%</span>
            <span><i style={{ background: "#EA404D" }}></i> Herança {suc.transmissivel > 0 ? Math.round((suc.heranca / suc.transmissivel) * 100) : 0}%</span>
          </div>
        </Sec>

        <Sec title="Herdeiros e partilhas" scope="Cliente">
          <div className="rel-herd">
            {suc.herdeiros.map((h, i) => (
              <div className="rel-herd-card" key={i}>
                <span className="rel-herd-role">{h.papel}</span>
                <strong>{h.nome}</strong>
                <em>{h.composicao}</em>
                <div className="rel-herd-val">{window.fmtCompact(h.valor)}</div>
                <span className="rel-herd-pct">{suc.transmissivel > 0 ? ((h.valor / suc.transmissivel) * 100).toFixed(0) : 0}% do transmissível</span>
              </div>
            ))}
          </div>
          <p className="rel-note">*Partilha simulada para o falecimento do cliente, conforme o regime de bens ({suc.regime}) — CC arts. 1.829 e 1.832. Estimativa didática; não substitui aconselhamento jurídico.</p>
        </Sec>

        <Sec title="Aviso Legal">
          <p className="rel-legal">
            Este estudo é dirigido exclusivamente ao destinatário indicado na capa e pode conter informações confidenciais.
            Seu propósito é fornecer informações para auxiliar o destinatário no planejamento financeiro, patrimonial e sucessório.
            As informações pessoais são fornecidas pelo destinatário levando em consideração seus dados cadastrais, familiares e
            patrimoniais, bem como suas necessidades financeiras e objetivos pessoais. O relatório tem natureza informativa e
            orientadora, e não deve ser interpretado como aconselhamento jurídico ou financeiro. Não nos responsabilizamos por
            decisões de investimento ou quaisquer decisões pessoais tomadas com base nas informações apresentadas neste relatório.
          </p>
        </Sec>
      </div>
    </div>
  );
}

Object.assign(window, { RelatorioPage, gerarDiagnostico });
