import { useCallback, useEffect, useMemo, useState } from "react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import {
  ArrowLeft,
  ChevronLeft,
  ChevronRight,
  Download,
  ExternalLink,
  Landmark,
  Loader2,
  Wallet,
} from "lucide-react";
import { toast } from "sonner";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import {
  fechamentoBancoPontosService,
  type BancoPontosExtratoItem,
  type BancoPontosParceiroExtrato,
} from "@/services/fechamento/bancoPontos";

const PER_PAGE = 20;

function formatPontos(valor: number): string {
  return valor.toLocaleString("pt-BR", { minimumFractionDigits: 0, maximumFractionDigits: 4 });
}

function formatData(iso: string): string {
  try {
    const d = new Date(iso);
    return d.toLocaleString("pt-BR", {
      day: "2-digit",
      month: "2-digit",
      year: "numeric",
      hour: "2-digit",
      minute: "2-digit",
    });
  } catch {
    return iso;
  }
}

/** Competência do fechamento (mês/ano), quando a API envia `competenciaMes` e `competenciaAno`. */
function formatCompetenciaMesAno(mes: number | null, ano: number | null): string {
  if (mes == null || ano == null) return "—";
  const m = Math.trunc(Number(mes));
  const y = Math.trunc(Number(ano));
  if (!Number.isFinite(m) || !Number.isFinite(y) || m < 1 || m > 12) return "—";
  return `${String(m).padStart(2, "0")}/${y}`;
}

type ExtratoLocationState = { nomeExibicao?: string };

function nomeExibicaoParceiro(p: BancoPontosParceiroExtrato): string {
  return p.codinome?.trim() ? `${p.nome} (${p.codinome.trim()})` : p.nome;
}

export default function BancoPontosExtrato() {
  const navigate = useNavigate();
  const location = useLocation();
  const { parceiroId = "" } = useParams();
  const nomeDoState = (location.state as ExtratoLocationState | null)?.nomeExibicao?.trim();
  const [loading, setLoading] = useState(true);
  const [exportando, setExportando] = useState(false);
  const [parceiro, setParceiro] = useState<BancoPontosParceiroExtrato | null>(null);
  const [linhas, setLinhas] = useState<BancoPontosExtratoItem[]>([]);
  const [meta, setMeta] = useState({ total: 0, paginaAtual: 1, totalPaginas: 1 });
  const [page, setPage] = useState(1);

  const load = useCallback(async () => {
    if (!parceiroId) return;
    try {
      setLoading(true);
      const res = await fechamentoBancoPontosService.listarExtrato(parceiroId, {
        page,
        perPage: PER_PAGE,
      });
      setParceiro(res.parceiro);
      setLinhas(res.data ?? []);
      setMeta(res.meta);
    } catch (e) {
      const msg = e instanceof Error ? e.message : "Erro ao carregar extrato.";
      toast.error(msg);
      setParceiro(null);
      setLinhas([]);
    } finally {
      setLoading(false);
    }
  }, [parceiroId, page]);

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

  useEffect(() => {
    setPage(1);
    setMeta({ total: 0, paginaAtual: 1, totalPaginas: 1 });
  }, [parceiroId]);

  const tituloParceiro = parceiro
    ? nomeExibicaoParceiro(parceiro)
    : nomeDoState ?? (loading ? "Carregando…" : "Parceiro");

  const saldoAtual = parceiro != null ? Number(parceiro.saldo ?? 0) : null;
  const saldoFormatado =
    parceiro != null && saldoAtual !== null && Number.isFinite(saldoAtual) ? formatPontos(saldoAtual) : null;
  const linhasOrdenadas = useMemo(
    () =>
      [...linhas].sort((a, b) => {
        const timeA = new Date(a.criadoEm).getTime();
        const timeB = new Date(b.criadoEm).getTime();
        if (Number.isNaN(timeA) || Number.isNaN(timeB)) {
          return String(a.criadoEm).localeCompare(String(b.criadoEm));
        }
        return timeA - timeB;
      }),
    [linhas],
  );

  const intervaloLabel = (() => {
    if (meta.total === 0) return "Mostrando 0 de 0";
    const inicio = (page - 1) * PER_PAGE + 1;
    const fim = Math.min(page * PER_PAGE, meta.total);
    return `Mostrando ${inicio}–${fim} de ${meta.total}`;
  })();

  const handleExportarXlsx = async () => {
    if (!parceiroId) return;
    try {
      setExportando(true);
      const { buffer, filename } = await fechamentoBancoPontosService.exportarExtrato(parceiroId);
      const blob = new Blob([buffer], {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = filename ?? `banco-pontos-${parceiroId}.xlsx`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
      toast.success("Planilha exportada com sucesso.");
    } catch (e) {
      const msg = e instanceof Error ? e.message : "Erro ao exportar extrato.";
      toast.error(msg);
    } finally {
      setExportando(false);
    }
  };

  return (
    <div className="flex h-full flex-col bg-background pb-16 md:pb-0">
      <div className="border-b border-border bg-muted/20 p-3 md:p-6">
        <div className="mb-3">
          <Button variant="ghost" size="sm" onClick={() => navigate("/fechamento/banco-pontos")}>
            <ArrowLeft className="mr-1 h-4 w-4" />
            Voltar ao banco de pontos
          </Button>
        </div>

        <div className="flex flex-col gap-4">
          <div className="min-w-0">
            <h1 className="flex flex-wrap items-center gap-2 text-xl font-bold text-foreground md:text-3xl">
              <Landmark className="h-5 w-5 md:h-6 md:w-6" />
              <span className="truncate">Extrato — {tituloParceiro}</span>
            </h1>
            <p className="mt-1 text-sm text-muted-foreground">
              Histórico de créditos e débitos (mais antigos primeiro).
            </p>
            {loading ? (
              <p className="mt-3 text-sm text-muted-foreground">Carregando saldo atual…</p>
            ) : parceiro != null && saldoFormatado != null ? (
              <div className="mt-3 flex flex-wrap items-baseline gap-2 rounded-lg border border-border/80 bg-muted/30 px-3 py-2 md:px-4 md:py-3">
                <div className="flex items-center gap-2 text-muted-foreground">
                  <Wallet className="h-4 w-4 shrink-0" />
                  <span className="text-xs font-semibold uppercase tracking-wide">Saldo atual</span>
                </div>
                <span
                  className={`text-2xl font-bold tabular-nums md:text-3xl ${
                    (saldoAtual ?? 0) >= 0 ? "text-emerald-600" : "text-red-600"
                  }`}
                >
                  {saldoFormatado}
                </span>
                <span className="text-xs text-muted-foreground">pontos</span>
              </div>
            ) : null}
          </div>
        </div>
      </div>

      <div className="flex-1 space-y-4 p-3 md:p-6">
        <div className="flex flex-wrap items-center justify-end gap-2">
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="border-border bg-background text-foreground hover:bg-muted/50 hover:text-foreground"
            disabled={!parceiroId || exportando}
            onClick={() => void handleExportarXlsx()}
          >
            {exportando ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <Download className="h-4 w-4" />
            )}
            Exportar XLSX
          </Button>
        </div>

        <div className="overflow-x-auto rounded-lg border">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="min-w-[150px]">Data</TableHead>
                <TableHead className="min-w-[110px] whitespace-nowrap">Competência</TableHead>
                <TableHead className="min-w-[280px]">Descrição</TableHead>
                <TableHead className="min-w-[100px]">Tipo</TableHead>
                <TableHead className="min-w-[130px] text-right">Valor (Pontos)</TableHead>
                <TableHead className="min-w-[120px] text-center">Fechamento</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {loading ? (
                <TableRow>
                  <TableCell colSpan={6} className="py-14 text-center text-muted-foreground">
                    <Loader2 className="mx-auto mb-2 h-8 w-8 animate-spin text-primary" />
                    Carregando extrato...
                  </TableCell>
                </TableRow>
              ) : linhasOrdenadas.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={6} className="py-12 text-center text-muted-foreground">
                    Nenhuma movimentação registrada para este parceiro.
                  </TableCell>
                </TableRow>
              ) : (
                linhasOrdenadas.map((linha) => {
                  const isCredito = linha.tipo === "credito";
                  const q = Number(linha.quantidade);
                  return (
                    <TableRow key={linha.id}>
                      <TableCell className="whitespace-nowrap text-sm text-muted-foreground">
                        {formatData(linha.criadoEm)}
                      </TableCell>
                      <TableCell className="whitespace-nowrap text-sm text-muted-foreground">
                        {formatCompetenciaMesAno(linha.competenciaMes, linha.competenciaAno)}
                      </TableCell>
                      <TableCell className="max-w-[420px] text-sm font-medium leading-snug">{linha.descricao}</TableCell>
                      <TableCell>
                        {isCredito ? (
                          <Badge className="border-emerald-600/30 bg-emerald-50 font-normal text-emerald-800 hover:bg-emerald-50 dark:bg-emerald-950/40 dark:text-emerald-200">
                            Crédito
                          </Badge>
                        ) : (
                          <Badge className="border-red-600/30 bg-red-50 font-normal text-red-800 hover:bg-red-50 dark:bg-red-950/40 dark:text-red-200">
                            Débito
                          </Badge>
                        )}
                      </TableCell>
                      <TableCell
                        className={`text-right font-semibold tabular-nums ${
                          isCredito ? "text-emerald-600" : "text-red-600"
                        }`}
                      >
                        {isCredito ? "+" : "−"}
                        {formatPontos(q)}
                      </TableCell>
                      <TableCell className="text-center">
                        {linha.fechamentoId ? (
                          <Button
                            size="sm"
                            variant="ghost"
                            className="gap-1 text-foreground hover:bg-zinc-200 hover:text-foreground dark:hover:bg-zinc-700"
                            onClick={() =>
                              navigate(`/fechamento/fechamentos/${linha.fechamentoId}`, {
                                state: { competenciaId: undefined, status: undefined },
                              })
                            }
                          >
                            <ExternalLink className="h-4 w-4" />
                            Abrir
                          </Button>
                        ) : (
                          <span className="text-sm text-muted-foreground">—</span>
                        )}
                      </TableCell>
                    </TableRow>
                  );
                })
              )}
            </TableBody>
          </Table>
        </div>

        <div className="flex flex-wrap items-center justify-between gap-3 border-t pt-3">
          <p className="text-sm text-muted-foreground">
            {loading ? (
              "Carregando paginação…"
            ) : (
              <>
                {intervaloLabel}
                {" · "}
                Página {meta.paginaAtual} de{" "}
                {meta.total === 0 ? 1 : Math.max(1, meta.totalPaginas)}
              </>
            )}
          </p>
          <div className="flex gap-2">
            <Button
              variant="outline"
              size="sm"
              disabled={loading || page <= 1}
              onClick={() => setPage((p) => Math.max(1, p - 1))}
            >
              <ChevronLeft className="h-4 w-4" />
              Anterior
            </Button>
            <Button
              variant="outline"
              size="sm"
              disabled={loading || page >= meta.totalPaginas || meta.totalPaginas < 1}
              onClick={() => setPage((p) => Math.min(Math.max(1, meta.totalPaginas), p + 1))}
            >
              Próxima
              <ChevronRight className="h-4 w-4" />
            </Button>
          </div>
        </div>
      </div>
    </div>
  );
}
