"use client";

import { useCallback, useEffect, useState } from "react";
import { Download, FolderDown, Loader2 } from "lucide-react";

import { Aviso } from "@/components/ui/aviso";
import { Dialog, DialogContent, DialogDescription, DialogTitle } from "@/components/ui/dialog";

import { pedirFiscal } from "./comum";
import { Dica } from "./dica";

/**
 * "Me manda os XMLs do mês": o pedido que todo contador faz e que, sem isto,
 * obrigava a abrir nota por nota.
 *
 * Entram as notas autorizadas e as canceladas do período — as duas são
 * escrituradas. O DANFE em PDF é opcional porque o contador raramente precisa
 * dele, e as notas recebidas entram em uma pasta separada.
 */
export function PacoteDoContador({ aberto, aoFechar }: { aberto: boolean; aoFechar: () => void }) {
  const hoje = new Date();
  const primeiroDoMes = new Date(Date.UTC(hoje.getUTCFullYear(), hoje.getUTCMonth(), 1)).toISOString().slice(0, 10);
  const ultimoDoMes = new Date(Date.UTC(hoje.getUTCFullYear(), hoje.getUTCMonth() + 1, 0)).toISOString().slice(0, 10);

  const [de, setDe] = useState(primeiroDoMes);
  const [ate, setAte] = useState(ultimoDoMes);
  const [comPdf, setComPdf] = useState(false);
  const [comRecebidas, setComRecebidas] = useState(true);
  const [quantas, setQuantas] = useState<number | null>(null);
  const [contando, setContando] = useState(false);
  const [baixando, setBaixando] = useState(false);
  const [erro, setErro] = useState<string | null>(null);

  const contar = useCallback(async () => {
    setContando(true);
    setErro(null);
    try {
      const resposta = await pedirFiscal<{ notas: number }>(`/api/fiscal/exportar?contar=1&de=${de}&ate=${ate}`);
      setQuantas(resposta.notas);
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não deu para contar as notas do período.");
    } finally {
      setContando(false);
    }
  }, [de, ate]);

  useEffect(() => {
    if (!aberto) return;
    const relogio = setTimeout(() => void contar(), 250);
    return () => clearTimeout(relogio);
  }, [aberto, contar]);

  const baixar = async () => {
    setBaixando(true);
    setErro(null);
    try {
      const busca = new URLSearchParams({ de, ate });
      if (comPdf) busca.set("pdf", "1");
      if (comRecebidas) busca.set("recebidas", "1");
      const resposta = await fetch(`/api/fiscal/exportar?${busca.toString()}`, { cache: "no-store" });
      if (!resposta.ok) {
        const corpo = (await resposta.json().catch(() => null)) as { error?: string } | null;
        throw new Error(corpo?.error || "Não foi possível montar o pacote.");
      }
      const arquivo = await resposta.blob();
      const nome = resposta.headers.get("Content-Disposition")?.match(/filename="([^"]+)"/)?.[1] ?? "notas-fiscais.zip";
      const endereco = URL.createObjectURL(arquivo);
      const link = document.createElement("a");
      link.href = endereco;
      link.download = nome;
      document.body.appendChild(link);
      link.click();
      link.remove();
      setTimeout(() => URL.revokeObjectURL(endereco), 30_000);
      aoFechar();
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível montar o pacote.");
    } finally {
      setBaixando(false);
    }
  };

  return (
    <Dialog open={aberto} onOpenChange={(v) => !v && aoFechar()}>
      <DialogContent className="w-[calc(100vw-24px)] max-w-[520px] 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-violet-500 to-purple-600 text-white">
              <FolderDown size={20} />
            </span>
            <div className="min-w-0">
              <DialogTitle className="text-xl font-extrabold tracking-tight text-[var(--ks-color-text-primary)]">
                Pacote para o contador
              </DialogTitle>
              <DialogDescription className="mt-1 text-sm leading-6 text-[var(--ks-color-text-muted)]">
                Todos os arquivos das notas do período em um download só, separados por tipo de nota.
              </DialogDescription>
            </div>
          </div>

          <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)]">De</span>
              <input type="date" value={de} onChange={(e) => setDe(e.target.value)} className="ks-field" />
            </label>
            <label className="block space-y-2">
              <span className="text-sm font-semibold text-[var(--ks-color-text-primary)]">Até</span>
              <input type="date" value={ate} onChange={(e) => setAte(e.target.value)} className="ks-field" />
            </label>
          </div>

          <div className="space-y-2 rounded-2xl bg-[var(--ks-color-bg-inset)] p-4">
            <label className="flex cursor-pointer items-start gap-3">
              <input type="checkbox" checked={comPdf} onChange={(e) => setComPdf(e.target.checked)} className="mt-0.5 h-4 w-4 accent-[var(--ks-color-primary)]" />
              <span className="text-sm text-[var(--ks-color-text-primary)]">
                Levar também o PDF de cada nota
                <span className="block text-xs text-[var(--ks-color-text-muted)]">O contador costuma precisar só do XML. Com PDF, o arquivo fica maior.</span>
              </span>
            </label>
            <label className="flex cursor-pointer items-start gap-3">
              <input
                type="checkbox"
                checked={comRecebidas}
                onChange={(e) => setComRecebidas(e.target.checked)}
                className="mt-0.5 h-4 w-4 accent-[var(--ks-color-primary)]"
              />
              <span className="text-sm text-[var(--ks-color-text-primary)]">
                Levar as notas recebidas de fornecedores
                <span className="block text-xs text-[var(--ks-color-text-muted)]">Só as que já estão completas; o resumo da SEFAZ não serve para escrituração.</span>
              </span>
            </label>
          </div>

          <p className="flex items-center text-sm text-[var(--ks-color-text-muted)]">
            {contando ? (
              <>
                <Loader2 size={14} className="mr-2 animate-spin" /> Contando as notas do período…
              </>
            ) : quantas === null ? (
              "Escolha o período."
            ) : quantas === 0 ? (
              "Nenhuma nota autorizada nesse período."
            ) : (
              <>
                <span className="ks-num font-bold text-[var(--ks-color-text-primary)]">{quantas}</span>
                <span className="ml-1">{quantas === 1 ? "nota entra no pacote" : "notas entram no pacote"}</span>
                <Dica titulo="O que entra">
                  Entram as notas autorizadas e as canceladas — as duas são escrituradas. Prévias e recusadas ficam de fora, porque não
                  existem para a contabilidade.
                </Dica>
              </>
            )}
          </p>

          {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 baixar()} disabled={baixando || quantas === 0} className="ks-button ks-button-primary">
              {baixando ? <Loader2 size={16} className="animate-spin" /> : <Download size={16} />}
              {baixando ? "Montando o pacote…" : "Baixar pacote"}
            </button>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
