import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { ArrowLeft, FileText, Trash2 } from "lucide-react";
import { toast } from "sonner";

import { AppShell } from "@/components/AppShell";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { Badge } from "@/components/ui/badge";
import {
  ambilTransaksiSatu,
  formatRupiah,
  formatTanggal,
  hapusTransaksi,
  urlBukti,
} from "@/lib/keuangan";

export const Route = createFileRoute("/_authenticated/transaksi/$id")({
  head: () => ({
    meta: [
      { title: "Detail Transaksi — Catatan Duit" },
      {
        name: "description",
        content: "Lihat detail transaksi lengkap dengan kategori, sumber, tujuan, dan foto bukti.",
      },
      { property: "og:title", content: "Detail Transaksi — Catatan Duit" },
      {
        property: "og:description",
        content: "Detail transaksi beserta bukti transfer yang tersimpan.",
      },
    ],
  }),
  component: DetailTransaksi,
  errorComponent: ({ error }) => (
    <AppShell>
      <p role="alert" className="text-sm text-destructive">
        {error.message}
      </p>
    </AppShell>
  ),
  notFoundComponent: () => (
    <AppShell>
      <p className="text-sm text-muted-foreground">Transaksi tidak ditemukan.</p>
    </AppShell>
  ),
});

function DetailTransaksi() {
  const { id } = Route.useParams();
  const navigate = useNavigate();
  const qc = useQueryClient();

  const { data, isLoading } = useQuery({
    queryKey: ["transaksi", id],
    queryFn: () => ambilTransaksiSatu(id),
  });

  const { data: bukti } = useQuery({
    queryKey: ["bukti", data?.bukti_path],
    queryFn: () => urlBukti(data!.bukti_path!),
    enabled: !!data?.bukti_path,
  });

  const hapus = useMutation({
    mutationFn: () => hapusTransaksi(id),
    onSuccess: () => {
      toast.success("Transaksi dihapus");
      qc.invalidateQueries({ queryKey: ["transaksi"] });
      navigate({ to: "/riwayat" });
    },
    onError: () => toast.error("Gagal menghapus transaksi"),
  });

  if (isLoading) {
    return (
      <AppShell>
        <Skeleton className="h-48 w-full rounded-3xl" />
      </AppShell>
    );
  }

  if (!data) {
    return (
      <AppShell>
        <p className="text-sm text-muted-foreground">Transaksi tidak ditemukan.</p>
      </AppShell>
    );
  }

  const masuk = data.jenis === "pemasukan";
  const gambar = data.bukti_nama ? !/\.pdf$/i.test(data.bukti_nama) : true;

  return (
    <AppShell>
      <Link
        to="/riwayat"
        className="mb-4 inline-flex items-center gap-1.5 text-sm text-muted-foreground"
      >
        <ArrowLeft className="size-4" /> Kembali
      </Link>

      <section className="rounded-3xl border border-border/70 bg-card p-5">
        <Badge variant={masuk ? "default" : "secondary"} className="capitalize">
          {data.jenis}
        </Badge>
        <h1 className="mt-3 text-3xl font-semibold tabular-nums">
          {masuk ? "+" : "−"}
          {formatRupiah(Number(data.nominal))}
        </h1>
        <p className="mt-1 text-sm text-muted-foreground">{formatTanggal(data.tanggal)}</p>

        <dl className="mt-5 space-y-3 text-sm">
          <Baris label="Kategori" nilai={data.kategori} />
          <Baris label="Dari" nilai={data.sumber ?? "—"} />
          <Baris label="Ke" nilai={data.tujuan ?? "—"} />
          <Baris label="Catatan" nilai={data.catatan ?? "—"} />
        </dl>
      </section>

      <section className="mt-4 rounded-3xl border border-border/70 bg-card p-5">
        <h2 className="text-sm font-semibold">Bukti transaksi</h2>
        {!data.bukti_path ? (
          <p className="mt-2 text-sm text-muted-foreground">Tidak ada bukti terlampir.</p>
        ) : bukti ? (
          gambar ? (
            <a href={bukti} target="_blank" rel="noreferrer">
              <img
                src={bukti}
                alt={`Bukti transaksi ${data.kategori}`}
                loading="lazy"
                className="mt-3 w-full rounded-2xl border border-border/70 object-contain"
              />
            </a>
          ) : (
            <a
              href={bukti}
              target="_blank"
              rel="noreferrer"
              className="mt-3 inline-flex items-center gap-2 rounded-xl border border-border px-3 py-2 text-sm"
            >
              <FileText className="size-4" /> {data.bukti_nama ?? "Buka berkas"}
            </a>
          )
        ) : (
          <Skeleton className="mt-3 h-40 w-full rounded-2xl" />
        )}
      </section>

      <Button
        variant="ghost"
        className="mt-4 w-full gap-2 text-destructive hover:text-destructive"
        onClick={() => hapus.mutate()}
        disabled={hapus.isPending}
      >
        <Trash2 className="size-4" /> Hapus transaksi
      </Button>
    </AppShell>
  );
}

function Baris({ label, nilai }: { label: string; nilai: string }) {
  return (
    <div className="flex justify-between gap-4 border-b border-border/60 pb-2 last:border-0">
      <dt className="text-muted-foreground">{label}</dt>
      <dd className="text-right font-medium">{nilai}</dd>
    </div>
  );
}
