import { notaParaTela } from "@/lib/fiscal/servidor/apresentacao";
import { saldoDoMes } from "@/lib/fiscal/servidor/base";
import type { NotaGuardada } from "@/lib/fiscal/servidor/notas";
import { rotaFiscal } from "@/lib/fiscal/servidor/rota";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

const GRUPOS: Record<string, string[]> = {
  autorizadas: ["autorizada", "contingencia"],
  andamento: ["preparando", "enviando", "processando", "cancelando"],
  problemas: ["rejeitada", "erro", "denegada"],
  canceladas: ["cancelada"],
  previas: ["rascunho"],
};

const POR_PAGINA = 50;

export async function GET(req: Request) {
  return rotaFiscal("fiscal.ver", async ({ admin, empresaId, ambiente }) => {
    const busca = new URL(req.url).searchParams;
    const grupo = busca.get("grupo") ?? "todas";
    const modelo = busca.get("modelo");
    const de = busca.get("de");
    const ate = busca.get("ate");
    const termo = (busca.get("q") ?? "").trim();
    const pagina = Math.max(1, Number(busca.get("pagina")) || 1);

    let consulta = admin
      .from("fiscal_notas")
      .select("*", { count: "exact" })
      .eq("empresa_id", empresaId)
      .eq("ambiente", ambiente)
      .neq("status", "removida")
      .order("created_at", { ascending: false })
      .range((pagina - 1) * POR_PAGINA, pagina * POR_PAGINA - 1);

    if (GRUPOS[grupo]) consulta = consulta.in("status", GRUPOS[grupo]);
    if (modelo === "nfe" || modelo === "nfce" || modelo === "nfse") consulta = consulta.eq("modelo", modelo);
    if (de && /^\d{4}-\d{2}-\d{2}$/.test(de)) consulta = consulta.gte("created_at", `${de}T00:00:00-03:00`);
    if (ate && /^\d{4}-\d{2}-\d{2}$/.test(ate)) consulta = consulta.lte("created_at", `${ate}T23:59:59.999-03:00`);
    if (termo) {
      const digitos = termo.replace(/\D/g, "");
      const limpo = termo.replace(/[%,()]/g, " ").trim();
      const filtros = [`destinatario->>nome.ilike.%${limpo}%`];
      if (digitos) {
        if (digitos.length <= 9) filtros.push(`numero.eq.${Number(digitos)}`);
        filtros.push(`chave.ilike.%${digitos}%`, `destinatario->>documento.ilike.%${digitos}%`);
      }
      consulta = consulta.or(filtros.join(","));
    }

    const { data, count, error } = await consulta;
    if (error) throw new Error(error.message);
    const notas = (data ?? []) as NotaGuardada[];

    const pedidoIds = [...new Set(notas.map((n) => n.pedido_id).filter((id): id is string => Boolean(id)))];
    const numeros = new Map<string, number | null>();
    if (pedidoIds.length) {
      const { data: pedidos } = await admin.from("orders").select("id,number").in("id", pedidoIds).eq("user_id", empresaId);
      for (const pedido of (pedidos ?? []) as Array<{ id: string; number: number | null }>) numeros.set(pedido.id, pedido.number);
    }

    const [saldo, contagens] = await Promise.all([
      saldoDoMes(admin, empresaId, ambiente),
      Promise.all(
        Object.entries(GRUPOS).map(async ([chave, status]) => {
          const { count: total } = await admin
            .from("fiscal_notas")
            .select("id", { count: "exact", head: true })
            .eq("empresa_id", empresaId)
            .eq("ambiente", ambiente)
            .in("status", status);
          return [chave, total ?? 0] as const;
        })
      ),
    ]);

    return {
      ambiente,
      notas: notas.map((nota) => notaParaTela(nota, { pedidoNumero: nota.pedido_id ? numeros.get(nota.pedido_id) ?? null : null })),
      total: count ?? 0,
      pagina,
      porPagina: POR_PAGINA,
      contagens: Object.fromEntries(contagens),
      saldo,
    };
  });
}
