"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { ChevronDown, Eye, FileText, Loader2, ReceiptText, Send, Settings2, Sparkles, X } from "lucide-react";

import { Aviso } from "@/components/ui/aviso";
import { CustomSelect } from "@/components/ui/custom-select";
import { Dialog, DialogContent, DialogDescription, DialogTitle } from "@/components/ui/dialog";
import { Switch } from "@/components/ui/switch";
import type { Presenca } from "@/lib/fiscal/emissor";
import type { Pendencia } from "@/lib/fiscal/montar";
import type { NotaNaTela, planoParaTela } from "@/lib/fiscal/servidor/apresentacao";
import { LIMITE_DAS_OBSERVACOES } from "@/lib/orders/observacoes";

import {
  diasParaVirarOMes,
  ErroDaTela,
  ListaDePendencias,
  MarcaDoModelo,
  mesPorExtenso,
  moeda,
  moedaDeCentavos,
  pedirFiscal,
  SeloDoStatus,
  SeloSemValorFiscal,
} from "./comum";
import { DetalheDaNota } from "./detalhe-da-nota";

type Plano = ReturnType<typeof planoParaTela>;

type Resposta = {
  ambiente: string;
  servidorPronto: boolean;
  notas: NotaNaTela[];
  plano: Plano;
};

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" },
];

export function EmitirNotaDoPedido({
  pedidoId,
  aberta,
  aoFechar,
  aoMudar,
  telefoneDoCliente,
  permissoes,
}: {
  pedidoId: string;
  aberta: boolean;
  aoFechar: () => void;
  aoMudar?: () => void;
  telefoneDoCliente?: string | null;
  permissoes: { emitir: boolean; cancelar: boolean; configurar: boolean };
}) {
  const [dados, setDados] = useState<Resposta | null>(null);
  const [carregando, setCarregando] = useState(false);
  const [erro, setErro] = useState<string | null>(null);
  const [pendenciasDoEnvio, setPendenciasDoEnvio] = useState<Pendencia[]>([]);
  const [enviando, setEnviando] = useState<"emitir" | "previa" | null>(null);
  const [ajustesAbertos, setAjustesAbertos] = useState(false);
  const [itensAbertos, setItensAbertos] = useState<string | null>(null);
  const [notaAberta, setNotaAberta] = useState<string | null>(null);
  const [acompanhando, setAcompanhando] = useState(false);
  /* Item digitado no pedido (sem produto do catálogo) recebendo o NCM aqui mesmo. */
  const [ncmDoItem, setNcmDoItem] = useState<{ itemId: string; descricao: string } | null>(null);

  /* Escolhas desta emissão. `null` = o que o servidor sugerir. */
  const [modelo, setModelo] = useState<"nfe" | "nfce" | null>(null);
  const [consumidorFinal, setConsumidorFinal] = useState<boolean | null>(null);
  const [presenca, setPresenca] = useState<Presenca | null>(null);
  const [enviarEmail, setEnviarEmail] = useState<boolean | null>(null);
  /* null = ninguém mexeu: vale a observação do pedido, que o plano traz. */
  const [observacao, setObservacao] = useState<string | null>(null);
  const [documento, setDocumento] = useState("");
  const pedidoAtual = useRef(0);

  const carregar = useCallback(async () => {
    const minha = ++pedidoAtual.current;
    setCarregando((atual) => atual || !dados);
    setErro(null);
    try {
      const busca = new URLSearchParams();
      if (modelo) busca.set("modelo", modelo);
      if (consumidorFinal !== null) busca.set("consumidorFinal", consumidorFinal ? "1" : "0");
      if (presenca) busca.set("presenca", presenca);
      if (documento.replace(/\D/g, "").length >= 11) busca.set("documento", documento.replace(/\D/g, ""));
      const json = await pedirFiscal<Resposta>(`/api/fiscal/pedidos/${pedidoId}?${busca.toString()}`);
      if (minha === pedidoAtual.current) setDados(json);
    } catch (e) {
      if (minha === pedidoAtual.current) setErro(e instanceof Error ? e.message : "Não foi possível preparar a nota.");
    } finally {
      if (minha === pedidoAtual.current) setCarregando(false);
    }
  }, [pedidoId, modelo, consumidorFinal, presenca, documento, dados]);

  useEffect(() => {
    if (!aberta) return;
    setPendenciasDoEnvio([]);
    setAcompanhando(false);
    void carregar();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [aberta, pedidoId, modelo, consumidorFinal, presenca]);

  /* O CPF digitado recalcula depois que a pessoa para de digitar. */
  useEffect(() => {
    if (!aberta) return;
    const digitos = documento.replace(/\D/g, "");
    if (digitos.length !== 0 && digitos.length !== 11 && digitos.length !== 14) return;
    const relogio = setTimeout(() => void carregar(), 400);
    return () => clearTimeout(relogio);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [documento]);

  const recarregarNotas = useCallback(async () => {
    try {
      const json = await pedirFiscal<{ notas: NotaNaTela[] }>(`/api/fiscal/pedidos/${pedidoId}?so=notas`);
      setDados((atual) => (atual ? { ...atual, notas: json.notas } : atual));
      return json.notas;
    } catch {
      return null;
    }
  }, [pedidoId]);

  /* Acompanha as notas recém-enviadas até a autoridade responder. */
  useEffect(() => {
    if (!aberta || !acompanhando) return;
    let voltas = 0;
    const relogio = setInterval(async () => {
      voltas += 1;
      const notas = await recarregarNotas();
      const alguemAndando = (notas ?? []).some((nota) => nota.emAndamento);
      if (!alguemAndando || voltas > 60) {
        clearInterval(relogio);
        setAcompanhando(false);
        aoMudar?.();
        void carregar();
      }
    }, 3000);
    return () => clearInterval(relogio);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [aberta, acompanhando]);

  const plano = dados?.plano ?? null;
  const observacaoAtual = observacao ?? plano?.observacoes ?? "";
  const aSair = useMemo(() => (plano?.notas ?? []).filter((nota) => !nota.jaEmitida), [plano]);
  const bloqueios = useMemo(() => {
    const todas = [...(plano?.pendenciasGerais ?? []), ...aSair.flatMap((nota) => nota.pendencias)];
    return todas.filter((p) => p.nivel === "bloqueio");
  }, [plano, aSair]);
  const todasAsPendencias = useMemo(() => {
    const vistas = new Set<string>();
    return [...(plano?.pendenciasGerais ?? []), ...aSair.flatMap((nota) => nota.pendencias)].filter((p) => {
      const chave = `${p.codigo}:${p.alvoId ?? ""}`;
      if (vistas.has(chave)) return false;
      vistas.add(chave);
      return true;
    });
  }, [plano, aSair]);

  const saldo = plano?.saldo;
  const temProdutos = aSair.some((nota) => nota.modelo !== "nfse") || (plano?.notas ?? []).some((nota) => nota.modelo !== "nfse");
  const ambosModelos = Boolean(plano?.emissor.modelos.nfe && plano?.emissor.modelos.nfce);
  const modeloAtual = plano?.modeloDeMercadoria ?? null;

  const emitir = async (previa: boolean) => {
    if (!plano) return;
    setEnviando(previa ? "previa" : "emitir");
    setErro(null);
    setPendenciasDoEnvio([]);
    try {
      const json = await pedirFiscal<{ notas: NotaNaTela[] }>(`/api/fiscal/pedidos/${pedidoId}`, {
        method: "POST",
        json: {
          previa,
          escolhas: {
            modeloDeMercadoria: modeloAtual,
            consumidorFinal: plano.consumidorFinal,
            presenca: plano.presenca,
            enviarEmail: enviarEmail ?? plano.enviarEmail,
            /* Vai sempre como texto, mesmo vazio: vazio é "sem observação nesta
               nota", e nulo faria o servidor pôr a do pedido de volta. */
            observacao: observacaoAtual.trim(),
            documento: documento.replace(/\D/g, "") || null,
          },
        },
      });
      setDados((atual) => (atual ? { ...atual, notas: json.notas } : atual));
      if (!previa) setAcompanhando(true);
      aoMudar?.();
      void carregar();
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível emitir.");
      if (e instanceof ErroDaTela) setPendenciasDoEnvio(e.pendencias);
    } finally {
      setEnviando(null);
    }
  };

  const notasDoPedido = dados?.notas ?? [];
  const recentes = notasDoPedido.filter((nota) => nota.status !== "removida");

  return (
    <>
      <Dialog open={aberta} onOpenChange={(v) => !v && aoFechar()}>
        <DialogContent
          hideClose
          className="flex max-h-[94vh] w-[calc(100vw-24px)] max-w-[780px] flex-col gap-0 overflow-hidden rounded-[24px] border-0 bg-[var(--ks-color-bg-elevated)] p-0 shadow-[0_30px_80px_rgba(26,26,43,0.28)]"
        >
          <DialogTitle className="sr-only">Nota fiscal do pedido</DialogTitle>
          <DialogDescription className="sr-only">Emitir e acompanhar as notas fiscais deste pedido.</DialogDescription>

          <header className="flex items-center gap-3 px-6 pb-3 pt-5">
            <span className="flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-violet-500 to-purple-600 text-white shadow-[0_8px_20px_rgba(124,58,237,0.35)]">
              <ReceiptText size={18} />
            </span>
            <div className="min-w-0 flex-1">
              <h2 className="text-lg font-extrabold tracking-tight text-[var(--ks-color-text-primary)]">
                Nota fiscal{plano?.numero ? ` · Pedido #${plano.numero}` : ""}
              </h2>
              {saldo ? (
                <p className="text-xs text-[var(--ks-color-text-muted)]">
                  Pacote de {mesPorExtenso(saldo.competencia)}:{" "}
                  <strong className={`ks-num ${saldo.disponiveis <= 0 ? "text-rose-600" : "text-[var(--ks-color-text-primary)]"}`}>
                    {Math.max(0, saldo.disponiveis)} {saldo.disponiveis === 1 ? "nota disponível" : "notas disponíveis"}
                  </strong>
                  {saldo.entradas > 0 ? ` de ${saldo.entradas}` : ""}
                </p>
              ) : null}
            </div>
            <button
              type="button"
              onClick={aoFechar}
              className="rounded-full p-2 text-[var(--ks-color-text-soft)] transition hover:bg-[var(--ks-color-bg-hover)] hover:text-[var(--ks-color-text-primary)]"
              aria-label="Fechar"
            >
              <X size={18} />
            </button>
          </header>

          <div className="flex-1 space-y-5 overflow-y-auto px-6 pb-5">
            {carregando && !dados ? (
              <div className="flex min-h-[240px] items-center justify-center">
                <Loader2 className="h-7 w-7 animate-spin text-[var(--ks-color-primary)]" />
              </div>
            ) : null}

            {erro ? (
              <Aviso tom="ruim" aoFechar={() => setErro(null)}>
                {erro}
              </Aviso>
            ) : null}
            {pendenciasDoEnvio.length ? (
              <div className="rounded-2xl bg-[var(--ks-color-bg-inset)] px-4 py-1">
                <ListaDePendencias pendencias={pendenciasDoEnvio} contexto={{ clienteId: plano?.clienteId, pedidoId }} />
              </div>
            ) : null}

            {dados && !dados.servidorPronto ? (
              <Aviso tom="neutro" titulo="Emissão de notas indisponível no momento">
                Tente de novo mais tarde. Se continuar assim, fale com o suporte do Ktalogu.
              </Aviso>
            ) : null}

            {plano && !plano.emissor.existe ? (
              <Aviso
                tom="atencao"
                titulo="Configure as notas fiscais primeiro"
                acao={
                  permissoes.configurar ? (
                    <a href="/dashboard/notas-fiscais/configuracao" className="ks-button ks-button-primary ks-button-sm">
                      <Settings2 size={14} />
                      Configurar
                    </a>
                  ) : undefined
                }
              >
                Leva poucos minutos: dados da empresa, certificado digital e como os produtos são tributados.
              </Aviso>
            ) : null}

            {/* Notas que já existem deste pedido */}
            {recentes.length ? (
              <section>
                <h3 className="mb-1 text-[11px] font-bold uppercase tracking-[0.14em] text-[var(--ks-color-text-soft)]">Notas deste pedido</h3>
                <ul>
                  {recentes.map((nota) => (
                    <li
                      key={nota.id}
                      onClick={() => setNotaAberta(nota.id)}
                      className="-mx-2 flex cursor-pointer items-center gap-3 rounded-xl border-t border-slate-100/60 px-2 py-3 transition-colors first:border-t-0 hover:bg-[var(--ks-color-bg-hover)]"
                    >
                      <MarcaDoModelo modelo={nota.modelo} tamanho="sm" />
                      <div className="min-w-0 flex-1">
                        <p className="flex flex-wrap items-center gap-2 text-sm font-bold text-[var(--ks-color-text-primary)]">
                          {nota.modeloNome}
                          {nota.numero ? <span className="ks-num">nº {nota.numero}</span> : null}
                          {nota.semValorFiscal ? <SeloSemValorFiscal /> : null}
                        </p>
                        <p className="truncate text-xs text-[var(--ks-color-text-muted)]">
                          {nota.explicacao && ["rejeitada", "erro", "denegada"].includes(nota.status) ? nota.explicacao.titulo : nota.descricaoDoStatus}
                        </p>
                      </div>
                      <span className="ks-num text-sm font-bold text-[var(--ks-color-text-primary)]">{moeda(nota.valor)}</span>
                      <SeloDoStatus tom={nota.tom} rotulo={nota.rotulo} />
                      {nota.status === "rascunho" ? (
                        <button
                          type="button"
                          onClick={(e) => {
                            e.stopPropagation();
                            window.open(`/api/fiscal/notas/${nota.id}/arquivo?tipo=pdf&previa=1`, "_blank", "noopener,noreferrer");
                          }}
                          className="ks-button ks-button-soft ks-button-sm"
                        >
                          <Eye size={14} />
                          Prévia
                        </button>
                      ) : nota.temArquivos ? (
                        <button
                          type="button"
                          onClick={(e) => {
                            e.stopPropagation();
                            window.open(`/api/fiscal/notas/${nota.id}/arquivo?tipo=pdf`, "_blank", "noopener,noreferrer");
                          }}
                          className="ks-button ks-button-soft ks-button-sm"
                        >
                          <FileText size={14} />
                          PDF
                        </button>
                      ) : null}
                    </li>
                  ))}
                </ul>
              </section>
            ) : null}

            {acompanhando ? (
              <Aviso tom="neutro" titulo="Enviando para a autorização">
                Acompanhando a resposta da SEFAZ e da prefeitura. Pode fechar: a nota continua sendo processada.
              </Aviso>
            ) : null}

            {/* O que vai sair */}
            {plano && plano.emissor.existe && aSair.length ? (
              <section>
                <h3 className="mb-1 text-[11px] font-bold uppercase tracking-[0.14em] text-[var(--ks-color-text-soft)]">
                  {aSair.length === 1 ? "Nota a emitir" : `${aSair.length} notas a emitir`}
                </h3>
                <ul>
                  {aSair.map((nota) => {
                    const aberto = itensAbertos === nota.chave;
                    const bloqueada = nota.pendencias.some((p) => p.nivel === "bloqueio");
                    return (
                      <li key={nota.chave} className="border-t border-slate-100/60 py-3 first:border-t-0">
                        <button type="button" onClick={() => setItensAbertos(aberto ? null : nota.chave)} className="flex w-full items-center gap-3 text-left">
                          <MarcaDoModelo modelo={nota.modelo} tamanho="sm" />
                          <div className="min-w-0 flex-1">
                            <p className="flex flex-wrap items-center gap-2 text-sm font-bold text-[var(--ks-color-text-primary)]">
                              {nota.titulo}
                              {nota.ambienteNota !== "producao" ? <SeloSemValorFiscal /> : null}
                            </p>
                            <p className="text-xs text-[var(--ks-color-text-muted)]">
                              {nota.resumo?.itens.length ?? 0} {nota.resumo?.itens.length === 1 ? "item" : "itens"}
                              {nota.contaCredito ? " · gasta 1 nota do pacote" : " · não gasta nota do pacote"}
                              {nota.existente ? ` · substitui a ${nota.existente.status === "rascunho" ? "prévia" : "tentativa"} anterior` : ""}
                            </p>
                          </div>
                          <span className={`ks-num text-base font-extrabold ${bloqueada ? "text-[var(--ks-color-text-soft)]" : "text-[var(--ks-color-text-primary)]"}`}>
                            {moedaDeCentavos(nota.valor)}
                          </span>
                          <ChevronDown size={16} className={`text-[var(--ks-color-text-soft)] transition-transform ${aberto ? "rotate-180" : ""}`} />
                        </button>
                        {aberto && nota.resumo ? (
                          <div className="mt-3 rounded-2xl bg-[var(--ks-color-bg-inset)] px-4 py-2">
                            <ul className="divide-y divide-slate-100/60">
                              {nota.resumo.itens.map((item, indice) => (
                                <li key={indice} className="flex items-start justify-between gap-3 py-2 text-xs">
                                  <span className="min-w-0 text-[var(--ks-color-text-primary)]">
                                    {item.descricao}
                                    <span className="text-[var(--ks-color-text-soft)]">
                                      {" "}
                                      · {item.quantidade.toLocaleString("pt-BR", { maximumFractionDigits: 4 })} {item.unidade}
                                    </span>
                                  </span>
                                  <span className="ks-num shrink-0 font-semibold text-[var(--ks-color-text-primary)]">{moedaDeCentavos(item.valor)}</span>
                                </li>
                              ))}
                            </ul>
                            <div className="space-y-1 border-t border-slate-100/60 py-2 text-xs text-[var(--ks-color-text-muted)]">
                              {nota.resumo.desconto > 0 ? <Resumo rotulo="Desconto" valor={`− ${moedaDeCentavos(nota.resumo.desconto)}`} /> : null}
                              {nota.resumo.frete > 0 ? <Resumo rotulo="Frete" valor={moedaDeCentavos(nota.resumo.frete)} /> : null}
                              {nota.resumo.outros > 0 ? <Resumo rotulo="Outras despesas" valor={moedaDeCentavos(nota.resumo.outros)} /> : null}
                              {nota.modelo === "nfse" && nota.resumo.impostoDestacado > 0 ? (
                                <Resumo rotulo="ISS" valor={moedaDeCentavos(nota.resumo.impostoDestacado)} />
                              ) : null}
                              {nota.modelo !== "nfse" && nota.resumo.emAberto > 0 ? (
                                <Resumo rotulo="A receber (vai como duplicata)" valor={moedaDeCentavos(nota.resumo.emAberto)} />
                              ) : null}
                            </div>
                          </div>
                        ) : null}
                      </li>
                    );
                  })}
                </ul>
              </section>
            ) : null}

            {plano && plano.emissor.existe && !aSair.length && !recentes.length && !plano.pendenciasGerais.length ? (
              <p className="text-sm text-[var(--ks-color-text-muted)]">Este pedido não tem itens para nota fiscal.</p>
            ) : null}

            {plano && plano.emissor.existe && aSair.length && todasAsPendencias.length ? (
              <section>
                <h3 className="mb-1 text-[11px] font-bold uppercase tracking-[0.14em] text-[var(--ks-color-text-soft)]">
                  {bloqueios.length ? "Falta resolver antes de emitir" : "Para conferir"}
                </h3>
                <ListaDePendencias
                  pendencias={todasAsPendencias}
                  contexto={{ clienteId: plano.clienteId, pedidoId }}
                  acao={(pendencia) => {
                    /* Item sem produto do catálogo: o NCM é informado aqui, só para esta nota. */
                    if (!pendencia.codigo.startsWith("produto.ncm:") || pendencia.alvoId || !permissoes.emitir) return null;
                    const itemId = pendencia.codigo.slice("produto.ncm:".length);
                    return {
                      rotulo: "Informar NCM",
                      aoClicar: () => setNcmDoItem({ itemId, descricao: pendencia.alvoNome ?? pendencia.detalhe ?? "Item" }),
                    };
                  }}
                />
                {ncmDoItem ? (
                  <NcmDoItem
                    pedidoId={pedidoId}
                    item={ncmDoItem}
                    aoFechar={() => setNcmDoItem(null)}
                    aoSalvar={() => {
                      setNcmDoItem(null);
                      void carregar();
                    }}
                  />
                ) : null}
                {bloqueios.length ? (
                  <button type="button" onClick={() => void carregar()} className="mt-1 text-xs font-semibold text-[var(--ks-color-primary)] hover:underline">
                    Já corrigi, conferir de novo
                  </button>
                ) : null}
              </section>
            ) : null}

            {/* Ajustes */}
            {plano && plano.emissor.existe && aSair.length ? (
              <section className="rounded-2xl bg-[var(--ks-color-bg-inset)]">
                <button type="button" onClick={() => setAjustesAbertos((v) => !v)} className="flex w-full items-center justify-between gap-3 px-4 py-3 text-left">
                  <span className="flex items-center gap-2 text-sm font-bold text-[var(--ks-color-text-primary)]">
                    <Settings2 size={15} className="text-[var(--ks-color-primary)]" />
                    Ajustes desta nota
                  </span>
                  <span className="flex items-center gap-2 text-xs text-[var(--ks-color-text-muted)]">
                    {modeloAtual ? (modeloAtual === "nfce" ? "NFC-e" : "NF-e") : ""}
                    {temProdutos && modeloAtual === "nfe" ? ` · ${plano.consumidorFinal ? "consumidor final" : "revenda"}` : ""}
                    {observacaoAtual.trim() ? " · com observação" : ""}
                    <ChevronDown size={16} className={`transition-transform ${ajustesAbertos ? "rotate-180" : ""}`} />
                  </span>
                </button>
                {ajustesAbertos ? (
                  <div className="space-y-4 border-t border-slate-100/60 px-4 pb-4 pt-3">
                    {temProdutos && ambosModelos ? (
                      <div className="space-y-1.5">
                        <p className="text-xs font-semibold text-[var(--ks-color-text-secondary)]">Nota dos produtos</p>
                        <div className="inline-flex rounded-xl bg-[var(--ks-color-bg-elevated)] p-1 shadow-sm">
                          {(["nfe", "nfce"] as const).map((opcao) => (
                            <button
                              key={opcao}
                              type="button"
                              onClick={() => setModelo(opcao)}
                              className={`rounded-lg px-4 py-1.5 text-xs font-bold transition ${
                                modeloAtual === opcao ? "bg-[var(--ks-color-primary)] text-white shadow" : "text-[var(--ks-color-text-muted)] hover:text-[var(--ks-color-text-primary)]"
                              }`}
                            >
                              {opcao === "nfe" ? "NF-e" : "NFC-e (cupom)"}
                            </button>
                          ))}
                        </div>
                      </div>
                    ) : null}

                    {temProdutos && modeloAtual === "nfe" ? (
                      <label className="flex items-center justify-between gap-4">
                        <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 text-[var(--ks-color-text-muted)]">Deixe desligado quando o cliente usa o material (o caso comum).</span>
                        </span>
                        <Switch checked={!plano.consumidorFinal} onCheckedChange={(revende) => setConsumidorFinal(!revende)} />
                      </label>
                    ) : null}

                    <div className="space-y-1.5">
                      <p className="text-xs font-semibold text-[var(--ks-color-text-secondary)]">Como foi a venda</p>
                      <CustomSelect options={PRESENCAS} value={plano.presenca} onChange={(v) => setPresenca(v as Presenca)} />
                    </div>

                    {modeloAtual === "nfce" || !plano.destinatario?.documento ? (
                      <div className="space-y-1.5">
                        <p className="text-xs font-semibold text-[var(--ks-color-text-secondary)]">CPF ou CNPJ na nota</p>
                        <input
                          value={documento}
                          onChange={(e) => setDocumento(e.target.value.replace(/[^\d./-]/g, "").slice(0, 18))}
                          placeholder={plano.destinatario?.documento ? "Usa o do cadastro" : "Opcional na NFC-e"}
                          inputMode="numeric"
                          className="ks-field w-full"
                        />
                      </div>
                    ) : null}

                    {plano.destinatario?.email ? (
                      <label className="flex items-center justify-between gap-4">
                        <span>
                          <span className="block text-sm font-semibold text-[var(--ks-color-text-primary)]">Enviar a nota por e-mail</span>
                          <span className="block text-xs text-[var(--ks-color-text-muted)]">{plano.destinatario.email}</span>
                        </span>
                        <Switch checked={enviarEmail ?? plano.enviarEmail} onCheckedChange={setEnviarEmail} />
                      </label>
                    ) : null}

                    <div className="space-y-1.5">
                      <p className="text-xs font-semibold text-[var(--ks-color-text-secondary)]">Observação na nota (opcional)</p>
                      <textarea
                        value={observacaoAtual}
                        onChange={(e) => setObservacao(e.target.value.slice(0, LIMITE_DAS_OBSERVACOES))}
                        rows={3}
                        className="ks-field w-full resize-y"
                        placeholder="Aparece nas informações complementares"
                      />
                      <p className="text-[11px] text-[var(--ks-color-text-muted)]">
                        Começa com as observações do pedido. O que estiver aqui sai nas informações complementares desta nota.
                      </p>
                    </div>
                  </div>
                ) : null}
              </section>
            ) : null}

          </div>

          {plano && plano.emissor.existe && aSair.length && permissoes.emitir ? (
            <footer className="flex flex-col gap-3 border-t border-[var(--ks-color-border-subtle)] px-6 py-4 sm:flex-row sm:items-center sm:justify-between">
              <p className="text-xs text-[var(--ks-color-text-muted)]">
                {plano.notasQueGastam > 0 ? (
                  <>
                    Gasta{" "}
                    <strong className="ks-num text-[var(--ks-color-text-primary)]">
                      {plano.notasQueGastam} {plano.notasQueGastam === 1 ? "nota" : "notas"}
                    </strong>{" "}
                    do pacote quando {plano.notasQueGastam === 1 ? "for autorizada" : "forem autorizadas"}.
                    {saldo && saldo.disponiveis > 0 && diasParaVirarOMes() <= 3 ? " O pacote zera na virada do mês." : ""}
                  </>
                ) : (
                  <>
                    <Sparkles size={12} className="mr-1 inline text-[var(--ks-color-primary)]" />
                    Notas de teste não gastam o pacote.
                  </>
                )}
              </p>
              <div className="flex gap-2">
                <button
                  type="button"
                  disabled={enviando !== null || bloqueios.filter((p) => p.codigo !== "creditos.sem_saldo").length > 0}
                  onClick={() => void emitir(true)}
                  className="ks-button ks-button-soft"
                  title="Gera o PDF da nota sem emitir"
                >
                  {enviando === "previa" ? <Loader2 size={15} className="animate-spin" /> : <Eye size={15} />}
                  Ver prévia
                </button>
                <button
                  type="button"
                  disabled={enviando !== null || bloqueios.length > 0 || acompanhando}
                  onClick={() => void emitir(false)}
                  className="ks-button ks-button-primary"
                >
                  {enviando === "emitir" ? <Loader2 size={15} className="animate-spin" /> : <Send size={15} />}
                  {aSair.length === 1 ? "Emitir nota" : `Emitir ${aSair.length} notas`}
                </button>
              </div>
            </footer>
          ) : null}
        </DialogContent>
      </Dialog>

      <DetalheDaNota
        notaId={notaAberta}
        aberta={Boolean(notaAberta)}
        aoFechar={() => setNotaAberta(null)}
        aoMudar={() => {
          void recarregarNotas();
          aoMudar?.();
        }}
        telefoneDoCliente={telefoneDoCliente}
        clienteId={plano?.clienteId}
        permissoes={permissoes}
      />
    </>
  );
}

/* O NCM de um item digitado no pedido: pelo número ou procurando pelo nome. */
function NcmDoItem({
  pedidoId,
  item,
  aoFechar,
  aoSalvar,
}: {
  pedidoId: string;
  item: { itemId: string; descricao: string };
  aoFechar: () => void;
  aoSalvar: () => void;
}) {
  const [valor, setValor] = useState("");
  const [resultados, setResultados] = useState<Array<{ codigo: string; descricao: string }>>([]);
  const [procurando, setProcurando] = useState(false);
  const [salvando, setSalvando] = useState(false);
  const [erro, setErro] = useState<string | null>(null);
  const digitos = valor.replace(/\D/g, "");
  const ehNumero = /^[\d.\s-]+$/.test(valor.trim());

  /* Digitou um nome: procura na tabela de NCM (depois que para de digitar). */
  useEffect(() => {
    const termo = valor.trim();
    if (ehNumero || termo.length < 3) {
      setResultados([]);
      return;
    }
    const relogio = setTimeout(async () => {
      setProcurando(true);
      try {
        const json = await pedirFiscal<{ resultados: Array<{ codigo: string; descricao: string }> }>(`/api/fiscal/consultas/ncm?q=${encodeURIComponent(termo)}`);
        setResultados(json.resultados.slice(0, 8));
      } catch {
        setResultados([]);
      } finally {
        setProcurando(false);
      }
    }, 450);
    return () => clearTimeout(relogio);
  }, [valor, ehNumero]);

  const salvar = async (ncm: string) => {
    setSalvando(true);
    setErro(null);
    try {
      await pedirFiscal(`/api/fiscal/pedidos/${pedidoId}`, { method: "PATCH", json: { itemId: item.itemId, ncm } });
      aoSalvar();
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível guardar o NCM.");
    } finally {
      setSalvando(false);
    }
  };

  return (
    <div className="mt-2 rounded-2xl bg-[var(--ks-color-bg-inset)] p-4">
      <p className="text-sm font-bold text-[var(--ks-color-text-primary)]">NCM de “{item.descricao}”</p>
      <p className="mt-0.5 text-xs text-[var(--ks-color-text-muted)]">
        Este item foi digitado no pedido, sem produto do catálogo. O NCM vale só para a nota deste pedido. Digite o número (8 dígitos) ou procure pelo nome.
      </p>
      <div className="mt-3 flex gap-2">
        <input
          autoFocus
          value={valor}
          onChange={(e) => setValor(e.target.value.slice(0, 60))}
          onKeyDown={(e) => {
            if (e.key === "Enter" && digitos.length === 8 && ehNumero) void salvar(digitos);
          }}
          placeholder="Ex.: 3926.40.00 ou placa acrílica"
          className="ks-field min-w-0 flex-1"
          aria-label="NCM ou nome para procurar"
        />
        <button type="button" className="ks-button ks-button-primary" disabled={salvando || !ehNumero || digitos.length !== 8} onClick={() => void salvar(digitos)}>
          {salvando ? <Loader2 size={15} className="animate-spin" /> : null}
          Usar este NCM
        </button>
        <button type="button" className="ks-button ks-button-soft" onClick={aoFechar} disabled={salvando}>
          Cancelar
        </button>
      </div>
      {procurando ? <p className="mt-2 text-xs text-[var(--ks-color-text-muted)]">Procurando…</p> : null}
      {resultados.length ? (
        <ul className="mt-2 divide-y divide-slate-100/60 rounded-xl bg-[var(--ks-color-bg-elevated)]">
          {resultados.map((r) => (
            <li key={r.codigo}>
              <button
                type="button"
                disabled={salvando}
                onClick={() => void salvar(r.codigo)}
                className="flex w-full items-start gap-3 px-3 py-2 text-left text-xs hover:bg-[var(--ks-color-bg-hover)]"
              >
                <span className="ks-num shrink-0 font-bold text-[var(--ks-color-text-primary)]">{r.codigo.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1.$2.$3")}</span>
                <span className="text-[var(--ks-color-text-muted)]">{r.descricao}</span>
              </button>
            </li>
          ))}
        </ul>
      ) : null}
      {erro ? <p className="mt-2 text-xs font-semibold text-rose-600">{erro}</p> : null}
      <p className="mt-2 text-[11px] text-[var(--ks-color-text-soft)]">Na dúvida sobre o número, confirme com o seu contador.</p>
    </div>
  );
}

function Resumo({ rotulo, valor }: { rotulo: string; valor: string }) {
  return (
    <div className="flex items-center justify-between gap-3">
      <span>{rotulo}</span>
      <span className="ks-num font-semibold text-[var(--ks-color-text-primary)]">{valor}</span>
    </div>
  );
}
