"use client";

import { useCallback, useEffect, useState } from "react";
import { AlertTriangle, Ban, Download, Loader2 } 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 { dataCurta, pedirFiscal, SeloDoStatus } from "./comum";
import { Dica } from "./dica";

type Inutilizacao = {
  id: string;
  modelo: "nfe" | "nfce";
  serie: string;
  numero_inicial: number;
  numero_final: number;
  motivo: string;
  status: "processando" | "registrada" | "rejeitada" | "erro";
  protocolo: string | null;
  mensagem: string | null;
  created_at: string;
};

type Painel = {
  inutilizacoes: Inutilizacao[];
  series: { nfe: string; nfce: string; configurada: boolean };
  podeInutilizar: boolean;
};

/**
 * Inutilizar numeração: contar à SEFAZ que uma faixa de números nunca virou
 * nota. Sem isso fica um buraco na sequência, e buraco sem explicação vira
 * multa e trava a escrituração do contador.
 */
export function InutilizarNumeracao({ aberto, aoFechar }: { aberto: boolean; aoFechar: () => void }) {
  const [painel, setPainel] = useState<Painel | null>(null);
  const [modelo, setModelo] = useState<"nfe" | "nfce">("nfe");
  const [serie, setSerie] = useState("");
  const [de, setDe] = useState("");
  const [ate, setAte] = useState("");
  const [motivo, setMotivo] = useState("");
  const [enviando, setEnviando] = useState(false);
  const [erro, setErro] = useState<string | null>(null);
  const [feito, setFeito] = useState<Inutilizacao | null>(null);

  const carregar = useCallback(async () => {
    try {
      const dados = await pedirFiscal<Painel>("/api/fiscal/inutilizacoes");
      setPainel(dados);
      setSerie((antes) => antes || dados.series[modelo] || "1");
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível abrir as inutilizações.");
    }
  }, [modelo]);

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

  useEffect(() => {
    if (painel) setSerie(painel.series[modelo] || "1");
  }, [modelo, painel]);

  const motivoLimpo = motivo.replace(/\s+/g, " ").trim();
  const numeroDe = Number(de);
  const numeroAte = Number(ate || de);
  const faixaValida = Number.isFinite(numeroDe) && numeroDe > 0 && Number.isFinite(numeroAte) && numeroAte >= numeroDe;
  const quantos = faixaValida ? numeroAte - numeroDe + 1 : 0;
  const podeEnviar = faixaValida && motivoLimpo.length >= 15 && Boolean(serie) && !enviando;

  const enviar = async () => {
    setEnviando(true);
    setErro(null);
    try {
      const resposta = await pedirFiscal<{ inutilizacao: Inutilizacao }>("/api/fiscal/inutilizacoes", {
        method: "POST",
        json: { modelo, serie, de: numeroDe, ate: numeroAte, motivo: motivoLimpo },
      });
      setFeito(resposta.inutilizacao);
      setDe("");
      setAte("");
      setMotivo("");
      await carregar();
    } catch (e) {
      setErro(e instanceof Error ? e.message : "A SEFAZ não aceitou a inutilização.");
    } finally {
      setEnviando(false);
    }
  };

  return (
    <Dialog open={aberto} onOpenChange={(v) => !v && aoFechar()}>
      <DialogContent className="max-h-[92vh] w-[calc(100vw-24px)] max-w-[600px] overflow-y-auto rounded-[24px] border-0 bg-[var(--ks-color-bg-elevated)] p-0">
        <div className="space-y-5 p-6">
          <div className="flex items-start gap-3">
            <span className="flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br from-slate-500 to-slate-700 text-white">
              <Ban size={20} />
            </span>
            <div className="min-w-0">
              <DialogTitle className="text-xl font-extrabold tracking-tight text-[var(--ks-color-text-primary)]">
                Inutilizar numeração
              </DialogTitle>
              <DialogDescription className="mt-1 text-sm leading-6 text-[var(--ks-color-text-muted)]">
                Quando um número some da sequência sem virar nota, a Secretaria da Fazenda precisa saber o porquê. É isso que esta tela faz.
              </DialogDescription>
            </div>
          </div>

          {painel && !painel.series.configurada ? (
            <Aviso tom="atencao">Configure as notas fiscais antes de inutilizar numeração.</Aviso>
          ) : null}

          {feito ? (
            <Aviso tom={feito.status === "registrada" ? "bom" : feito.status === "processando" ? "neutro" : "ruim"} aoFechar={() => setFeito(null)}>
              {feito.status === "registrada"
                ? `Números ${feito.numero_inicial} a ${feito.numero_final} da série ${feito.serie} inutilizados na SEFAZ.`
                : feito.status === "processando"
                  ? "Enviado. A SEFAZ ainda está processando; a lista abaixo atualiza quando responder."
                  : feito.mensagem || "A SEFAZ não aceitou."}
            </Aviso>
          ) : null}

          <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
            <label className="block space-y-2">
              <span className="text-sm font-semibold text-[var(--ks-color-text-primary)]">Tipo de nota</span>
              <CustomSelect
                options={[
                  { value: "nfe", label: "Nota de produto (NF-e)" },
                  { value: "nfce", label: "Cupom fiscal (NFC-e)" },
                ]}
                value={modelo}
                onChange={(v) => setModelo(v === "nfce" ? "nfce" : "nfe")}
              />
            </label>
            <label className="block space-y-2">
              <span className="flex items-baseline text-sm font-semibold text-[var(--ks-color-text-primary)]">
                Série
                <Dica titulo="Série">A mesma série em que o número queimou. O sistema já traz a que a empresa usa.</Dica>
              </span>
              <input value={serie} onChange={(e) => setSerie(e.target.value.replace(/\D/g, "").slice(0, 3))} inputMode="numeric" className="ks-field tabular-nums" />
            </label>
            <label className="block space-y-2">
              <span className="text-sm font-semibold text-[var(--ks-color-text-primary)]">Do número</span>
              <input value={de} onChange={(e) => setDe(e.target.value.replace(/\D/g, "").slice(0, 9))} inputMode="numeric" placeholder="Ex.: 42" className="ks-field tabular-nums" />
            </label>
            <label className="block space-y-2">
              <span className="text-sm font-semibold text-[var(--ks-color-text-primary)]">Até o número</span>
              <input
                value={ate}
                onChange={(e) => setAte(e.target.value.replace(/\D/g, "").slice(0, 9))}
                inputMode="numeric"
                placeholder={de || "Ex.: 45"}
                className="ks-field tabular-nums"
              />
            </label>
          </div>

          <label className="block space-y-2">
            <span className="flex items-baseline text-sm font-semibold text-[var(--ks-color-text-primary)]">
              Por que esses números não viraram nota
              <Dica titulo="Motivo">Vai para a SEFAZ do jeito que você escrever. Ex.: falha no envio, numeração pulada pelo sistema anterior.</Dica>
            </span>
            <textarea
              value={motivo}
              onChange={(e) => setMotivo(e.target.value.slice(0, 255))}
              rows={2}
              placeholder="Ex.: Numeração perdida por falha de comunicação no envio."
              className="ks-field resize-none"
            />
            <span className="block text-xs text-[var(--ks-color-text-muted)]">{motivoLimpo.length}/255 · a SEFAZ exige pelo menos 15 letras.</span>
          </label>

          <Aviso tom="atencao" titulo="Confira antes de enviar">
            {quantos > 0
              ? `Vai inutilizar ${quantos === 1 ? "o número" : `${quantos} números`} da série ${serie || "?"}. `
              : ""}
            Número inutilizado nunca mais pode ser usado, e não dá para desfazer. Números que já viraram nota são recusados automaticamente.
          </Aviso>

          {erro ? <Aviso tom="ruim">{erro}</Aviso> : null}

          <div className="flex flex-wrap justify-end gap-2">
            <button type="button" onClick={aoFechar} className="ks-button ks-button-soft">
              Fechar
            </button>
            <button
              type="button"
              onClick={() => void enviar()}
              disabled={!podeEnviar || !painel?.podeInutilizar}
              className="ks-button ks-button-primary"
            >
              {enviando ? <Loader2 size={16} className="animate-spin" /> : <Ban size={16} />}
              Inutilizar na SEFAZ
            </button>
          </div>
          {painel && !painel.podeInutilizar ? (
            <p className="flex items-center gap-1.5 text-xs text-[var(--ks-color-text-soft)]">
              <AlertTriangle size={13} /> Só quem pode cancelar notas inutiliza numeração.
            </p>
          ) : null}

          {painel?.inutilizacoes.length ? (
            <div className="space-y-2 border-t border-[var(--ks-color-border-subtle)] pt-4">
              <p className="text-sm font-bold text-[var(--ks-color-text-primary)]">Já inutilizados</p>
              <ul className="space-y-2">
                {painel.inutilizacoes.map((item) => (
                  <li key={item.id} className="flex flex-wrap items-center justify-between gap-2 rounded-xl bg-[var(--ks-color-bg-inset)] px-3 py-2">
                    <div className="min-w-0">
                      <p className="text-sm font-semibold text-[var(--ks-color-text-primary)]">
                        {item.modelo === "nfe" ? "Nota de produto" : "Cupom fiscal"} · série {item.serie} · nº {item.numero_inicial}
                        {item.numero_final !== item.numero_inicial ? ` a ${item.numero_final}` : ""}
                      </p>
                      <p className="text-xs text-[var(--ks-color-text-muted)]">
                        {dataCurta(item.created_at)} · {item.motivo}
                      </p>
                      {item.mensagem && item.status !== "registrada" ? (
                        <p className="text-xs text-rose-600">{item.mensagem}</p>
                      ) : null}
                    </div>
                    <div className="flex items-center gap-2">
                      <SeloDoStatus
                        tom={item.status === "registrada" ? "bom" : item.status === "processando" ? "andamento" : "ruim"}
                        rotulo={
                          item.status === "registrada"
                            ? "Registrada"
                            : item.status === "processando"
                              ? "Processando"
                              : item.status === "rejeitada"
                                ? "Recusada"
                                : "Falhou"
                        }
                      />
                      {item.status === "registrada" ? (
                        <a href={`/api/fiscal/inutilizacoes/${item.id}?arquivo=xml`} className="ks-button ks-button-soft h-8 px-2 text-xs">
                          <Download size={13} />
                          XML
                        </a>
                      ) : null}
                    </div>
                  </li>
                ))}
              </ul>
            </div>
          ) : null}
        </div>
      </DialogContent>
    </Dialog>
  );
}
