"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import Link from "next/link";
import { ArrowLeft, ArrowLeftRight, Banknote, CalendarClock, CreditCard, Loader2, QrCode, Receipt, Settings2, WalletCards } from "lucide-react";

import { ClientFormModal } from "@/components/clients/client-form-modal";
import { ErroDaTela, moeda, pedirFiscal } from "@/components/fiscal/comum";
import { DetalheDaNota } from "@/components/fiscal/detalhe-da-nota";
import { Aviso } from "@/components/ui/aviso";
import { CustomSelect } from "@/components/ui/custom-select";
import { PageHeader } from "@/components/ui/page-header";
import { Switch } from "@/components/ui/switch";
import type { Presenca } from "@/lib/fiscal/emissor";
import type { Pendencia } from "@/lib/fiscal/montar";
import type { NotaNaTela } from "@/lib/fiscal/servidor/apresentacao";
import { usePermissoes } from "@/lib/permissoes-do-usuario";
import { getSupabaseClient } from "@/lib/supabase";
import type { Client } from "@/types/client";

import { Bloco, Escolha, Recolhivel } from "../configuracao/campos";
import { BlocoCliente } from "./bloco-cliente";
import { BlocoItens } from "./bloco-itens";
import { CampoDeDinheiro } from "./campo-de-dinheiro";
import { Resumo, STATUS_QUE_ENCERRAM } from "./resumo";
import {
  dadosParaEnviar,
  formularioDosDados,
  NOME_DO_TIPO,
  novaChave,
  totalDaLinha,
  type ClienteDaEmissao,
  type ContextoNaTela,
  type FormaNaTela,
  type Formulario,
  type Linha,
  type Modelo,
  type PlanoNaTela,
} from "./tipos";

const FORMAS: FormaNaTela[] = [
  { chave: "pix", rotulo: "Pix", pago: true, Icone: QrCode },
  { chave: "dinheiro", rotulo: "Dinheiro", pago: true, Icone: Banknote },
  { chave: "credito", rotulo: "Cartão de crédito", pago: true, Icone: CreditCard },
  { chave: "debito", rotulo: "Cartão de débito", pago: true, Icone: WalletCards },
  { chave: "transferencia", rotulo: "Transferência", pago: true, Icone: ArrowLeftRight },
  { chave: "boleto", rotulo: "Boleto a receber", pago: false, Icone: Receipt },
  { chave: "a_prazo", rotulo: "A prazo", pago: false, Icone: CalendarClock },
];

const PRESENCAS: Array<{ value: Presenca; label: string }> = [
  { value: "presence", label: "Presencial, retirada no balcão" },
  { value: "internet", label: "Pela internet" },
  { value: "telephone", label: "Por telefone ou WhatsApp" },
  { value: "delivery", label: "Entrega em domicílio" },
  { value: "othersNonPresenceOperation", label: "Outra, sem o cliente presente" },
];

const MODELOS: Modelo[] = ["nfe", "nfce", "nfse"];

function formularioVazio(modelo: Modelo | null = null): Formulario {
  return {
    chave: novaChave(),
    modelo,
    cliente: null,
    semCliente: modelo === "nfce",
    documento: "",
    linhas: [],
    desconto: 0,
    frete: 0,
    pagamento: "pix",
    vencimento: "",
    perfilId: "",
    consumidorFinal: null,
    presenca: null,
    observacao: "",
    enviarEmail: null,
  };
}

/** Hoje + 30 dias, no fuso de São Paulo, no formato do campo de data. */
function daquiA30Dias() {
  const data = new Date(Date.now() + 30 * 86400000);
  return new Intl.DateTimeFormat("en-CA", { timeZone: "America/Sao_Paulo", year: "numeric", month: "2-digit", day: "2-digit" }).format(data);
}

function rolarAte(id: string, focar?: string) {
  const alvo = document.getElementById(id);
  if (!alvo) return;
  alvo.scrollIntoView({ behavior: "smooth", block: "center" });
  if (focar) setTimeout(() => (document.getElementById(focar) as HTMLElement | null)?.focus(), 350);
}

export default function EmitirNotaFiscalCliente() {
  const { pode } = usePermissoes();
  const permissoes = { emitir: pode("fiscal.emitir"), cancelar: pode("fiscal.cancelar"), configurar: pode("fiscal.configurar") };

  const [contexto, setContexto] = useState<ContextoNaTela | null>(null);
  const [erroAoAbrir, setErroAoAbrir] = useState<string | null>(null);
  const [formulario, setFormulario] = useState<Formulario>(() => formularioVazio());
  const [plano, setPlano] = useState<PlanoNaTela | null>(null);
  const [conferindo, setConferindo] = useState(false);
  const [erro, setErro] = useState<string | null>(null);
  const [erroDoPlano, setErroDoPlano] = useState<string | null>(null);
  const [corpoConferido, setCorpoConferido] = useState<string | null>(null);
  const [pendenciasDoEnvio, setPendenciasDoEnvio] = useState<Pendencia[]>([]);
  const [enviando, setEnviando] = useState<"emitir" | "previa" | null>(null);
  const [nota, setNota] = useState<NotaNaTela | null>(null);
  const [detalheAberto, setDetalheAberto] = useState(false);
  const [cadastro, setCadastro] = useState<{ aberto: boolean; cliente: Client | null }>({ aberto: false, cliente: null });
  const [abrindoCadastro, setAbrindoCadastro] = useState(false);
  const [tentouEmitir, setTentouEmitir] = useState(false);
  const [versao, setVersao] = useState(0);
  const rodadaDoPlano = useRef(0);

  /* Abre a tela: contexto da empresa e, com ?nota= ou ?copiar=, a nota guardada. */
  useEffect(() => {
    let viva = true;
    const busca = new URLSearchParams(window.location.search);
    const editar = busca.get("nota");
    const copiar = busca.get("copiar");
    const sufixo = editar ? `?nota=${encodeURIComponent(editar)}` : copiar ? `?copiar=${encodeURIComponent(copiar)}` : "";

    const abrir = async () => {
      let json: ContextoNaTela;
      try {
        json = await pedirFiscal<ContextoNaTela>(`/api/fiscal/avulsa${sufixo}`);
      } catch (e) {
        if (!sufixo) throw e;
        /* A nota pedida não abre aqui: segue com uma nota em branco e avisa. */
        if (viva) setErroAoAbrir(e instanceof Error ? e.message : "Não foi possível abrir a nota.");
        json = await pedirFiscal<ContextoNaTela>("/api/fiscal/avulsa");
      }
      if (!viva) return;
      setContexto(json);
      const primeiroLigado = MODELOS.find((modelo) => json.emissor.modelos[modelo]) ?? null;
      if (json.formulario) {
        const { dados, cliente, fotos } = json.formulario;
        /* Editar remonta a mesma nota; copiar começa uma nova com os mesmos dados. */
        const mesmaNota = editar && json.nota ? json.nota : null;
        setFormulario(formularioDosDados(dados, cliente, mesmaNota ? mesmaNota.id : novaChave(), fotos));
        if (mesmaNota) setNota(mesmaNota);
      } else {
        setFormulario(formularioVazio(primeiroLigado));
      }
    };

    abrir().catch((e: unknown) => {
      if (viva) setErroAoAbrir(e instanceof Error ? e.message : "Não foi possível abrir a emissão de notas.");
    });
    return () => {
      viva = false;
    };
  }, []);

  /* Voltou de outra aba (corrigiu o cadastro do cliente ou do produto): confere de novo. */
  useEffect(() => {
    const aoVoltar = () => setVersao((v) => v + 1);
    window.addEventListener("focus", aoVoltar);
    return () => window.removeEventListener("focus", aoVoltar);
  }, []);

  const travado = Boolean(nota && (nota.emAndamento || STATUS_QUE_ENCERRAM.includes(nota.status)));
  const pronto = Boolean(contexto && contexto.emissor.existe && formulario.modelo);
  const corpo = useMemo(() => JSON.stringify(dadosParaEnviar(formulario)), [formulario]);

  /* Confere enquanto a pessoa preenche. */
  useEffect(() => {
    if (!pronto || travado) return;
    const minha = ++rodadaDoPlano.current;
    const relogio = setTimeout(async () => {
      setConferindo(true);
      try {
        const json = await pedirFiscal<{ plano: PlanoNaTela }>("/api/fiscal/avulsa", {
          method: "POST",
          json: { acao: "planejar", dados: JSON.parse(corpo) },
        });
        if (minha !== rodadaDoPlano.current) return;
        setPlano(json.plano);
        setCorpoConferido(corpo);
        setErroDoPlano(null);
        setPendenciasDoEnvio([]);
      } catch (e) {
        if (minha === rodadaDoPlano.current) setErroDoPlano(e instanceof Error ? e.message : "Não foi possível conferir a nota.");
      } finally {
        if (minha === rodadaDoPlano.current) setConferindo(false);
      }
    }, 600);
    return () => clearTimeout(relogio);
  }, [corpo, pronto, travado, versao]);

  /* Acompanha a nota enviada até a resposta chegar. */
  const notaId = nota?.id ?? null;
  const notaAndando = Boolean(nota?.emAndamento);
  useEffect(() => {
    if (!notaId || !notaAndando) return;
    let voltas = 0;
    const relogio = setInterval(async () => {
      voltas += 1;
      try {
        const json = await pedirFiscal<{ nota: NotaNaTela }>(`/api/fiscal/notas/${notaId}`);
        setNota(json.nota);
      } catch {
        /* Tenta na próxima volta. */
      }
      if (voltas >= 90) clearInterval(relogio);
    }, 3000);
    return () => clearInterval(relogio);
  }, [notaId, notaAndando]);

  /* A nota terminou (autorizada, recusada...): o pacote do mês mudou, relê o saldo. */
  const statusDaNota = nota?.status ?? null;
  useEffect(() => {
    if (!statusDaNota || notaAndando || statusDaNota === "rascunho") return;
    let viva = true;
    pedirFiscal<ContextoNaTela>("/api/fiscal/avulsa")
      .then((json) => {
        if (!viva) return;
        setContexto((atual) => (atual ? { ...atual, saldo: json.saldo } : atual));
        setPlano((atual) => (atual ? { ...atual, saldo: json.saldo } : atual));
      })
      .catch(() => undefined);
    return () => {
      viva = false;
    };
  }, [statusDaNota, notaAndando]);

  const mudar = useCallback((parcial: Partial<Formulario>) => setFormulario((atual) => ({ ...atual, ...parcial })), []);
  const mudarLinhas = useCallback((atualizar: (linhas: Linha[]) => Linha[]) => setFormulario((atual) => ({ ...atual, linhas: atualizar(atual.linhas) })), []);

  const trocarModelo = (modelo: Modelo) => {
    setFormulario((atual) => {
      const forma = FORMAS.find((item) => item.chave === atual.pagamento);
      return {
        ...atual,
        modelo,
        semCliente: modelo === "nfce" ? !atual.cliente : false,
        pagamento: modelo === "nfce" && forma && !forma.pago ? "pix" : atual.pagamento,
        presenca: modelo === "nfce" && atual.presenca && !["presence", "delivery"].includes(atual.presenca) ? null : atual.presenca,
        perfilId: "",
      };
    });
    /* A prévia de outro tipo deixa de valer; o servidor descarta ao emitir. */
    if (nota?.status === "rascunho") setNota(null);
  };

  /* ---------------- Pendências ---------------- */

  const pendencias = useMemo(() => {
    const origem = pendenciasDoEnvio.length ? pendenciasDoEnvio : [...(plano?.pendenciasGerais ?? []), ...(plano?.notas ?? []).flatMap((n) => n.pendencias)];
    const vistas = new Set<string>();
    return origem.filter((p) => {
      const chave = `${p.codigo}:${p.alvoId ?? ""}`;
      if (vistas.has(chave)) return false;
      vistas.add(chave);
      return true;
    });
  }, [plano, pendenciasDoEnvio]);

  const bloqueios = useMemo(() => pendencias.filter((p) => p.nivel === "bloqueio"), [pendencias]);
  const emBranco = !formulario.cliente && !formulario.semCliente && formulario.linhas.length === 0;

  const problemasPorLinha = useMemo(() => {
    const mapa = new Map<number, Pendencia[]>();
    if (!tentouEmitir) {
      /* Antes de tentar emitir, a linha só acusa o NCM (o resto a pessoa ainda está digitando). */
      for (const p of pendencias) {
        if (p.onde === "pedido" && p.codigo.startsWith("produto.ncm") && p.alvoId && /^\d+$/.test(p.alvoId)) {
          mapa.set(Number(p.alvoId), [...(mapa.get(Number(p.alvoId)) ?? []), p]);
        }
      }
      return mapa;
    }
    for (const p of pendencias) {
      if (p.onde !== "pedido" || !p.alvoId || !/^\d+$/.test(p.alvoId)) continue;
      mapa.set(Number(p.alvoId), [...(mapa.get(Number(p.alvoId)) ?? []), p]);
    }
    return mapa;
  }, [pendencias, tentouEmitir]);

  const problemaNoCliente = tentouEmitir && bloqueios.some((p) => p.onde === "cliente");

  /* ---------------- Cliente ---------------- */

  const resumoDoCliente = async (id: string) => {
    const json = await pedirFiscal<{ clientes: ClienteDaEmissao[] }>(`/api/fiscal/avulsa/buscas?tipo=clientes&id=${encodeURIComponent(id)}`);
    return json.clientes[0] ?? null;
  };

  const abrirCadastroDoCliente = async () => {
    if (!formulario.cliente) return;
    setAbrindoCadastro(true);
    try {
      const { data, error } = await getSupabaseClient().from("clients").select("*").eq("id", formulario.cliente.id).maybeSingle();
      if (error || !data) throw new Error("Não foi possível abrir o cadastro do cliente.");
      setCadastro({ aberto: true, cliente: data as Client });
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível abrir o cadastro do cliente.");
    } finally {
      setAbrindoCadastro(false);
    }
  };

  const aoSalvarCliente = async (clienteId?: string) => {
    const id = clienteId ?? cadastro.cliente?.id ?? null;
    setCadastro({ aberto: false, cliente: null });
    if (!id) return;
    try {
      const resumo = await resumoDoCliente(id);
      if (resumo) mudar({ cliente: resumo, semCliente: false });
      setVersao((v) => v + 1);
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível carregar o cliente.");
    }
  };

  const acaoDaPendencia = (pendencia: Pendencia) => {
    if (pendencia.onde === "cliente") {
      if (formulario.cliente) return { rotulo: "Editar cadastro", aoClicar: () => void abrirCadastroDoCliente() };
      return { rotulo: "Escolher", aoClicar: () => rolarAte("secao-cliente", "busca-do-cliente") };
    }
    if (pendencia.onde === "pedido" && pendencia.alvoId && /^\d+$/.test(pendencia.alvoId)) {
      const linha = formulario.linhas[Number(pendencia.alvoId)];
      const campo = pendencia.codigo.startsWith("produto.ncm") ? `ncm-${linha?.id}` : pendencia.codigo.includes(".valor") ? `valor-${linha?.id}` : pendencia.codigo.includes(".quantidade") ? `quantidade-${linha?.id}` : `descricao-${linha?.id}`;
      return { rotulo: "Ir para a linha", aoClicar: () => rolarAte(`linha-${pendencia.alvoId}`, linha ? campo : undefined) };
    }
    if (pendencia.codigo === "avulsa.sem_itens") return { rotulo: "Adicionar", aoClicar: () => rolarAte("secao-itens") };
    if (pendencia.onde === "pagamento") return { rotulo: "Ver pagamento", aoClicar: () => rolarAte("secao-pagamento") };
    return null;
  };

  /* ---------------- Emitir ---------------- */

  const rolarParaOPrimeiroProblema = () => {
    const primeiro = bloqueios[0];
    if (!primeiro) return;
    const acao = acaoDaPendencia(primeiro);
    if (acao) acao.aoClicar();
  };

  const emitir = async (previa: boolean) => {
    if (!formulario.modelo || enviando) return;
    /* Se a pessoa clicou antes da conferência do que acabou de digitar, quem decide é o servidor. */
    const conferido = corpoConferido === corpo && !pendenciasDoEnvio.length;
    const impedem = !conferido ? [] : previa ? bloqueios.filter((p) => p.codigo !== "creditos.sem_saldo") : bloqueios;
    if (impedem.length) {
      setTentouEmitir(true);
      rolarParaOPrimeiroProblema();
      return;
    }
    setEnviando(previa ? "previa" : "emitir");
    setErro(null);
    setPendenciasDoEnvio([]);
    try {
      const json = await pedirFiscal<{ plano: PlanoNaTela; notas: NotaNaTela[] }>("/api/fiscal/avulsa", {
        method: "POST",
        json: { acao: previa ? "previa" : "emitir", dados: dadosParaEnviar(formulario) },
      });
      const primeira = json.notas[0] ?? null;
      if (primeira) {
        setNota(primeira);
        setFormulario((atual) => ({ ...atual, chave: primeira.id }));
      }
      setPlano(json.plano);
      setTentouEmitir(false);
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível emitir.");
      if (e instanceof ErroDaTela && e.pendencias.length) {
        setPendenciasDoEnvio(e.pendencias);
        setTentouEmitir(true);
      }
    } finally {
      setEnviando(null);
    }
  };

  const emitirOutra = () => {
    setFormulario((atual) => formularioVazio(atual.modelo));
    setNota(null);
    setPlano(null);
    setErro(null);
    setPendenciasDoEnvio([]);
    setTentouEmitir(false);
    window.history.replaceState(null, "", "/dashboard/notas-fiscais/emitir");
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  /* ---------------- Tela ---------------- */

  const modelo = formulario.modelo;
  const ligados = contexto ? MODELOS.filter((m) => contexto.emissor.modelos[m]) : [];
  const configurada = Boolean(contexto?.emissor.existe && contexto.emissor.status === "ativo");
  const perfisDoTipo = contexto && modelo ? contexto.perfis.filter((p) => p.tipo === (modelo === "nfse" ? "servico" : "mercadoria")) : [];
  const formaAtual = FORMAS.find((forma) => forma.chave === formulario.pagamento) ?? FORMAS[0];
  const subtotal = Math.round(formulario.linhas.reduce((acc, linha) => acc + totalDaLinha(linha), 0) * 100) / 100;
  const consumidorFinal = formulario.consumidorFinal ?? plano?.consumidorFinal ?? contexto?.preferencias.consumidorFinal ?? true;
  const presenca = formulario.presenca ?? plano?.presenca ?? (modelo === "nfce" ? "presence" : contexto?.preferencias.presenca ?? "presence");
  const emailDoCliente = !formulario.semCliente ? formulario.cliente?.email ?? null : null;

  return (
    <div className="space-y-6">
      <PageHeader
        eyebrow="Notas fiscais"
        title="Emitir nota fiscal"
        subtitle="Para vender sem pedido no sistema: escolha o cliente, os itens e emita."
        actions={
          <Link href="/dashboard/notas-fiscais" className="ks-button ks-button-soft">
            <ArrowLeft size={16} />
            Emissão de notas
          </Link>
        }
      />

      {erroAoAbrir ? (
        <Aviso tom="ruim" aoFechar={() => setErroAoAbrir(null)}>
          {erroAoAbrir}
        </Aviso>
      ) : null}

      {!contexto ? (
        erroAoAbrir ? null : (
          <div className="flex justify-center py-24">
            <Loader2 className="h-8 w-8 animate-spin text-[var(--ks-color-primary)]" />
          </div>
        )
      ) : !permissoes.emitir ? (
        <Aviso tom="neutro" titulo="Você não tem permissão para emitir notas">
          Peça ao responsável da empresa para liberar a emissão de notas fiscais no seu acesso.
        </Aviso>
      ) : !configurada || !ligados.length ? (
        <Aviso
          tom="atencao"
          titulo={!contexto.emissor.existe ? "Configure as notas fiscais primeiro" : contexto.emissor.status === "suspenso" ? "Emissão suspensa" : "Termine a configuração das notas"}
          acao={
            permissoes.configurar && contexto.emissor.status !== "suspenso" ? (
              <Link href="/dashboard/notas-fiscais/configuracao" className="ks-button ks-button-primary ks-button-sm">
                <Settings2 size={14} />
                Configurar
              </Link>
            ) : undefined
          }
        >
          {contexto.emissor.status === "suspenso"
            ? "A emissão desta empresa foi suspensa. Fale com o suporte do Ktalogu."
            : "Leva poucos minutos: dados da empresa, certificado digital e quais notas você vai emitir."}
        </Aviso>
      ) : (
        <>
          {!contexto.servidorPronto ? (
            <Aviso tom="atencao" titulo="Emissão de notas indisponível no momento">
              Você pode preencher a nota agora; a emissão volta assim que o serviço for restabelecido. Se demorar, fale com o suporte do Ktalogu.
            </Aviso>
          ) : null}

          <div className="grid grid-cols-1 items-start gap-6 xl:grid-cols-[minmax(0,1fr)_340px] 2xl:grid-cols-[minmax(0,1fr)_400px]">
            <div className="min-w-0 space-y-8 rounded-3xl bg-[var(--ks-color-bg-elevated)] p-5 shadow-[0_10px_30px_rgba(26,26,43,0.06)] sm:p-8 xl:p-10">
              {travado ? (
                <div className="flex flex-col gap-3 rounded-2xl bg-[var(--ks-color-bg-inset)] px-4 py-3 sm:flex-row sm:items-center sm:justify-between">
                  <p className="text-sm text-[var(--ks-color-text-muted)]">
                    <strong className="text-[var(--ks-color-text-primary)]">Esta nota já foi enviada.</strong> Os dados abaixo ficam como foram emitidos.
                  </p>
                  <button type="button" onClick={emitirOutra} className="ks-button ks-button-soft ks-button-sm shrink-0">
                    Emitir outra nota
                  </button>
                </div>
              ) : null}
              <Bloco titulo="Tipo de nota" texto={ligados.length < 3 && permissoes.configurar ? <>Outro tipo aparece aqui quando for ligado em <Link href="/dashboard/notas-fiscais/configuracao?passo=notas" className="font-semibold text-[var(--ks-color-primary)] hover:underline">Configuração</Link>.</> : undefined}>
                <Escolha<Modelo>
                  colunas={ligados.length >= 3 ? 3 : ligados.length === 2 ? 2 : 1}
                  valor={modelo}
                  aoMudar={(novo) => !travado && trocarModelo(novo)}
                  opcoes={ligados.map((chave) => ({
                    valor: chave,
                    titulo: `${NOME_DO_TIPO[chave].titulo} (${NOME_DO_TIPO[chave].sigla})`,
                    texto: NOME_DO_TIPO[chave].texto,
                    desligado: travado && chave !== modelo,
                  }))}
                />
              </Bloco>

              {modelo ? (
                <>
                  <div id="secao-cliente" className="scroll-mt-24">
                    <Bloco
                      titulo={modelo === "nfse" ? "Para quem foi o serviço" : "Cliente"}
                      texto={
                        modelo === "nfe"
                          ? "A nota de produto sai com os dados do cadastro: nome, CPF ou CNPJ e endereço."
                          : modelo === "nfse"
                            ? "A nota de serviço sai com o nome e o CPF ou CNPJ de quem contratou."
                            : undefined
                      }
                    >
                      <BlocoCliente
                        modelo={modelo}
                        cliente={formulario.cliente}
                        semCliente={formulario.semCliente}
                        documento={formulario.documento}
                        aoEscolher={(cliente) => mudar({ cliente, semCliente: false })}
                        aoTirar={() => mudar({ cliente: null, enviarEmail: null })}
                        aoMudarSemCliente={(semCliente) => mudar({ semCliente, ...(semCliente ? { cliente: null, enviarEmail: null } : { documento: "" }) })}
                        aoMudarDocumento={(documento) => mudar({ documento })}
                        aoEditar={() => void abrirCadastroDoCliente()}
                        aoCadastrar={() => setCadastro({ aberto: true, cliente: null })}
                        abrindoCadastro={abrindoCadastro}
                        destaque={problemaNoCliente}
                        travado={travado}
                      />
                    </Bloco>
                  </div>

                  <div id="secao-itens" className="scroll-mt-24">
                    <Bloco titulo={modelo === "nfse" ? "Serviços" : "Itens"} texto={modelo === "nfse" ? "O que foi feito e quanto custou." : "Do catálogo ou digitados na hora."}>
                      <BlocoItens
                        modelo={modelo}
                        linhas={formulario.linhas}
                        aoMudarLinhas={mudarLinhas}
                        problemasDaLinha={(indice) => problemasPorLinha.get(indice) ?? []}
                        travado={travado}
                      />
                      {formulario.linhas.length ? (
                        <div className="ml-auto grid w-full max-w-md grid-cols-[minmax(0,1fr)_140px] items-center gap-x-4 gap-y-3 rounded-2xl bg-[var(--ks-color-bg-inset)] px-4 py-4 sm:grid-cols-[minmax(0,1fr)_170px] sm:px-5">
                          <span className="text-sm text-[var(--ks-color-text-muted)]">Soma dos itens</span>
                          <span className="ks-num text-right text-sm font-semibold text-[var(--ks-color-text-primary)]">{moeda(subtotal)}</span>
                          <label htmlFor="desconto-da-nota" className="text-sm text-[var(--ks-color-text-muted)]">
                            Desconto
                          </label>
                          <div className="relative">
                            <span className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-xs font-semibold text-[var(--ks-color-text-soft)]">R$</span>
                            <CampoDeDinheiro
                              id="desconto-da-nota"
                              valor={formulario.desconto}
                              aoMudar={(desconto) => mudar({ desconto: Math.max(0, desconto) })}
                              placeholder="0,00"
                              disabled={travado}
                              className="ks-field ks-num text-right"
                              style={{ paddingLeft: "2.25rem" }}
                            />
                          </div>
                          {modelo === "nfe" ? (
                            <>
                              <label htmlFor="frete-da-nota" className="text-sm text-[var(--ks-color-text-muted)]">
                                Frete cobrado
                              </label>
                              <div className="relative">
                                <span className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-xs font-semibold text-[var(--ks-color-text-soft)]">R$</span>
                                <CampoDeDinheiro
                                  id="frete-da-nota"
                                  valor={formulario.frete}
                                  aoMudar={(frete) => mudar({ frete: Math.max(0, frete) })}
                                  placeholder="0,00"
                                  disabled={travado}
                                  className="ks-field ks-num text-right"
                                  style={{ paddingLeft: "2.25rem" }}
                                />
                              </div>
                            </>
                          ) : null}
                        </div>
                      ) : null}
                    </Bloco>
                  </div>

                  {modelo !== "nfse" ? (
                    <div id="secao-pagamento" className="scroll-mt-24">
                      <Bloco
                        titulo="Pagamento"
                        texto={modelo === "nfce" ? "O cupom fiscal é para venda paga na hora." : "Como o cliente pagou ou vai pagar."}
                      >
                        <div className="grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-4 2xl:grid-cols-7">
                          {FORMAS.filter((forma) => modelo === "nfe" || forma.pago).map((forma) => {
                            const ativa = formulario.pagamento === forma.chave;
                            return (
                              <button
                                key={forma.chave}
                                type="button"
                                disabled={travado}
                                aria-pressed={ativa}
                                onClick={() =>
                                  mudar({
                                    pagamento: forma.chave,
                                    vencimento: forma.pago ? "" : formulario.vencimento || daquiA30Dias(),
                                  })
                                }
                                className={`flex flex-col items-start gap-2 rounded-2xl px-4 py-3 text-left text-sm font-semibold transition disabled:cursor-not-allowed disabled:opacity-50 ${
                                  ativa
                                    ? "bg-gradient-to-br from-violet-500 to-purple-600 text-white shadow-[0_12px_28px_rgba(124,58,237,0.30)]"
                                    : "bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-primary)] hover:bg-[var(--ks-color-bg-hover)]"
                                }`}
                              >
                                <forma.Icone size={18} className={ativa ? "text-white" : "text-[var(--ks-color-primary)]"} />
                                {forma.rotulo}
                              </button>
                            );
                          })}
                        </div>
                        {!formaAtual.pago && modelo === "nfe" ? (
                          <label className="block max-w-xs space-y-2">
                            <span className="flex items-baseline gap-2 text-sm font-semibold text-[var(--ks-color-text-primary)]">
                              Vencimento
                              <span className="text-xs font-normal text-[var(--ks-color-text-soft)]">opcional</span>
                            </span>
                            <input
                              type="date"
                              value={formulario.vencimento}
                              min={new Intl.DateTimeFormat("en-CA", { timeZone: "America/Sao_Paulo", year: "numeric", month: "2-digit", day: "2-digit" }).format(new Date())}
                              disabled={travado}
                              onChange={(e) => mudar({ vencimento: e.target.value })}
                              className="ks-field"
                            />
                            <span className="block text-xs leading-5 text-[var(--ks-color-text-muted)]">Vai na nota como a data da cobrança. Sem data, a nota sai com vencimento hoje.</span>
                          </label>
                        ) : null}
                      </Bloco>
                    </div>
                  ) : null}

                  <div className="border-t border-[var(--ks-color-border-subtle)] pt-6">
                    <Recolhivel titulo="Mais opções: observação, forma da venda e tributação">
                      <div className="grid grid-cols-1 gap-5 lg:grid-cols-2">
                        <label className="block space-y-2 lg:col-span-2">
                          <span className="flex items-baseline gap-2 text-sm font-semibold text-[var(--ks-color-text-primary)]">
                            Observação na nota
                            <span className="text-xs font-normal text-[var(--ks-color-text-soft)]">opcional</span>
                          </span>
                          <textarea
                            value={formulario.observacao}
                            disabled={travado}
                            onChange={(e) => mudar({ observacao: e.target.value.slice(0, 500) })}
                            rows={3}
                            placeholder="Aparece nas informações complementares da nota"
                            className="ks-field resize-none"
                          />
                        </label>

                        <div className="space-y-2">
                          <p className="text-sm font-semibold text-[var(--ks-color-text-primary)]">Como foi a venda</p>
                          <CustomSelect
                            disabled={travado}
                            options={modelo === "nfce" ? PRESENCAS.filter((p) => p.value === "presence" || p.value === "delivery") : PRESENCAS}
                            value={presenca}
                            onChange={(valor) => mudar({ presenca: valor as Presenca })}
                          />
                        </div>

                        {perfisDoTipo.length > 1 ? (
                          <div className="space-y-2">
                            <p className="text-sm font-semibold text-[var(--ks-color-text-primary)]">
                              {modelo === "nfse" ? "Tipo de serviço" : "Tributação dos itens sem cadastro"}
                            </p>
                            <CustomSelect
                              disabled={travado}
                              options={perfisDoTipo.map((perfil) => ({ value: perfil.id, label: perfil.padrao ? `${perfil.nome} (padrão)` : perfil.nome }))}
                              value={formulario.perfilId || perfisDoTipo.find((p) => p.padrao)?.id || ""}
                              onChange={(perfilId) => mudar({ perfilId })}
                            />
                          </div>
                        ) : null}

                        {modelo === "nfe" ? (
                          <label className="flex items-center justify-between gap-4 rounded-2xl bg-[var(--ks-color-bg-inset)] px-4 py-3">
                            <span>
                              <span className="block text-sm font-semibold text-[var(--ks-color-text-primary)]">O cliente vai revender estes produtos</span>
                              <span className="block text-xs leading-5 text-[var(--ks-color-text-muted)]">Deixe desligado quando o cliente usa o que comprou (o caso comum).</span>
                            </span>
                            <Switch checked={!consumidorFinal} onCheckedChange={(revende) => mudar({ consumidorFinal: !revende })} disabled={travado} />
                          </label>
                        ) : null}

                        {emailDoCliente ? (
                          <label className="flex items-center justify-between gap-4 rounded-2xl bg-[var(--ks-color-bg-inset)] px-4 py-3">
                            <span className="min-w-0">
                              <span className="block text-sm font-semibold text-[var(--ks-color-text-primary)]">Enviar a nota por e-mail</span>
                              <span className="block truncate text-xs text-[var(--ks-color-text-muted)]">{emailDoCliente}</span>
                            </span>
                            <Switch
                              checked={formulario.enviarEmail ?? plano?.enviarEmail ?? contexto.preferencias.enviarEmail}
                              onCheckedChange={(enviarEmail) => mudar({ enviarEmail })}
                              disabled={travado}
                            />
                          </label>
                        ) : null}
                      </div>
                    </Recolhivel>
                  </div>
                </>
              ) : null}
            </div>

            <aside className="min-w-0 xl:sticky xl:top-4">
              <Resumo
                contexto={contexto}
                formulario={formulario}
                plano={plano}
                conferindo={conferindo}
                pendencias={pendencias}
                mostrarPendencias={!emBranco || tentouEmitir}
                nota={nota}
                enviando={enviando}
                erro={erro ?? erroDoPlano}
                aoFecharErro={() => (erro ? setErro(null) : setErroDoPlano(null))}
                aoEmitir={() => void emitir(false)}
                aoPrevia={() => void emitir(true)}
                aoOutra={emitirOutra}
                aoAbrirDetalhe={() => setDetalheAberto(true)}
                acaoDaPendencia={acaoDaPendencia}
              />
            </aside>
          </div>
        </>
      )}

      <ClientFormModal
        isOpen={cadastro.aberto}
        onClose={() => setCadastro({ aberto: false, cliente: null })}
        onSuccess={(clienteId) => void aoSalvarCliente(clienteId)}
        client={cadastro.cliente}
      />

      <DetalheDaNota
        notaId={nota?.id ?? null}
        aberta={detalheAberto && Boolean(nota)}
        aoFechar={() => setDetalheAberto(false)}
        aoMudar={(atualizada) => {
          if (atualizada.status === "removida") {
            setNota(null);
            setDetalheAberto(false);
            mudar({ chave: novaChave() });
          } else {
            setNota(atualizada);
          }
        }}
        clienteId={formulario.cliente?.id ?? null}
        permissoes={permissoes}
      />
    </div>
  );
}
