"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import {
  AlertTriangle,
  Ban,
  CheckCircle2,
  ChevronLeft,
  ChevronRight,
  Clock,
  FilePlus2,
  FileText,
  FolderDown,
  Inbox,
  ListChecks,
  Loader2,
  ReceiptText,
  Search,
  Settings2,
  ShoppingBag,
} from "lucide-react";

import {
  dataCurta,
  diasParaVirarOMes,
  documentoFormatado,
  MarcaDoModelo,
  mesPorExtenso,
  moeda,
  pedirFiscal,
  SeloDoStatus,
  SeloSemValorFiscal,
} from "@/components/fiscal/comum";
import { DetalheDaNota } from "@/components/fiscal/detalhe-da-nota";
import { InutilizarNumeracao } from "@/components/fiscal/inutilizar-numeracao";
import { PacoteDoContador } from "@/components/fiscal/pacote-do-contador";
import { Aviso } from "@/components/ui/aviso";
import { CustomSelect } from "@/components/ui/custom-select";
import { Input } from "@/components/ui/input";
import { PageHeader } from "@/components/ui/page-header";
import type { NotaNaTela } from "@/lib/fiscal/servidor/apresentacao";
import { usePermissoes } from "@/lib/permissoes-do-usuario";

type Saldo = { competencia: string; entradas: number; usadas: number; reservadas: number; disponiveis: number };

type Resposta = {
  ambiente: string;
  notas: NotaNaTela[];
  total: number;
  pagina: number;
  porPagina: number;
  contagens: Record<string, number>;
  saldo: Saldo;
};

/* As abas da página, no sublinhado da casa (o mesmo desenho do Estoque). */
const ABAS = [
  { chave: "todas", rotulo: "Todas", icone: ListChecks },
  { chave: "autorizadas", rotulo: "Autorizadas", icone: CheckCircle2 },
  { chave: "andamento", rotulo: "Em andamento", icone: Clock },
  { chave: "problemas", rotulo: "Com problema", icone: AlertTriangle },
  { chave: "canceladas", rotulo: "Canceladas", icone: Ban },
  { chave: "previas", rotulo: "Prévias", icone: FileText },
] as const;

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

  const [dados, setDados] = useState<Resposta | null>(null);
  const [carregando, setCarregando] = useState(true);
  const [erro, setErro] = useState<string | null>(null);
  const [grupo, setGrupo] = useState<(typeof ABAS)[number]["chave"]>("todas");
  const [modelo, setModelo] = useState("");
  const [termo, setTermo] = useState("");
  const [termoAplicado, setTermoAplicado] = useState("");
  const [de, setDe] = useState("");
  const [ate, setAte] = useState("");
  const [pagina, setPagina] = useState(1);
  const [notaAberta, setNotaAberta] = useState<string | null>(null);
  const [pacoteAberto, setPacoteAberto] = useState(false);
  const [inutilizarAberto, setInutilizarAberto] = useState(false);

  useEffect(() => {
    const relogio = setTimeout(() => {
      setTermoAplicado(termo.trim());
      setPagina(1);
    }, 350);
    return () => clearTimeout(relogio);
  }, [termo]);

  const carregar = useCallback(async () => {
    setCarregando(true);
    setErro(null);
    try {
      const busca = new URLSearchParams({ grupo, pagina: String(pagina) });
      if (modelo) busca.set("modelo", modelo);
      if (termoAplicado) busca.set("q", termoAplicado);
      if (de) busca.set("de", de);
      if (ate) busca.set("ate", ate);
      setDados(await pedirFiscal<Resposta>(`/api/fiscal/notas?${busca.toString()}`));
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível carregar as notas.");
    } finally {
      setCarregando(false);
    }
  }, [grupo, modelo, termoAplicado, de, ate, pagina]);

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

  /* Com nota andando, a lista se atualiza sozinha. */
  useEffect(() => {
    if (!dados?.notas.some((nota) => nota.emAndamento)) return;
    const relogio = setInterval(() => void carregar(), 6000);
    return () => clearInterval(relogio);
  }, [dados, carregar]);

  const saldo = dados?.saldo;
  const usoDoPacote = saldo && saldo.entradas > 0 ? Math.min(100, Math.round(((saldo.usadas + saldo.reservadas) / saldo.entradas) * 100)) : 0;
  const diasParaZerar = diasParaVirarOMes();
  const totalPaginas = dados ? Math.max(1, Math.ceil(dados.total / dados.porPagina)) : 1;
  const nenhumaNotaNunca = useMemo(
    () => Boolean(dados && dados.total === 0 && grupo === "todas" && !modelo && !termoAplicado && !de && !ate),
    [dados, grupo, modelo, termoAplicado, de, ate]
  );

  return (
    <div className="space-y-6">
      <PageHeader
        eyebrow="Notas fiscais"
        title="Emissão de notas"
        subtitle="Emita nota com ou sem pedido e acompanhe todas as notas da empresa."
        actions={
          <div className="flex flex-wrap items-center gap-2">
            <button type="button" onClick={() => setPacoteAberto(true)} className="ks-button ks-button-soft" title="Baixar os XMLs do período">
              <FolderDown size={16} />
              Pacote do contador
            </button>
            {permissoes.recebidas ? (
              <Link href="/dashboard/notas-fiscais/recebidas" className="ks-button ks-button-soft">
                <Inbox size={16} />
                Notas recebidas
              </Link>
            ) : null}
            {permissoes.cancelar ? (
              <button type="button" onClick={() => setInutilizarAberto(true)} className="ks-button ks-button-soft" title="Avisar a SEFAZ sobre números que não viraram nota">
                <Ban size={16} />
                Inutilizar numeração
              </button>
            ) : null}
            {permissoes.configurar ? (
              <Link href="/dashboard/notas-fiscais/configuracao" className="ks-button ks-button-soft">
                <Settings2 size={16} />
                Configuração
              </Link>
            ) : null}
          </div>
        }
      />

      {/* O pacote do mês */}
      {saldo ? (
        <section className="flex flex-col gap-4 rounded-2xl bg-[var(--ks-color-bg-elevated)] px-5 py-4 shadow-[0_10px_30px_rgba(26,26,43,0.06)] sm:flex-row sm:items-center">
          <div className="flex items-center gap-4">
            <span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-gradient-to-br from-violet-500 to-purple-600 text-white shadow-[0_10px_24px_rgba(124,58,237,0.32)]">
              <ReceiptText size={22} />
            </span>
            <div>
              <p className="text-[11px] font-bold uppercase tracking-[0.14em] text-[var(--ks-color-text-soft)]">
                Pacote de {mesPorExtenso(saldo.competencia)}
              </p>
              <p className="flex items-baseline gap-1.5">
                <span className={`ks-num text-3xl font-extrabold ${saldo.disponiveis <= 0 ? "text-rose-600" : "text-[var(--ks-color-text-primary)]"}`}>
                  {Math.max(0, saldo.disponiveis)}
                </span>
                <span className="text-sm text-[var(--ks-color-text-muted)]">
                  {saldo.disponiveis === 1 ? "nota disponível" : "notas disponíveis"}
                  {saldo.entradas > 0 ? ` de ${saldo.entradas}` : ""}
                </span>
              </p>
            </div>
          </div>
          <div className="min-w-0 flex-1 sm:px-4">
            <div className="h-2 overflow-hidden rounded-full bg-[var(--ks-color-bg-inset)]">
              <div
                className={`h-full rounded-full ${usoDoPacote >= 90 ? "bg-gradient-to-r from-rose-500 to-red-600" : "bg-gradient-to-r from-violet-500 to-purple-600"}`}
                style={{ width: `${usoDoPacote}%` }}
              />
            </div>
            <p className="mt-1.5 text-xs text-[var(--ks-color-text-muted)]">
              <span className="ks-num font-semibold text-[var(--ks-color-text-primary)]">{saldo.usadas}</span> usadas
              {saldo.reservadas > 0 ? (
                <>
                  {" "}
                  · <span className="ks-num font-semibold text-[var(--ks-color-text-primary)]">{saldo.reservadas}</span> aguardando autorização
                </>
              ) : null}
              {saldo.entradas > 0 ? ` · zera em ${diasParaZerar === 0 ? "menos de um dia" : `${diasParaZerar} ${diasParaZerar === 1 ? "dia" : "dias"}`}` : ""}
            </p>
          </div>
          <Link href="/dashboard/assinatura#notas" className="ks-button ks-button-primary shrink-0">
            <ShoppingBag size={16} />
            {saldo.entradas === 0 ? "Comprar pacote" : "Comprar mais"}
          </Link>
        </section>
      ) : null}

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

      {/* Abas no sublinhado da casa, fora da superfície — como no Estoque. */}
      <div className="flex items-center gap-6 overflow-x-auto border-b border-[var(--ks-color-border-subtle)] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
        {ABAS.map(({ chave, rotulo, icone: Icone }) => {
          const contagem = chave === "todas" ? null : dados?.contagens?.[chave] ?? 0;
          const ativa = grupo === chave;
          return (
            <button
              key={chave}
              type="button"
              onClick={() => {
                setGrupo(chave);
                setPagina(1);
              }}
              className={`-mb-px flex shrink-0 items-center gap-2 whitespace-nowrap border-b-2 pb-3 text-sm font-semibold transition-colors ${
                ativa
                  ? "border-[var(--ks-color-primary)] text-[var(--ks-color-primary)]"
                  : "border-transparent text-[var(--ks-color-text-soft)] hover:text-[var(--ks-color-text-primary)]"
              }`}
            >
              <Icone className="h-4 w-4" />
              {rotulo}
              {contagem ? (
                <span
                  className={`ks-num rounded-full px-1.5 text-[11px] font-bold ${
                    chave === "problemas" ? "bg-rose-500 text-white" : ativa ? "bg-[var(--ks-color-primary)] text-white" : "bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-muted)]"
                  }`}
                >
                  {contagem}
                </span>
              ) : null}
            </button>
          );
        })}
      </div>

      <div className="ks-surface overflow-hidden rounded-xl border border-[var(--ks-color-border-subtle)] shadow-sm">
        {/* A barra do Estoque: busca, filtros finos, contadores de relance e a ação principal. */}
        <div className="flex flex-wrap items-center justify-between gap-x-4 gap-y-3 border-b border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-subtle)]/30 p-4">
          {/* Dois grupos: o que filtra à esquerda, o que resume e age à direita.
              Sem espaço, o grupo da direita desce inteiro — em vez de o botão cair sozinho. */}
          <div className="flex min-w-0 flex-1 flex-wrap items-center gap-2">
            <div className="relative min-w-[200px] max-w-[260px] flex-1">
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
              <Input placeholder="Buscar por número, chave, cliente ou CPF/CNPJ" value={termo} onChange={(e) => setTermo(e.target.value)} className="pl-9" />
            </div>
            <div className="w-36">
              <CustomSelect
                size="sm"
                options={[
                  { value: "", label: "Todos os modelos" },
                  { value: "nfe", label: "NF-e" },
                  { value: "nfce", label: "NFC-e" },
                  { value: "nfse", label: "NFS-e" },
                ]}
                value={modelo}
                onChange={(v) => {
                  setModelo(v);
                  setPagina(1);
                }}
              />
            </div>
            <div className="flex items-center gap-2 text-xs text-[var(--ks-color-text-muted)]">
              <input
                type="date"
                value={de}
                onChange={(e) => {
                  setDe(e.target.value);
                  setPagina(1);
                }}
                className="ks-field h-9 w-[8.75rem]"
                aria-label="De"
              />
              até
              <input
                type="date"
                value={ate}
                onChange={(e) => {
                  setAte(e.target.value);
                  setPagina(1);
                }}
                className="ks-field h-9 w-[8.75rem]"
                aria-label="Até"
              />
            </div>
          </div>
          <div className="flex flex-wrap items-center gap-x-4 gap-y-2">
            <div className="flex items-center gap-4 text-xs font-medium text-slate-500">
              <span className="flex items-center gap-1.5">
                <span className="h-1.5 w-1.5 rounded-full bg-emerald-500" />
                <span className="ks-num">{dados?.contagens?.autorizadas ?? 0}</span> autorizadas
              </span>
              <span className="flex items-center gap-1.5">
                <span className="h-1.5 w-1.5 rounded-full bg-[var(--ks-color-primary)]" />
                <span className="ks-num">{dados?.contagens?.andamento ?? 0}</span> em andamento
              </span>
              <span className="flex items-center gap-1.5">
                <span className="h-1.5 w-1.5 rounded-full bg-rose-500" />
                <span className="ks-num">{dados?.contagens?.problemas ?? 0}</span> com problema
              </span>
              {carregando ? <Loader2 className="h-4 w-4 animate-spin text-[var(--ks-color-primary)]" /> : null}
            </div>
            {permissoes.emitir ? (
              <Link href="/dashboard/notas-fiscais/emitir" className="ks-button ks-button-primary">
                <FilePlus2 size={16} />
                Emitir nota fiscal
              </Link>
            ) : null}
          </div>
        </div>

        {!dados && carregando ? (
          <div className="flex justify-center py-16">
            <Loader2 className="h-8 w-8 animate-spin text-[var(--ks-color-primary)]" />
          </div>
        ) : nenhumaNotaNunca ? (
          <div className="flex flex-col items-center justify-center px-6 py-16 text-center">
            <span className="mb-4 flex h-16 w-16 items-center justify-center rounded-3xl bg-gradient-to-br from-violet-500 to-purple-600 text-white shadow-[0_14px_30px_rgba(124,58,237,0.32)]">
              <ReceiptText size={28} />
            </span>
            <h3 className="text-lg font-bold text-[var(--ks-color-text-primary)]">Nenhuma nota emitida ainda</h3>
            <p className="mt-1 max-w-md text-sm text-[var(--ks-color-text-muted)]">
              Emita aqui, no botão <strong>Emitir nota fiscal</strong>, ou direto do pedido. No PDV, o cupom fiscal sai junto com a venda.
            </p>
            <div className="mt-5 flex flex-wrap justify-center gap-2">
              {permissoes.emitir ? (
                <Link href="/dashboard/notas-fiscais/emitir" className="ks-button ks-button-primary">
                  <FilePlus2 size={16} />
                  Emitir nota fiscal
                </Link>
              ) : null}
              {permissoes.configurar ? (
                <Link href="/dashboard/notas-fiscais/configuracao" className="ks-button ks-button-soft">
                  <Settings2 size={16} />
                  Configurar notas fiscais
                </Link>
              ) : null}
              <Link href="/dashboard/orders" className="ks-button ks-button-soft">
                Ir para os pedidos
              </Link>
            </div>
          </div>
        ) : dados && dados.notas.length === 0 ? (
          <p className="px-6 py-12 text-center text-sm text-[var(--ks-color-text-muted)]">Nenhuma nota com esses filtros.</p>
        ) : dados ? (
          <div className="overflow-x-auto">
            <div className="min-w-[860px]">
              <div className="grid grid-cols-[minmax(0,1.1fr)_minmax(0,1fr)_90px_100px_120px_130px_52px] gap-3 px-6 py-3 text-[10px] font-semibold uppercase tracking-[0.14em] text-slate-400">
                <span>Nota</span>
                <span>Cliente</span>
                <span>Pedido</span>
                <span>Data</span>
                <span className="text-right">Valor</span>
                <span>Situação</span>
                <span />
              </div>
              {dados.notas.map((nota) => (
                <div
                  key={nota.id}
                  onClick={() => setNotaAberta(nota.id)}
                  className="grid cursor-pointer grid-cols-[minmax(0,1.1fr)_minmax(0,1fr)_90px_100px_120px_130px_52px] items-center gap-3 border-t border-slate-100/60 px-6 py-3.5 transition-colors hover:bg-[var(--ks-color-bg-subtle)]/50"
                >
                  <div className="flex min-w-0 items-center gap-3">
                    <MarcaDoModelo modelo={nota.modelo} />
                    <div className="min-w-0">
                      <p className="flex items-center gap-2 truncate text-sm font-semibold 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-[11px] text-[var(--ks-color-text-soft)]">
                        {nota.explicacao && ["rejeitada", "erro", "denegada"].includes(nota.status)
                          ? nota.explicacao.titulo
                          : nota.serie
                            ? `série ${nota.serie}`
                            : nota.origem === "teste"
                              ? "nota de teste"
                              : "sem número ainda"}
                      </p>
                    </div>
                  </div>
                  <div className="min-w-0">
                    <p className="truncate text-sm text-[var(--ks-color-text-primary)]">{nota.destinatarioNome || "Consumidor"}</p>
                    {nota.destinatarioDocumento ? (
                      <p className="truncate text-[11px] text-[var(--ks-color-text-soft)]">{documentoFormatado(nota.destinatarioDocumento)}</p>
                    ) : null}
                  </div>
                  <div className="text-sm">
                    {nota.pedidoId && nota.pedidoNumero ? (
                      <Link
                        href={`/dashboard/orders/${nota.pedidoId}?aba=financeiro`}
                        onClick={(e) => e.stopPropagation()}
                        className="font-semibold text-[var(--ks-color-primary)] hover:underline"
                      >
                        #{nota.pedidoNumero}
                      </Link>
                    ) : nota.semPedido ? (
                      <span className="text-xs text-[var(--ks-color-text-soft)]">sem pedido</span>
                    ) : (
                      <span className="text-[var(--ks-color-text-soft)]">—</span>
                    )}
                  </div>
                  <div className="text-sm text-[var(--ks-color-text-muted)]">{dataCurta(nota.autorizadaEm || nota.criadaEm)}</div>
                  <div className="ks-num text-right text-sm font-semibold text-[var(--ks-color-text-primary)]">{moeda(nota.valor)}</div>
                  <div>
                    <SeloDoStatus tom={nota.tom} rotulo={nota.rotulo} titulo={nota.descricaoDoStatus} />
                  </div>
                  <div className="flex justify-end">
                    {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-ghost ks-button-sm"
                        title="Abrir o PDF"
                      >
                        <FileText size={15} />
                      </button>
                    ) : null}
                  </div>
                </div>
              ))}
            </div>
          </div>
        ) : null}

        {dados && dados.total > dados.porPagina ? (
          <div className="flex items-center justify-between gap-3 border-t border-[var(--ks-color-border-subtle)] px-4 py-3 text-xs text-[var(--ks-color-text-muted)]">
            <span className="ks-num">
              {(dados.pagina - 1) * dados.porPagina + 1}–{Math.min(dados.total, dados.pagina * dados.porPagina)} de {dados.total}
            </span>
            <div className="flex gap-2">
              <button type="button" disabled={pagina <= 1} onClick={() => setPagina((p) => Math.max(1, p - 1))} className="ks-button ks-button-soft ks-button-sm">
                <ChevronLeft size={14} />
                Anterior
              </button>
              <button type="button" disabled={pagina >= totalPaginas} onClick={() => setPagina((p) => p + 1)} className="ks-button ks-button-soft ks-button-sm">
                Próxima
                <ChevronRight size={14} />
              </button>
            </div>
          </div>
        ) : null}
      </div>

      <DetalheDaNota
        notaId={notaAberta}
        aberta={Boolean(notaAberta)}
        aoFechar={() => setNotaAberta(null)}
        aoMudar={() => void carregar()}
        permissoes={permissoes}
      />

      <PacoteDoContador aberto={pacoteAberto} aoFechar={() => setPacoteAberto(false)} />
      {permissoes.cancelar ? (
        <InutilizarNumeracao
          aberto={inutilizarAberto}
          aoFechar={() => {
            setInutilizarAberto(false);
            void carregar();
          }}
        />
      ) : null}
    </div>
  );
}
