"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { TrendingUp, Scale, Save, Target, ChevronDown, Check, Timer } from "lucide-react";
import { PageHeader } from "@/components/ui/page-header";
import { Button } from "@/components/ui/button";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { usePermissoes } from "@/lib/permissoes-do-usuario";
import { InfoTooltip } from "@/components/ui/info-tooltip";
import { formatarDuracao } from "@/lib/orders/ficha-de-producao";
import type { Expediente } from "@/lib/orders/expediente";
import type { CapacidadeDaFila } from "@/lib/precificacao/tempo-de-producao";
import type { FilaDeProducao, PrevistoXReal } from "@/lib/precificacao/tempo-de-producao.server";

/**
 * O Ponto de Equilíbrio em duas abas, na organização consagrada do ramo.
 *
 * MÊS ATUAL: a linha de três blocos (Vendido | anel | MC + Lucro), depois
 * QUANTO VENDER — os três PEs em cartões com barra de progresso —, o ranking
 * ABC numa tabela só (Cliente | Vendedor no toque) e o caminho do lucro: a
 * curva do acumulado cruzando a linha do fixo, com as duas zonas ditas na
 * cara ("pagando a casa" | "lucro"), o dia do cruzamento marcado e o valor
 * de cada dia no passar do mouse.
 *
 * OUTROS MESES: a trajetória em tabela — e o chevron expande o dashboard
 * completo daquele mês, com o custo fixo FOTOGRAFADO na virada.
 *
 * A margem de referência dos PEs usa os últimos 90 dias — amostra estável,
 * sem seletor para errar. Alertas operacionais (estoque, custo velho) moram
 * no hub da precificação, não aqui: esta tela é o placar do mês.
 */

type LinhaABC = {
  nome: string; receita: number; cm: number; lucro: number | null; pedidos: number;
  classe: "A" | "B" | "C"; participacaoPct: number;
};

type MesBloco = {
  competencia: string; fechado: boolean; diaAtual: number; diasNoMes: number;
  pedidos: number; receita: number; cm: number; fixoDoMes: number; coberturaPct: number;
  progressoPct: number; lucroAtual: number; bateu: boolean; diasRestantes: number;
  cmNecessariaAteHoje: number; emRitmo: boolean; mcPctDoMes: number;
  faturamentoParaEquilibrio: number | null; metaVendaAteHoje: number | null;
  previsaoCm: number; previsaoLucro: number; previsaoVenda: number;
  metaDoComercial: number | null; metaDoComercialAteHoje: number | null;
  metaDoComercialEmRitmo: boolean | null;
  porDia: { dia: number; receita: number; cm: number }[];
  rankingClientes: LinhaABC[]; rankingVendedores: LinhaABC[];
};

type Saude = {
  periodo: { dias: number };
  vendas: {
    pedidos: number; receita: number; custoDireto: number; materiaPrima: number;
    maoDeObra: number; variaveisPct: number;
    variaveisValor: number; margemContribuicao: number; mcPct: number;
    cobertura: { comCustoPct: number; congeladaPct: number };
  };
  mes: MesBloco;
  outrosMeses: MesBloco[];
  porProduto: { id: string; nome: string; receita: number; materiais: number | null; margemPct: number | null }[];
  porCategoria: { nome: string; receita: number; margemPct: number | null }[];
  equilibrio: {
    fixoMensal: number; mesesComLancamento: number; depreciacaoMensal: number;
    lucroDesejado: number; mcPct: number;
    contabil: number | null; financeiro: number | null; economico: number | null;
    receitaMensalizada: number;
  };
  capacidade: {
    horasDisponiveisMes: number; horasUsadasPeriodo: number;
    coberturaFichaPct: number; horasNoEquilibrio: number | null;
  };
  /* A ficha confrontada com a bancada, e a fila contra o mês. */
  tempo?: {
    previstoXReal: PrevistoXReal;
    fila: FilaDeProducao;
    capacidade: CapacidadeDaFila;
    expediente: Expediente;
    erro: string | null;
  } | null;
};

const dinheiro = (v: number) =>
  new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(v || 0);
const qtd = (v: number) =>
  new Intl.NumberFormat("pt-BR", { maximumFractionDigits: 2 }).format(v || 0);

const MESES = ["janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"];
const nomeDaCompetencia = (competencia: string) => {
  const [ano, mes] = competencia.split("-");
  const nome = MESES[Number(mes) - 1] ?? competencia;
  return `${nome.charAt(0).toUpperCase()}${nome.slice(1)} · ${ano}`;
};
const soOMes = (competencia: string) => {
  const nome = MESES[Number(competencia.split("-")[1]) - 1] ?? competencia;
  return nome.charAt(0).toUpperCase() + nome.slice(1);
};

/* A margem de referência dos PEs: 90 dias fechados numa amostra estável. */
const JANELA_DIAS = 90;

export default function SaudeDaPrecificacaoPage() {
  const { pode } = usePermissoes();
  const podeEditar = pode("pricing.health.write");

  const [aba, setAba] = useState<"atual" | "outros">("atual");
  const [dados, setDados] = useState<Saude | null>(null);
  const [carregando, setCarregando] = useState(true);
  const [lucro, setLucro] = useState("");
  const [meta, setMeta] = useState("");
  const [salvandoMetas, setSalvandoMetas] = useState(false);

  const carregar = useCallback(async () => {
    setCarregando(true);
    try {
      const r = await fetch(`/api/precificacao/saude?dias=${JANELA_DIAS}`, { cache: "no-store" });
      const j = (await r.json()) as Saude;
      if (r.ok) {
        setDados(j);
        setLucro(j.equilibrio.lucroDesejado > 0 ? String(j.equilibrio.lucroDesejado).replace(".", ",") : "");
        setMeta(j.mes.metaDoComercial ? String(j.mes.metaDoComercial).replace(".", ",") : "");
      }
    } finally {
      setCarregando(false);
    }
  }, []);

  useEffect(() => { void carregar(); }, [carregar]);

  const salvarMetas = async () => {
    setSalvandoMetas(true);
    try {
      await fetch("/api/precificacao/saude", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          lucro_desejado: Number(lucro.replace(/\./g, "").replace(",", ".")) || 0,
          meta_de_vendas: Number(meta.replace(/\./g, "").replace(",", ".")) || 0,
        }),
      });
      await carregar();
    } finally {
      setSalvandoMetas(false);
    }
  };

  if (carregando && !dados) {
    return <PageHeader eyebrow="Financeiro" title="Ponto de Equilíbrio" subtitle="Carregando…" />;
  }
  if (!dados) {
    return <PageHeader eyebrow="Financeiro" title="Ponto de Equilíbrio" subtitle="Não foi possível carregar." />;
  }

  const v = dados.vendas;
  const e = dados.equilibrio;
  const m = dados.mes;
  const cap = dados.capacidade;
  const temFixo = e.fixoMensal > 0;

  return (
    <div className="space-y-4">
      <PageHeader
        eyebrow="Financeiro"
        title="Ponto de Equilíbrio"
        subtitle="Quanto do mês já pagou a casa — e quando começa o lucro"
      />

      {/* As duas abas, como o ramo organiza: o mês em curso e a trajetória —
          no MESMO estilo sublinhado da Personalização da vitrine. */}
      <AbasSublinhadas
        valor={aba}
        aoMudar={(v) => setAba(v as "atual" | "outros")}
        abas={[
          { valor: "atual", rotulo: "Mês atual" },
          { valor: "outros", rotulo: "Outros meses" },
        ]}
      />

      {aba === "atual" ? (
        <div className="space-y-4">
          <CardsDoMes m={m} temFixo={temFixo} />

          {!temFixo && (
            <p className="text-center text-sm text-[var(--ks-color-text-muted)]">
              Cadastre os custos fixos em Financeiro → Contas a Pagar → Custos fixos e o anel liga sozinho.
            </p>
          )}
          {temFixo && m.receita > 0 && m.coberturaPct < 100 && (
            <p className="text-center text-[11px] text-[var(--ks-color-text-soft)]">
              {m.coberturaPct.toFixed(0)}% da receita do mês tem custo conhecido — a fatia sem custo
              entra na MC pelo valor cheio.
            </p>
          )}

          <QuantoVenderPorMes e={e} cap={cap} />

          {dados.tempo ? <TempoDaProducao t={dados.tempo} /> : null}

          <RankingCard m={m} />

          {temFixo && (
            <section className="ks-surface rounded-2xl p-5 border border-[var(--ks-color-border-subtle)]">
              <div className="flex items-start gap-3 mb-3">
                <span className="ks-tile ks-tile-sm shrink-0" style={{ background: "var(--ks-color-primary)" }}>
                  <TrendingUp size={18} />
                </span>
                <div>
                  <h2 className="ks-section-title inline-flex items-center">
                    Primeiro a casa, depois o lucro
                    <InfoTooltip text="A MC acumulada, dia a dia. Na zona de baixo, cada venda paga contas; no dia em que a curva cruza a linha do custo fixo, o mês bateu o PE — dali em diante é a zona do lucro. Passe o mouse para ver o acumulado de cada dia." />
                  </h2>
                  <p className="ks-section-hint mt-0.5">MC acumulada × custo fixo, dia a dia</p>
                </div>
              </div>
              <CaminhoDoLucro porDia={m.porDia} fixo={m.fixoDoMes} diasNoMes={m.diasNoMes}
                              diaAtual={m.diaAtual} fechado={m.fechado} />
            </section>
          )}

          <div className="grid grid-cols-1 xl:grid-cols-[1fr_320px] gap-4 items-start">
            {/* MC por produto */}
            <section className="ks-surface rounded-2xl p-5 border border-[var(--ks-color-border-subtle)]">
              <div className="flex items-start gap-3 mb-3">
                <span className="ks-tile ks-tile-sm shrink-0" style={{ background: "var(--ks-emerald)" }}>
                  <TrendingUp size={18} />
                </span>
                <h2 className="ks-section-title inline-flex items-center">
                  MC por produto
                  <InfoTooltip text={`Contribuição de cada produto nos últimos ${JANELA_DIAS} dias: receita menos matéria-prima e menos os ${v.variaveisPct.toFixed(1)}% de impostos e taxas. ${v.cobertura.comCustoPct.toFixed(0)}% da receita tem custo conhecido — ${v.cobertura.congeladaPct.toFixed(0)}% congelado na venda, o resto do cadastro atual.`} />
                </h2>
              </div>
              {dados.porProduto.length === 0 ? (
                <p className="text-sm text-[var(--ks-color-text-muted)]">Sem vendas no período.</p>
              ) : (
                <div className="overflow-x-auto">
                  <table className="w-full text-xs border-separate border-spacing-y-1">
                    <thead>
                      <tr className="text-left text-[10px] uppercase tracking-wide text-[var(--ks-color-text-soft)]">
                        <th className="font-medium py-1">Produto</th>
                        <th className="font-medium py-1 text-right">Receita</th>
                        <th className="font-medium py-1 text-right">MC</th>
                      </tr>
                    </thead>
                    <tbody>
                      {dados.porProduto.slice(0, 8).map((p) => (
                        <tr key={p.id} className="bg-[var(--ks-color-bg-inset)]">
                          <td className="py-2 px-2 rounded-l-lg max-w-[240px] truncate">{p.nome}</td>
                          <td className="py-2 px-2 text-right whitespace-nowrap">{dinheiro(p.receita)}</td>
                          <td className="py-2 px-2 rounded-r-lg text-right font-semibold whitespace-nowrap"
                              style={{ color: p.margemPct == null
                                ? "var(--ks-color-text-soft)"
                                : p.margemPct < 0 ? "var(--ks-color-status-danger)"
                                : p.margemPct < 15 ? "var(--ks-color-status-warning)" : "var(--ks-color-text-primary)" }}>
                            {p.margemPct == null ? "sem custo" : `${p.margemPct.toFixed(1)}%`}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
              {dados.porCategoria.length > 1 && (
                <div className="mt-3 flex flex-wrap gap-1.5">
                  {dados.porCategoria.map((c) => (
                    <span key={c.nome} className="text-[11px] px-2.5 py-1 rounded-full bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-muted)]">
                      {c.nome}: {c.margemPct == null ? "sem custo" : `${c.margemPct.toFixed(0)}%`}
                    </span>
                  ))}
                </div>
              )}
            </section>

            {/* Metas do mês */}
            {podeEditar && (
              <div className="ks-surface rounded-2xl p-4 border border-[var(--ks-color-border-subtle)]">
                <div className="flex items-center gap-2 text-xs font-semibold text-[var(--ks-color-text-soft)] mb-3">
                  <Target size={14} /> Metas do mês
                </div>
                <div className="space-y-3">
                  <div className="space-y-1">
                    <label className="text-[11px] text-[var(--ks-color-text-soft)] inline-flex items-center">
                      Meta de vendas do comercial
                      <InfoTooltip text="A régua da gestão: quanto o time deve vender no mês. O bloco Vendido compara com o proporcional do dia. Em branco, a referência é o faturamento do PE." />
                    </label>
                    <input inputMode="decimal" value={meta} onChange={(ev) => setMeta(ev.target.value)}
                           placeholder={m.faturamentoParaEquilibrio != null ? `PE: ${dinheiro(m.faturamentoParaEquilibrio)}` : "Ex: 30.000"}
                           className="ks-field w-full" />
                  </div>
                  <div className="space-y-1">
                    <label className="text-[11px] text-[var(--ks-color-text-soft)] inline-flex items-center">
                      Lucro desejado por mês
                      <InfoTooltip text="Define o PE econômico — a meta de verdade, porque empatar não é objetivo de ninguém." />
                    </label>
                    <input inputMode="decimal" value={lucro} onChange={(ev) => setLucro(ev.target.value)}
                           placeholder="Ex: 5.000" className="ks-field w-full" />
                  </div>
                  <Button onClick={() => void salvarMetas()} disabled={salvandoMetas}
                          icon={<Save size={14} />} className="w-full justify-center">
                    {salvandoMetas ? "Salvando…" : "Salvar metas"}
                  </Button>
                </div>
              </div>
            )}
          </div>
        </div>
      ) : (
        <OutrosMeses meses={dados.outrosMeses} />
      )}
    </div>
  );
}

/* ------------------------------------------------------------------------- */

/* O estilo de aba da casa: sublinhado, como na Personalização da vitrine. O
   componente é compartilhado, então o restyle entra por className (o cn do
   projeto usa twMerge, que resolve o conflito de classes). */
const CLASSE_DA_ABA =
  "rounded-none border-b-2 border-transparent bg-transparent px-1 pb-3 pt-1 font-medium text-[var(--ks-color-text-soft)] shadow-none data-[state=active]:border-[var(--ks-color-primary)] data-[state=active]:bg-transparent data-[state=active]:text-[var(--ks-color-primary)] data-[state=active]:shadow-none";

function AbasSublinhadas({ valor, aoMudar, abas, compacta }: {
  valor: string;
  aoMudar: (v: string) => void;
  abas: { valor: string; rotulo: string }[];
  compacta?: boolean;
}) {
  return (
    <Tabs value={valor} onValueChange={aoMudar} className="w-full">
      <TabsList className="h-auto w-full justify-start gap-1 rounded-none border-b border-[var(--ks-color-border-subtle)] bg-transparent p-0">
        {abas.map((a, i) => (
          <TabsTrigger
            key={a.valor}
            value={a.valor}
            className={`${CLASSE_DA_ABA}${i > 0 ? " ml-5" : ""}${compacta ? " text-xs pb-2" : ""}`}
          >
            {a.rotulo}
          </TabsTrigger>
        ))}
      </TabsList>
    </Tabs>
  );
}

/**
 * Quanto vender por mês: os três PEs em cartões com barra de progresso —
 * cada um com sua cor, seu porquê e o quanto do caminho a receita do
 * trimestre já cobre.
 */
/* A ficha contra a bancada. A precificação chuta minutos e eles viram custo;
   aqui o tempo real volta para dizer se o chute está certo — e a fila diz
   quanto do mês já está comprometido. */
function TempoDaProducao({ t }: { t: NonNullable<Saude["tempo"]> }) {
  const c = t.capacidade;
  const px = t.previstoXReal;
  const cob = px.cobertura;
  const dataBr = (iso: string) => {
    const [a, m, d] = iso.split("-");
    return `${d}/${m}/${a}`;
  };
  const rotuloDaSituacao: Record<string, string> = {
    subestimado: "ficha subestima",
    superestimado: "ficha superestima",
    ok: "ficha acerta",
    poucos_dados: "poucos pedidos",
  };
  const corDaRazao = (p: PrevistoXReal["porProduto"][number]) =>
    p.situacao === "poucos_dados"
      ? "var(--ks-color-text-soft)"
      : p.situacao === "subestimado"
        ? "var(--ks-color-status-danger)"
        : p.situacao === "superestimado"
          ? "var(--ks-color-status-warning)"
          : "var(--ks-color-text-primary)";
  const estoura = c.ocupacaoDoMesPct != null && c.ocupacaoDoMesPct > 100;

  return (
    <section className="ks-surface rounded-2xl p-5 border border-[var(--ks-color-border-subtle)]">
      <div className="flex items-start gap-3 mb-4">
        <span className="ks-tile ks-tile-sm shrink-0" style={{ background: "var(--ks-sky)" }}>
          <Timer size={18} />
        </span>
        <div>
          <h2 className="ks-section-title inline-flex items-center">
            Tempo previsto × real
            <InfoTooltip text={`Os minutos da ficha viram custo de máquina, de gente e a fatia de custo fixo pelo tempo. Aqui o tempo medido na bancada volta para conferir a ficha: por apontamento de item quando existe, senão pelo cronômetro do pedido dentro do expediente, rateado entre os itens. Razão acima de 1,5 em 3 ou mais pedidos: a ficha subestima e o preço nasce baixo. A fila soma o previsto de tudo que ainda não saiu da produção contra as horas produtivas do mês.`} />
          </h2>
          <p className="ks-section-hint mt-0.5">
            {cob.pedidosComReal} pedidos com tempo medido nos últimos {JANELA_DIAS} dias · {cob.porApontamento} por apontamento, {cob.porCronometro} pelo cronômetro
            {cob.aproximados > 0 ? ` · ${cob.aproximados} itens com histórico aproximado` : ""}
          </p>
        </div>
      </div>

      <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
        <MedidaDeTempo rotulo="Fila prevista" valor={formatarDuracao(t.fila.minutosPrevistos)}
                       sub={`${t.fila.aguardando} aguardando · ${t.fila.emProducao} em produção`} />
        <MedidaDeTempo rotulo="Capacidade do mês" valor={c.horasMes ? `${qtd(c.horasMes)} h` : "—"}
                       sub={c.horasPorDiaUtil ? `${qtd(c.horasPorDiaUtil)} h por dia útil · ${c.diasUteisNoMes} dias` : "horas produtivas não informadas"} />
        <MedidaDeTempo rotulo="Ocupação do mês" valor={c.ocupacaoDoMesPct != null ? `${c.ocupacaoDoMesPct.toFixed(0)}%` : "—"}
                       sub={c.diasUteisNecessarios != null ? `${c.diasUteisNecessarios} ${c.diasUteisNecessarios === 1 ? "dia útil" : "dias úteis"} de fila` : ""}
                       cor={estoura ? "var(--ks-color-status-danger)" : undefined} />
        <MedidaDeTempo rotulo="Próximo prazo livre" valor={c.prazoSugerido ? dataBr(c.prazoSugerido) : "—"}
                       sub={c.prazoSugerido ? "no ritmo da capacidade" : ""} />
      </div>
      {!c.horasMes && (
        <p className="mt-3 text-xs text-[var(--ks-color-text-muted)]">
          Informe as horas produtivas do mês em{" "}
          <a href="/dashboard/financial/payables?tab=custos-fixos" className="font-semibold text-[var(--ks-color-primary)] underline">
            Financeiro → Custos fixos
          </a>{" "}
          para ver ocupação e prazo. É o mesmo número que alimenta a hora da estrutura nos preços.
        </p>
      )}
      {t.fila.itensSemFicha > 0 && (
        <p className="mt-1 text-[11px] text-[var(--ks-color-text-soft)]">
          {t.fila.itensSemFicha} itens da fila não têm ficha técnica e ficam fora do tempo.
        </p>
      )}

      <div className="mt-4 pt-4 border-t border-[var(--ks-color-border-subtle)]">
        {px.porProduto.length === 0 ? (
          <p className="text-sm text-[var(--ks-color-text-muted)]">
            Nenhum tempo real medido ainda. Aponte os itens no kanban de produção, ou deixe o cronômetro correr: o tempo útil dentro do expediente entra aqui quando o pedido é finalizado.
          </p>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-xs border-separate border-spacing-y-1">
              <thead>
                <tr className="text-left text-[10px] uppercase tracking-wide text-[var(--ks-color-text-soft)]">
                  <th className="font-medium py-1">Produto</th>
                  <th className="font-medium py-1 text-right">Pedidos</th>
                  <th className="font-medium py-1 text-right">Previsto</th>
                  <th className="font-medium py-1 text-right">Real</th>
                  <th className="font-medium py-1 text-right">Razão</th>
                  <th className="font-medium py-1">Ficha</th>
                </tr>
              </thead>
              <tbody>
                {px.porProduto.slice(0, 12).map((p) => (
                  <tr key={p.productId} className="bg-[var(--ks-color-bg-inset)]">
                    <td className="py-2 px-2 rounded-l-lg max-w-[240px] truncate">
                      <a href={`/dashboard/products/${p.productId}`} className="hover:underline">{p.nome}</a>
                      {p.fonte === "cronometro" ? <span className="ml-1 text-[10px] text-[var(--ks-color-text-soft)]">cronômetro</span> : null}
                      {p.aproximados > 0 ? <span className="ml-1 text-[10px] text-[var(--ks-color-text-soft)]">~</span> : null}
                    </td>
                    <td className="py-2 px-2 text-right whitespace-nowrap">{p.pedidos}</td>
                    <td className="py-2 px-2 text-right whitespace-nowrap">{formatarDuracao(p.previstoMin)}</td>
                    <td className="py-2 px-2 text-right whitespace-nowrap">{formatarDuracao(p.realMin)}</td>
                    <td className="py-2 px-2 text-right font-semibold whitespace-nowrap" style={{ color: corDaRazao(p) }}>
                      {p.razao.toFixed(2).replace(".", ",")}×
                    </td>
                    <td className="py-2 px-2 rounded-r-lg whitespace-nowrap" style={{ color: corDaRazao(p) }}>
                      {rotuloDaSituacao[p.situacao]}
                      {p.sugestaoFator != null ? (
                        <span className="ml-1 font-semibold">· ×{p.sugestaoFator.toFixed(2).replace(".", ",")} nos minutos</span>
                      ) : null}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </section>
  );
}

function MedidaDeTempo({ rotulo, valor, sub, cor }: { rotulo: string; valor: string; sub?: string; cor?: string }) {
  return (
    <div className="rounded-xl bg-[var(--ks-color-bg-inset)] px-3 py-2.5">
      <div className="text-[10px] uppercase tracking-wide text-[var(--ks-color-text-soft)]">{rotulo}</div>
      <div className="mt-0.5 text-lg font-bold" style={{ color: cor ?? "var(--ks-color-text-primary)" }}>{valor}</div>
      {sub ? <div className="text-[11px] text-[var(--ks-color-text-muted)]">{sub}</div> : null}
    </div>
  );
}

function QuantoVenderPorMes({ e, cap }: {
  e: Saude["equilibrio"]; cap: Saude["capacidade"];
}) {
  const capacidadeEstoura =
    cap.horasNoEquilibrio != null && cap.horasDisponiveisMes > 0 && cap.horasNoEquilibrio > cap.horasDisponiveisMes;
  const acima = e.contabil != null && e.receitaMensalizada >= e.contabil;

  return (
    <section className="ks-surface rounded-2xl p-5 border border-[var(--ks-color-border-subtle)]">
      <div className="flex items-start gap-3 mb-4">
        <span className="ks-tile ks-tile-sm shrink-0" style={{ background: "var(--ks-color-primary)" }}>
          <Scale size={18} />
        </span>
        <div>
          <h2 className="ks-section-title inline-flex items-center">
            Quanto vender por mês
            <InfoTooltip text={`Com a MC média de ${e.mcPct.toFixed(1)}% dos últimos ${JANELA_DIAS} dias, cada R$ 100 vendidos deixam ${dinheiro(e.mcPct)} para os custos fixos. O PE é o custo fixo dividido por essa margem — três versões, para três perguntas. A barra mostra quanto do caminho o ritmo atual já cobre.`} />
          </h2>
          <p className="ks-section-hint mt-0.5">
            No ritmo atual, o mês fecha em <strong className="text-[var(--ks-color-text-primary)]">{dinheiro(e.receitaMensalizada)}</strong>
            {e.contabil != null && (
              acima
                ? <span className="text-[var(--ks-color-status-success,#059669)]"> — {dinheiro(e.receitaMensalizada - (e.contabil ?? 0))} acima do PE contábil</span>
                : <span className="text-[var(--ks-color-status-danger)]"> — faltam {dinheiro((e.contabil ?? 0) - e.receitaMensalizada)} para o PE contábil</span>
            )}
          </p>
        </div>
      </div>

      {e.contabil == null ? (
        <p className="text-sm text-[var(--ks-color-text-muted)] py-2">
          {e.fixoMensal <= 0
            ? "Cadastre os custos fixos para ver o ponto de equilíbrio."
            : "Sem MC positiva no período não existe PE — nenhum volume de venda paga as contas."}
        </p>
      ) : (
        <>
          <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
            <MetaDeVenda cor="var(--ks-color-primary)" titulo="PE contábil" valor={e.contabil}
                         receita={e.receitaMensalizada} explica="Cobre todas as contas do mês. Abaixo disto, prejuízo." />
            <MetaDeVenda cor="var(--ks-sky)" titulo="PE financeiro" valor={e.financeiro}
                         receita={e.receitaMensalizada}
                         explica={e.depreciacaoMensal > 0
                           ? `Só o que sai do caixa — sem ${dinheiro(e.depreciacaoMensal)} de depreciação.`
                           : "Igual ao contábil: sem depreciação cadastrada."} />
            <MetaDeVenda cor="var(--ks-emerald)" titulo="PE econômico" valor={e.economico}
                         receita={e.receitaMensalizada}
                         explica={e.lucroDesejado > 0
                           ? `Contas pagas e ${dinheiro(e.lucroDesejado)} de lucro no bolso.`
                           : "Defina abaixo quanto quer que sobre."} />
          </div>
          {cap.horasDisponiveisMes > 0 && cap.horasNoEquilibrio != null && (
            <p className="mt-3 pt-3 border-t border-[var(--ks-color-border-subtle)] text-xs text-[var(--ks-color-text-muted)]">
              Vender o PE contábil pede{" "}
              <strong className={capacidadeEstoura ? "text-[var(--ks-color-status-danger)]" : "text-[var(--ks-color-text-primary)]"}>
                {qtd(cap.horasNoEquilibrio)} h de máquina
              </strong>{" "}
              das {qtd(cap.horasDisponiveisMes)} h que existem —
              {capacidadeEstoura
                ? " não cabe: ou o preço sobe, ou o fixo desce, ou entra máquina."
                : ` cabe, com folga de ${qtd(cap.horasDisponiveisMes - cap.horasNoEquilibrio)} h.`}
            </p>
          )}
        </>
      )}
    </section>
  );
}

function MetaDeVenda({ cor, titulo, valor, receita, explica }: {
  cor: string; titulo: string; valor: number | null; receita: number; explica: string;
}) {
  const pct = valor && valor > 0 ? Math.min(100, (receita / valor) * 100) : 0;
  const bateu = valor != null && valor > 0 && receita >= valor;
  return (
    <div className="rounded-2xl bg-[var(--ks-color-bg-inset)] p-4 border-l-4" style={{ borderLeftColor: cor }}>
      <div className="flex items-center justify-between gap-2">
        <span className="text-[10px] uppercase tracking-wide font-bold text-[var(--ks-color-text-soft)]">{titulo}</span>
        {bateu && (
          <span className="inline-flex h-4.5 items-center gap-1 rounded-full px-1.5 text-[9px] font-black text-white"
                style={{ background: "var(--ks-emerald)" }}>
            <Check size={10} /> BATIDO
          </span>
        )}
      </div>
      <div className="text-[22px] font-black text-[var(--ks-color-text-primary)] mt-1 leading-tight">
        {valor == null ? "—" : dinheiro(valor)}
      </div>
      <div className="mt-2.5 flex items-center gap-2">
        <div className="flex-1 h-2.5 rounded-full bg-[var(--ks-color-bg-hover)] overflow-hidden">
          <div className="h-full rounded-full transition-all duration-700"
               style={{ width: `${pct}%`, background: bateu ? "var(--ks-emerald)" : cor }} />
        </div>
        <span className="text-[10px] font-bold shrink-0"
              style={{ color: bateu ? "var(--ks-emerald,#059669)" : "var(--ks-color-text-soft)" }}>
          {valor == null ? "" : `${pct.toFixed(0)}%`}
        </span>
      </div>
      <div className="text-[10px] text-[var(--ks-color-text-soft)] mt-2 leading-snug">{explica}</div>
    </div>
  );
}

/**
 * A linha de três blocos do mês, na organização do ramo: Vendido | anel |
 * MC + Lucro. O anel fica no centro, grande e sem moldura — os vizinhos é
 * que moram em cartões.
 */
function CardsDoMes({ m, temFixo }: { m: MesBloco; temFixo: boolean }) {
  const corDaMeta = m.fechado
    ? "var(--ks-color-text-primary)"
    : m.metaDoComercialEmRitmo == null
      ? "var(--ks-color-text-primary)"
      : m.metaDoComercialEmRitmo ? "var(--ks-emerald,#059669)" : "var(--ks-color-status-danger)";
  const metaAteHoje = m.metaDoComercialAteHoje ?? m.metaVendaAteHoje;

  return (
    <div className="grid grid-cols-1 xl:grid-cols-[1fr_auto_1.35fr] items-stretch gap-4">
      {/* Vendido */}
      <section className="order-2 xl:order-1 ks-surface rounded-2xl p-5 border border-[var(--ks-color-border-subtle)] flex flex-col justify-center">
        <div className="flex items-center justify-between">
          <span className="text-xs font-semibold text-[var(--ks-color-text-soft)]">Vendido</span>
          <span className="text-[9px] font-bold uppercase px-2 py-0.5 rounded-full bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-soft)]">
            {soOMes(m.competencia)}
          </span>
        </div>
        <div className="mt-3 space-y-3 text-right">
          <div>
            <div className="text-3xl font-black leading-none" style={{ color: corDaMeta }}>
              {dinheiro(m.receita)}
            </div>
            <div className="text-[10px] text-[var(--ks-color-text-soft)] mt-1">
              {m.fechado ? "valor vendido" : "aprovado até hoje"} · {m.pedidos} {m.pedidos === 1 ? "pedido" : "pedidos"}
            </div>
          </div>
          {!m.fechado && metaAteHoje != null && (
            <div>
              <div className="text-lg font-bold text-[var(--ks-color-text-primary)] leading-none">
                {dinheiro(metaAteHoje)}
              </div>
              <div className="text-[10px] text-[var(--ks-color-text-soft)] mt-1 inline-flex items-center">
                <span>meta até hoje</span>
                <InfoTooltip text={m.metaDoComercial
                  ? `O proporcional do dia ${m.diaAtual} da meta de ${dinheiro(m.metaDoComercial)} definida pela gestão.`
                  : "Sem meta do comercial definida, a referência é o proporcional do faturamento que bate o PE."} />
              </div>
            </div>
          )}
          {m.faturamentoParaEquilibrio != null && (
            <div>
              <div className="text-lg font-bold text-[var(--ks-color-text-primary)] leading-none">
                {dinheiro(m.faturamentoParaEquilibrio)}
              </div>
              <div className="text-[10px] text-[var(--ks-color-text-soft)] mt-1 inline-flex items-center">
                <span>faturamento p/ PE</span>
                <InfoTooltip text="Custo fixo ÷ MC média deste mês — recalcula a cada venda: venda cheia de matéria-prima contribui menos e empurra este número para cima." />
              </div>
            </div>
          )}
        </div>
      </section>

      {/* O anel, sem moldura */}
      <div className="order-1 xl:order-2 flex flex-col items-center justify-center">
        <AnelDoEquilibrio progressoPct={m.progressoPct} bateu={m.bateu} temFixo={temFixo} />
        <div className="mt-1.5 text-sm font-semibold text-[var(--ks-color-text-primary)]">
          {nomeDaCompetencia(m.competencia)}
        </div>
        <div className="text-[11px] text-[var(--ks-color-text-soft)]">
          {m.fechado
            ? "mês fechado"
            : `dia ${m.diaAtual} de ${m.diasNoMes}${m.diasRestantes > 0 ? ` · faltam ${m.diasRestantes} dias` : " · último dia"}`}
        </div>
      </div>

      {/* MC + Lucro */}
      <section className="order-3 ks-surface rounded-2xl border border-[var(--ks-color-border-subtle)] flex flex-col">
        <div className="p-5 pb-4 flex-1">
          <div className="text-xs font-semibold text-[var(--ks-color-text-soft)] inline-flex items-center">
            Contribuição marginal (MC)
            <InfoTooltip text="O que as vendas devolvem para pagar as contas: receita menos matéria-prima e menos impostos e taxas. A mão de obra fica dentro — é custo fixo sendo recuperado. Quando o acumulado cruza o custo fixo, o mês bateu o PE." />
          </div>
          <div className="mt-2 grid grid-cols-2 sm:grid-cols-4 gap-3">
            <div>
              <div className="text-[10px] text-[var(--ks-color-text-soft)]">{m.fechado ? "No mês" : "Hoje"}</div>
              <div className="text-base font-black leading-tight"
                   style={{ color: m.fechado || m.emRitmo ? "var(--ks-emerald,#059669)" : "var(--ks-color-status-danger)" }}>
                {dinheiro(m.cm)}
              </div>
              <div className="text-[10px] text-[var(--ks-color-text-soft)]">{m.mcPctDoMes.toFixed(1)}% da venda</div>
            </div>
            {!m.fechado && (
              <div>
                <div className="text-[10px] text-[var(--ks-color-text-soft)]">Necessário até hoje</div>
                <div className="text-base font-bold text-[var(--ks-color-text-primary)] leading-tight">
                  {dinheiro(m.cmNecessariaAteHoje)}
                </div>
              </div>
            )}
            <div>
              <div className="text-[10px] text-[var(--ks-color-text-soft)]">Custo fixo</div>
              <div className="text-base font-bold text-[var(--ks-color-text-primary)] leading-tight">
                {dinheiro(m.fixoDoMes)}
              </div>
            </div>
            {!m.fechado && (
              <div>
                <div className="text-[10px] text-[var(--ks-color-text-soft)]">Dias restantes</div>
                <div className="text-base font-bold text-[var(--ks-color-text-primary)] leading-tight">
                  {m.diasRestantes} {m.diasRestantes === 1 ? "dia" : "dias"}
                </div>
              </div>
            )}
          </div>
        </div>
        <div className="p-5 pt-4 border-t border-[var(--ks-color-border-subtle)] flex-1">
          <div className="text-xs font-semibold text-[var(--ks-color-text-soft)] inline-flex items-center">
            Lucro
            <InfoTooltip text="MC acumulada menos o custo fixo. Negativo é o que ainda falta para pagar a casa; positivo é lucro de verdade. A previsão extrapola o ritmo dos dias corridos." />
          </div>
          <div className="mt-2 grid grid-cols-2 sm:grid-cols-4 gap-3">
            <div>
              <div className="text-[10px] text-[var(--ks-color-text-soft)]">{m.fechado ? "Lucro final" : "Atual"}</div>
              <div className="text-base font-black leading-tight"
                   style={{ color: m.lucroAtual >= 0 ? "var(--ks-emerald,#059669)" : "var(--ks-color-status-danger)" }}>
                {dinheiro(m.lucroAtual)}
              </div>
              {m.receita > 0 && (
                <div className="text-[10px] text-[var(--ks-color-text-soft)]">
                  {((m.lucroAtual / m.receita) * 100).toFixed(1)}% da venda
                </div>
              )}
            </div>
            {!m.fechado && (
              <>
                <div>
                  <div className="text-[10px] text-[var(--ks-color-text-soft)]">Previsão de lucro</div>
                  <div className="text-base font-bold leading-tight"
                       style={{ color: m.previsaoLucro >= 0 ? "var(--ks-emerald,#059669)" : "var(--ks-color-status-danger)" }}>
                    {dinheiro(m.previsaoLucro)}
                  </div>
                </div>
                <div>
                  <div className="text-[10px] text-[var(--ks-color-text-soft)]">Previsão de vendas</div>
                  <div className="text-base font-bold text-[var(--ks-color-text-primary)] leading-tight">
                    {dinheiro(m.previsaoVenda)}
                  </div>
                </div>
              </>
            )}
            <div>
              <div className="text-[10px] text-[var(--ks-color-text-soft)]">Meta de vendas</div>
              <div className="text-base font-bold text-[var(--ks-color-text-primary)] leading-tight">
                {m.metaDoComercial != null ? dinheiro(m.metaDoComercial) : "—"}
              </div>
            </div>
          </div>
        </div>
      </section>
    </div>
  );
}

/** O ranking ABC numa tabela só, com o toque Cliente | Vendedor do ramo. */
function RankingCard({ m }: { m: MesBloco }) {
  const [visao, setVisao] = useState<"clientes" | "vendedores">("clientes");
  const linhas = visao === "clientes" ? m.rankingClientes : m.rankingVendedores;
  if (m.rankingClientes.length === 0 && m.rankingVendedores.length === 0) return null;

  const COR_DA_CLASSE: Record<LinhaABC["classe"], string> = {
    A: "var(--ks-emerald)",
    B: "var(--ks-amber)",
    C: "var(--ks-color-text-soft)",
  };
  const totalVendido = linhas.reduce((acc, l) => acc + l.receita, 0);
  const totalCm = linhas.reduce((acc, l) => acc + l.cm, 0);
  const lucroCompleto = linhas.length > 0 && linhas.every((l) => l.lucro != null);
  const totalLucro = linhas.reduce((acc, l) => acc + (l.lucro ?? 0), 0);

  return (
    <section className="ks-surface rounded-2xl p-5 border border-[var(--ks-color-border-subtle)]">
      <div className="mb-3 space-y-2">
        <h2 className="ks-section-title inline-flex items-center">
          Ranking ABC de vendas
          <span className="ml-2 text-[9px] font-bold uppercase px-2 py-0.5 rounded-full bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-soft)]">
            {soOMes(m.competencia)}
          </span>
          <InfoTooltip text="Ordenado pela CONTRIBUIÇÃO (MC), não pela receita: pedido caro só de matéria-prima ajuda menos que um menor cheio de mão de obra. Nota A concentra 80% da MC do mês, B vai até 95%, C é o resto. Ranking é a fatia da receita; Lucro desconta o custo INTEIRO e os variáveis ('—' quando falta custo)." />
        </h2>
        <AbasSublinhadas
          compacta
          valor={visao}
          aoMudar={(v) => setVisao(v as "clientes" | "vendedores")}
          abas={[
            { valor: "clientes", rotulo: "Cliente" },
            { valor: "vendedores", rotulo: "Vendedor" },
          ]}
        />
      </div>

      {linhas.length === 0 ? (
        <p className="text-sm text-[var(--ks-color-text-muted)]">Sem vendas neste mês.</p>
      ) : (
        <div className="overflow-x-auto">
          <table className="w-full text-xs border-separate border-spacing-y-1 min-w-[640px]">
            <thead>
              <tr className="text-left text-[10px] uppercase tracking-wide text-[var(--ks-color-text-soft)]">
                <th className="font-medium py-0.5">{visao === "clientes" ? "Cliente" : "Vendedor"}</th>
                <th className="font-medium py-0.5 text-right">Valor vendido</th>
                <th className="font-medium py-0.5 text-right">Contrib. marginal</th>
                <th className="font-medium py-0.5 text-right">Pedidos</th>
                <th className="font-medium py-0.5 text-right">Lucro</th>
                <th className="font-medium py-0.5 text-right">% de lucro</th>
                <th className="font-medium py-0.5 text-right">Ranking</th>
                <th className="font-medium py-0.5 text-center w-12">Nota</th>
              </tr>
            </thead>
            <tbody>
              {linhas.map((l, i) => (
                <tr key={`${l.nome}-${i}`} className="bg-[var(--ks-color-bg-inset)]">
                  <td className="py-2 px-2 rounded-l-lg max-w-[190px] truncate font-medium text-[var(--ks-color-text-primary)]">
                    {l.nome}
                  </td>
                  <td className="py-2 px-2 text-right whitespace-nowrap">{dinheiro(l.receita)}</td>
                  <td className="py-2 px-2 text-right whitespace-nowrap font-semibold"
                      style={{ color: l.cm < 0 ? "var(--ks-color-status-danger)" : "var(--ks-color-text-primary)" }}>
                    {dinheiro(l.cm)}
                  </td>
                  <td className="py-2 px-2 text-right">{l.pedidos}</td>
                  <td className="py-2 px-2 text-right whitespace-nowrap font-semibold"
                      style={{ color: l.lucro == null
                        ? "var(--ks-color-text-soft)"
                        : l.lucro < 0 ? "var(--ks-color-status-danger)" : "var(--ks-emerald,#059669)" }}>
                    {l.lucro == null ? "—" : dinheiro(l.lucro)}
                  </td>
                  <td className="py-2 px-2 text-right text-[var(--ks-color-text-muted)]">
                    {l.lucro == null || l.receita <= 0 ? "—" : `${((l.lucro / l.receita) * 100).toFixed(1)}%`}
                  </td>
                  <td className="py-2 px-2 text-right text-[var(--ks-color-text-muted)]">
                    {totalVendido > 0 ? `${((l.receita / totalVendido) * 100).toFixed(1)}%` : "—"}
                  </td>
                  <td className="py-2 px-2 rounded-r-lg text-center">
                    <span className="inline-flex h-5 w-5 items-center justify-center rounded-full text-[10px] font-black text-white"
                          style={{ background: COR_DA_CLASSE[l.classe] }}>
                      {l.classe}
                    </span>
                  </td>
                </tr>
              ))}
            </tbody>
            <tfoot>
              <tr className="text-[11px] font-bold text-[var(--ks-color-text-primary)]">
                <td className="pt-1.5 px-2">Total</td>
                <td className="pt-1.5 px-2 text-right whitespace-nowrap">{dinheiro(totalVendido)}</td>
                <td className="pt-1.5 px-2 text-right whitespace-nowrap">{dinheiro(totalCm)}</td>
                <td className="pt-1.5 px-2 text-right">{linhas.reduce((acc, l) => acc + l.pedidos, 0)}</td>
                <td className="pt-1.5 px-2 text-right whitespace-nowrap"
                    style={{ color: !lucroCompleto ? "var(--ks-color-text-soft)" : totalLucro < 0 ? "var(--ks-color-status-danger)" : "var(--ks-emerald,#059669)" }}>
                  {lucroCompleto ? dinheiro(totalLucro) : "—"}
                </td>
                <td className="pt-1.5 px-2 text-right text-[var(--ks-color-text-muted)]">
                  {lucroCompleto && totalVendido > 0 ? `${((totalLucro / totalVendido) * 100).toFixed(1)}%` : "—"}
                </td>
                <td />
                <td />
              </tr>
            </tfoot>
          </table>
        </div>
      )}
    </section>
  );
}

/** A aba Outros Meses: a tabela da trajetória, e o chevron abre o dashboard
 *  completo do mês — os mesmos blocos do mês atual, congelados no último dia. */
function OutrosMeses({ meses }: { meses: MesBloco[] }) {
  const [expandido, setExpandido] = useState<string | null>(null);

  if (meses.length === 0) {
    return (
      <p className="text-sm text-[var(--ks-color-text-muted)] py-6 text-center">
        Nenhum mês anterior com vendas ainda — a trajetória nasce na primeira virada.
      </p>
    );
  }

  return (
    <section className="ks-surface rounded-2xl p-5 border border-[var(--ks-color-border-subtle)]">
      <h2 className="ks-section-title inline-flex items-center mb-3">
        Ponto de equilíbrio dos meses anteriores
        <InfoTooltip text="Cada mês com o custo fixo FOTOGRAFADO na virada — o lucro de um mês fechado nunca mais muda. Meses fechados antes da fotografia existir herdaram o fixo de hoje, uma única vez. O chevron abre o dashboard completo do mês." />
      </h2>
      <div className="overflow-x-auto">
        <table className="w-full text-xs border-separate border-spacing-y-1 min-w-[680px]">
          <thead>
            <tr className="text-left text-[10px] uppercase tracking-wide text-[var(--ks-color-text-soft)]">
              <th className="font-medium py-0.5">Mês</th>
              <th className="font-medium py-0.5 text-right">Valor vendido</th>
              <th className="font-medium py-0.5 text-right">Contrib. marginal</th>
              <th className="font-medium py-0.5 text-right">Pedidos</th>
              <th className="font-medium py-0.5 text-right">Lucro</th>
              <th className="font-medium py-0.5 text-right">% de lucro</th>
              <th className="font-medium py-0.5 text-right">Custo fixo</th>
              <th className="w-9" />
            </tr>
          </thead>
          <tbody>
            {meses.map((mes) => {
              const aberto = expandido === mes.competencia;
              return (
                <FragmentoDoMes
                  key={mes.competencia}
                  mes={mes}
                  aberto={aberto}
                  aoAlternar={() => setExpandido(aberto ? null : mes.competencia)}
                />
              );
            })}
          </tbody>
        </table>
      </div>
    </section>
  );
}

function FragmentoDoMes({ mes, aberto, aoAlternar }: {
  mes: MesBloco; aberto: boolean; aoAlternar: () => void;
}) {
  return (
    <>
      <tr className="bg-[var(--ks-color-bg-inset)] cursor-pointer hover:opacity-90" onClick={aoAlternar}>
        <td className="py-2.5 px-2 rounded-l-lg font-semibold text-[var(--ks-color-text-primary)] whitespace-nowrap">
          {nomeDaCompetencia(mes.competencia)}
        </td>
        <td className="py-2.5 px-2 text-right whitespace-nowrap">{dinheiro(mes.receita)}</td>
        <td className="py-2.5 px-2 text-right whitespace-nowrap">{dinheiro(mes.cm)}</td>
        <td className="py-2.5 px-2 text-right">{mes.pedidos}</td>
        <td className="py-2.5 px-2 text-right whitespace-nowrap font-semibold"
            style={{ color: mes.lucroAtual >= 0 ? "var(--ks-emerald,#059669)" : "var(--ks-color-status-danger)" }}>
          {dinheiro(mes.lucroAtual)}
        </td>
        <td className="py-2.5 px-2 text-right text-[var(--ks-color-text-muted)]">
          {mes.receita > 0 ? `${((mes.lucroAtual / mes.receita) * 100).toFixed(1)}%` : "—"}
        </td>
        <td className="py-2.5 px-2 text-right whitespace-nowrap text-[var(--ks-color-text-muted)]">
          {dinheiro(mes.fixoDoMes)}
        </td>
        <td className="py-2.5 px-2 rounded-r-lg text-center">
          <ChevronDown size={14}
                       className="inline text-[var(--ks-color-text-soft)] transition-transform"
                       style={{ transform: aberto ? "rotate(180deg)" : "none" }} />
        </td>
      </tr>
      {aberto && (
        <tr>
          <td colSpan={8} className="pt-3 pb-4">
            <div className="space-y-4">
              <CardsDoMes m={mes} temFixo={mes.fixoDoMes > 0} />
              {mes.porDia.length > 0 && mes.fixoDoMes > 0 && (
                <div className="ks-surface rounded-2xl p-5 border border-[var(--ks-color-border-subtle)]">
                  <div className="text-xs font-semibold text-[var(--ks-color-text-soft)] mb-2">
                    Primeiro a casa, depois o lucro
                  </div>
                  <CaminhoDoLucro porDia={mes.porDia} fixo={mes.fixoDoMes}
                                  diasNoMes={mes.diasNoMes} diaAtual={mes.diaAtual} fechado={mes.fechado} />
                </div>
              )}
              <RankingCard m={mes} />
            </div>
          </td>
        </tr>
      )}
    </>
  );
}

/**
 * O anel do equilíbrio. Uma volta cheia = custo fixo pago; ele NÃO morre nos
 * 100% — a segunda volta, em verde, é o lucro correndo por cima (um mês de
 * 180% mostra o anel cheio e mais 80% de verde, como um relógio passando do
 * meio-dia).
 */
function AnelDoEquilibrio({ progressoPct, bateu, temFixo }: {
  progressoPct: number; bateu: boolean; temFixo: boolean;
}) {
  const tamanho = 218;
  const raio = 92;
  const espessura = 16;
  const circunferencia = 2 * Math.PI * raio;
  const pct = temFixo ? Math.max(0, progressoPct) : 0;
  const volta1 = Math.min(100, pct);
  const volta2 = Math.min(100, Math.max(0, pct - 100));

  const arco = (fracaoPct: number) =>
    `${(circunferencia * fracaoPct) / 100} ${circunferencia}`;

  return (
    <div className="relative" style={{ width: tamanho, height: tamanho }}>
      <svg width={tamanho} height={tamanho} viewBox={`0 0 ${tamanho} ${tamanho}`} role="img"
           aria-label={temFixo ? `${pct.toFixed(1)}% do custo fixo pago` : "sem custo fixo cadastrado"}>
        <g transform={`rotate(-90 ${tamanho / 2} ${tamanho / 2})`}>
          <circle cx={tamanho / 2} cy={tamanho / 2} r={raio} fill="none"
                  stroke="var(--ks-color-bg-hover)" strokeWidth={espessura} />
          {volta1 > 0 && (
            <circle cx={tamanho / 2} cy={tamanho / 2} r={raio} fill="none"
                    stroke={bateu ? "var(--ks-emerald)" : "var(--ks-color-primary)"}
                    strokeWidth={espessura} strokeLinecap="round"
                    strokeDasharray={arco(volta1)}
                    style={{ transition: "stroke-dasharray 0.6s ease" }} />
          )}
          {/* A segunda volta: o lucro por cima da volta cheia. Mais fina, para
              a volta de baixo continuar visível — duas voltas, duas camadas. */}
          {volta2 > 0 && (
            <circle cx={tamanho / 2} cy={tamanho / 2} r={raio} fill="none"
                    stroke="var(--ks-color-status-success, #059669)"
                    strokeWidth={espessura * 0.55} strokeLinecap="round"
                    strokeDasharray={arco(volta2)}
                    style={{ transition: "stroke-dasharray 0.6s ease" }} />
          )}
        </g>
      </svg>
      <div className="absolute inset-0 flex flex-col items-center justify-center">
        <div className="text-4xl font-black leading-none"
             style={{ color: !temFixo
               ? "var(--ks-color-text-soft)"
               : bateu ? "var(--ks-emerald,#059669)" : "var(--ks-color-text-primary)" }}>
          {temFixo ? `${pct >= 100 ? pct.toFixed(0) : pct.toFixed(1)}%` : "—"}
        </div>
        <div className="text-[10px] uppercase tracking-[0.14em] text-[var(--ks-color-text-soft)] mt-1.5">
          do fixo pago
        </div>
        {bateu && (
          <div className="text-[10px] font-bold text-[var(--ks-emerald,#059669)] mt-0.5">
            lucrando
          </div>
        )}
      </div>
    </div>
  );
}

/**
 * O caminho até o lucro — o gráfico que conta a história sozinho.
 *
 * Duas zonas ditas na cara: embaixo da linha do fixo, "pagando a casa";
 * acima, "lucro". A curva do acumulado é suave e anima ao entrar; o dia em
 * que ela cruza a linha ganha um marcador ("bateu o PE"); e o mouse percorre
 * os dias com um cursor que mostra a venda e o acumulado de cada um.
 */
function CaminhoDoLucro({ porDia, fixo, diasNoMes, diaAtual, fechado }: {
  porDia: { dia: number; receita: number; cm: number }[];
  fixo: number; diasNoMes: number; diaAtual: number; fechado: boolean;
}) {
  const svgRef = useRef<SVGSVGElement>(null);
  const linhaRef = useRef<SVGPathElement>(null);
  const [hoverDia, setHoverDia] = useState<number | null>(null);
  const [desenhado, setDesenhado] = useState(false);
  const [comprimento, setComprimento] = useState(0);

  useEffect(() => {
    /* A curva entra desenhando-se: mede o traço e libera o dash. */
    const total = linhaRef.current?.getTotalLength() ?? 0;
    setComprimento(total);
    const t = setTimeout(() => setDesenhado(true), 60);
    return () => clearTimeout(t);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [porDia.length, fixo]);

  if (porDia.length === 0) {
    return (
      <p className="text-sm text-[var(--ks-color-text-muted)] py-4">
        Sem vendas neste mês ainda — a curva nasce na primeira venda.
      </p>
    );
  }

  const W = 720;
  const H = 230;
  const PAD_E = 52;
  const PAD_D = 16;
  const PAD_T = 26;
  const PAD_B = 26;

  /* A série por dia, 0..hoje, com o acumulado carregado adiante — é ela que o
     cursor percorre. */
  const cmDoDia = new Map(porDia.map((d) => [d.dia, d.cm]));
  const vendaDoDia = new Map(porDia.map((d) => [d.dia, d.receita]));
  const fimDaSerie = Math.max(diaAtual, porDia[porDia.length - 1]?.dia ?? 1);
  const serie: { dia: number; acumulado: number }[] = [];
  let soma = 0;
  for (let dia = 0; dia <= fimDaSerie; dia++) {
    soma += cmDoDia.get(dia) ?? 0;
    serie.push({ dia, acumulado: soma });
  }
  const acumuladoFinal = soma;

  const maxY = Math.max(fixo, acumuladoFinal) * 1.18;
  const x = (dia: number) => PAD_E + (dia / diasNoMes) * (W - PAD_E - PAD_D);
  const y = (valor: number) => PAD_T + (1 - Math.max(0, valor) / maxY) * (H - PAD_T - PAD_B);
  const yFixo = y(fixo);
  const yBase = y(0);

  /* Só os dias com venda viram vértice — a curva anda reta nos dias parados,
     que é a verdade deles. */
  const vertices = [{ dia: 0, acumulado: 0 }, ...serie.filter((p) => p.dia > 0 && cmDoDia.has(p.dia))];
  if (vertices[vertices.length - 1].dia < fimDaSerie) {
    vertices.push({ dia: fimDaSerie, acumulado: acumuladoFinal });
  }
  const pontos = vertices.map((p) => ({ px: x(p.dia), py: y(p.acumulado) }));

  /* Curva Catmull-Rom → Bézier, com tensão baixa para não inventar vale. */
  const caminhoDaLinha = pontos.length < 2
    ? ""
    : pontos.map((p, i) => {
        if (i === 0) return `M${p.px.toFixed(1)},${p.py.toFixed(1)}`;
        const p0 = pontos[i - 2] ?? pontos[i - 1];
        const p1 = pontos[i - 1];
        const p2 = p;
        const p3 = pontos[i + 1] ?? p;
        const c1x = p1.px + (p2.px - p0.px) / 8;
        const c1y = p1.py + (p2.py - p0.py) / 8;
        const c2x = p2.px - (p3.px - p1.px) / 8;
        const c2y = p2.py - (p3.py - p1.py) / 8;
        return `C${c1x.toFixed(1)},${c1y.toFixed(1)} ${c2x.toFixed(1)},${c2y.toFixed(1)} ${p2.px.toFixed(1)},${p2.py.toFixed(1)}`;
      }).join(" ");
  const caminhoDaArea = `${caminhoDaLinha} L${pontos[pontos.length - 1].px.toFixed(1)},${yBase.toFixed(1)} L${pontos[0].px.toFixed(1)},${yBase.toFixed(1)} Z`;

  /* O dia do cruzamento: onde o acumulado passa do fixo. */
  let cruzamento: { dia: number } | null = null;
  if (fixo > 0) {
    for (let i = 1; i < serie.length; i++) {
      if (serie[i - 1].acumulado < fixo && serie[i].acumulado >= fixo) {
        cruzamento = { dia: serie[i].dia };
        break;
      }
    }
  }

  const clipId = `lucro-${Math.round(fixo)}-${diasNoMes}-${porDia.length}`;
  const gradId = `area-${Math.round(fixo)}-${diasNoMes}-${porDia.length}`;
  const dinheiroCurto = (valor: number) =>
    valor >= 1000 ? `${(valor / 1000).toLocaleString("pt-BR", { maximumFractionDigits: 1 })}k` : valor.toFixed(0);

  const aoMoverMouse = (ev: React.MouseEvent<SVGSVGElement>) => {
    const caixa = svgRef.current?.getBoundingClientRect();
    if (!caixa) return;
    const vx = ((ev.clientX - caixa.left) / caixa.width) * W;
    const dia = Math.round(((vx - PAD_E) / (W - PAD_E - PAD_D)) * diasNoMes);
    if (dia < 1 || dia > fimDaSerie) { setHoverDia(null); return; }
    setHoverDia(dia);
  };

  const pontoDoHover = hoverDia != null ? serie[hoverDia] : null;
  const lucroNoHover = pontoDoHover ? pontoDoHover.acumulado - fixo : 0;

  return (
    <div className="relative">
      <svg ref={svgRef} viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", height: "auto", minWidth: 440 }}
           role="img" aria-label="Margem de contribuição acumulada do mês contra o custo fixo"
           onMouseMove={aoMoverMouse} onMouseLeave={() => setHoverDia(null)}>
        <defs>
          <linearGradient id={gradId} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="var(--ks-color-primary)" stopOpacity="0.28" />
            <stop offset="100%" stopColor="var(--ks-color-primary)" stopOpacity="0.02" />
          </linearGradient>
          <clipPath id={clipId}>
            <rect x={0} y={0} width={W} height={Math.max(0, yFixo)} />
          </clipPath>
        </defs>

        {/* As duas zonas, ditas na cara. */}
        {fixo > 0 && yFixo > PAD_T && (
          <>
            <rect x={PAD_E} y={PAD_T - 8} width={W - PAD_E - PAD_D} height={Math.max(0, yFixo - (PAD_T - 8))}
                  fill="var(--ks-emerald, #059669)" opacity={0.05} />
            <rect x={PAD_E} y={yFixo} width={W - PAD_E - PAD_D} height={Math.max(0, yBase - yFixo)}
                  fill="var(--ks-color-status-danger)" opacity={0.04} />
            <text x={PAD_E + 8} y={Math.max(PAD_T + 4, yFixo - 8)} fontSize={9} fontWeight={800}
                  letterSpacing="0.12em" fill="var(--ks-emerald, #059669)" opacity={0.8}>
              LUCRO
            </text>
            <text x={PAD_E + 8} y={Math.min(yBase - 6, yFixo + 14)} fontSize={9} fontWeight={800}
                  letterSpacing="0.12em" fill="var(--ks-color-status-danger)" opacity={0.65}>
              PAGANDO A CASA
            </text>
          </>
        )}

        {/* Grade recessiva com os valores. */}
        {[maxY / 2, maxY].map((valor, i) => (
          <g key={i}>
            <line x1={PAD_E} x2={W - PAD_D} y1={y(valor)} y2={y(valor)}
                  stroke="var(--ks-color-border-subtle)" strokeWidth={1} opacity={0.7} />
            <text x={PAD_E - 6} y={y(valor) + 3} textAnchor="end" fontSize={9}
                  fill="var(--ks-color-text-soft)">
              {dinheiroCurto(valor)}
            </text>
          </g>
        ))}
        <line x1={PAD_E} x2={W - PAD_D} y1={yBase} y2={yBase}
              stroke="var(--ks-color-border-subtle)" strokeWidth={1} />
        <text x={PAD_E - 6} y={yBase + 3} textAnchor="end" fontSize={9} fill="var(--ks-color-text-soft)">0</text>

        {/* A área e a curva — verde por cima da linha do fixo. */}
        <path d={caminhoDaArea} fill={`url(#${gradId})`} />
        <path d={caminhoDaArea} fill="var(--ks-emerald, #059669)" opacity={0.16} clipPath={`url(#${clipId})`} />
        <path ref={linhaRef} d={caminhoDaLinha} fill="none" stroke="var(--ks-color-primary)" strokeWidth={3}
              strokeLinejoin="round" strokeLinecap="round"
              strokeDasharray={comprimento || undefined}
              strokeDashoffset={comprimento ? (desenhado ? 0 : comprimento) : undefined}
              style={{ transition: "stroke-dashoffset 1.1s ease" }} />
        <path d={caminhoDaLinha} fill="none" stroke="var(--ks-emerald, #059669)" strokeWidth={3.2}
              strokeLinejoin="round" strokeLinecap="round" clipPath={`url(#${clipId})`}
              strokeDasharray={comprimento || undefined}
              strokeDashoffset={comprimento ? (desenhado ? 0 : comprimento) : undefined}
              style={{ transition: "stroke-dashoffset 1.1s ease" }} />

        {/* A linha do custo fixo. */}
        <line x1={PAD_E} x2={W - PAD_D} y1={yFixo} y2={yFixo}
              stroke="var(--ks-color-status-danger)" strokeWidth={1.5} strokeDasharray="6 5" opacity={0.8} />
        <text x={W - PAD_D} y={yFixo - 6} textAnchor="end" fontSize={9.5} fontWeight={700}
              fill="var(--ks-color-status-danger)">
          custo fixo {dinheiroCurto(fixo)}
        </text>

        {/* O dia em que bateu o PE. */}
        {cruzamento && (
          <g>
            <line x1={x(cruzamento.dia)} x2={x(cruzamento.dia)} y1={yFixo} y2={yBase}
                  stroke="var(--ks-emerald, #059669)" strokeWidth={1} strokeDasharray="3 3" opacity={0.6} />
            <circle cx={x(cruzamento.dia)} cy={yFixo} r={6.5} fill="var(--ks-emerald, #059669)"
                    stroke="var(--ks-color-bg-elevated, #fff)" strokeWidth={2} />
            <text x={x(cruzamento.dia)} y={yFixo - 12} textAnchor="middle" fontSize={9.5} fontWeight={800}
                  fill="var(--ks-emerald, #059669)">
              bateu o PE · dia {cruzamento.dia}
            </text>
          </g>
        )}

        {/* Os dias com venda. */}
        {vertices.filter((p) => p.dia > 0 && cmDoDia.has(p.dia)).map((p) => (
          <circle key={p.dia} cx={x(p.dia)} cy={y(p.acumulado)} r={hoverDia === p.dia ? 5.5 : 4}
                  fill={p.acumulado >= fixo && fixo > 0 ? "var(--ks-emerald, #059669)" : "var(--ks-color-primary)"}
                  stroke="var(--ks-color-bg-elevated, #fff)" strokeWidth={2}
                  style={{ transition: "r 0.15s ease" }} />
        ))}

        {/* Hoje, quando o mês está aberto. */}
        {!fechado && (
          <g>
            <line x1={x(diaAtual)} x2={x(diaAtual)} y1={PAD_T - 4} y2={yBase}
                  stroke="var(--ks-color-text-soft)" strokeWidth={1} strokeDasharray="2 3" opacity={0.5} />
            <text x={x(diaAtual)} y={PAD_T - 10} textAnchor="middle" fontSize={9}
                  fill="var(--ks-color-text-soft)">hoje</text>
          </g>
        )}

        {/* O cursor do mouse: a linha do dia e o ponto sobre a curva. */}
        {pontoDoHover && (
          <g>
            <line x1={x(pontoDoHover.dia)} x2={x(pontoDoHover.dia)} y1={PAD_T} y2={yBase}
                  stroke="var(--ks-color-text-primary)" strokeWidth={1} opacity={0.35} />
            <circle cx={x(pontoDoHover.dia)} cy={y(pontoDoHover.acumulado)} r={6}
                    fill={pontoDoHover.acumulado >= fixo && fixo > 0 ? "var(--ks-emerald, #059669)" : "var(--ks-color-primary)"}
                    stroke="var(--ks-color-bg-elevated, #fff)" strokeWidth={2.5} />
          </g>
        )}

        {/* Eixo dos dias. */}
        {[1, 5, 10, 15, 20, 25, diasNoMes].filter((d, i, arr) => arr.indexOf(d) === i && d <= diasNoMes).map((dia) => (
          <text key={dia} x={x(dia)} y={H - 8} textAnchor="middle" fontSize={9}
                fill="var(--ks-color-text-soft)">
            {dia}
          </text>
        ))}
      </svg>

      {/* O balão do dia, seguindo o cursor. */}
      {pontoDoHover && (
        <div className="pointer-events-none absolute z-10 rounded-xl border border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-elevated,#fff)] px-3 py-2 shadow-lg text-[11px]"
             style={{
               left: `min(max(${(x(pontoDoHover.dia) / W) * 100}% - 70px, 4px), calc(100% - 150px))`,
               top: 2,
             }}>
          <div className="font-bold text-[var(--ks-color-text-primary)]">Dia {pontoDoHover.dia}</div>
          {vendaDoDia.has(pontoDoHover.dia) ? (
            <div className="text-[var(--ks-color-text-muted)]">
              vendeu {dinheiro(vendaDoDia.get(pontoDoHover.dia) ?? 0)} · MC {dinheiro(cmDoDia.get(pontoDoHover.dia) ?? 0)}
            </div>
          ) : (
            <div className="text-[var(--ks-color-text-soft)]">sem venda</div>
          )}
          <div className="font-semibold text-[var(--ks-color-text-primary)]">
            acumulado {dinheiro(pontoDoHover.acumulado)}
          </div>
          <div className="font-semibold"
               style={{ color: lucroNoHover >= 0 ? "var(--ks-emerald,#059669)" : "var(--ks-color-status-danger)" }}>
            {lucroNoHover >= 0
              ? `lucro de ${dinheiro(lucroNoHover)}`
              : `faltam ${dinheiro(-lucroNoHover)} p/ o PE`}
          </div>
        </div>
      )}
    </div>
  );
}
