"use client";

import { useMemo, useState, useTransition } from "react";
import Link from "next/link";
import {
  type ColumnDef,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  type SortingState,
  useReactTable,
} from "@tanstack/react-table";
import {
  ArrowUpRight,
  ChevronLeft,
  ChevronRight,
  ExternalLink,
  Loader2,
  MoreHorizontal,
  Plus,
  Receipt,
  Search,
  Trash2,
} from "lucide-react";
import { toast } from "sonner";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { deleteInvoiceAction } from "@/lib/appwrite/invoice-actions";
import { formatDate, formatTRY } from "@/lib/format";
import { cn } from "@/lib/utils";

import { InvoiceFormSheet } from "./invoice-form-sheet";
import { type Customer, type InvoiceRow, STATUS_COLOR, STATUS_LABEL } from "./types";

type Props = { invoices: InvoiceRow[]; customers: Customer[] };

export function InvoicesClient({ invoices, customers }: Props) {
  const [search, setSearch] = useState("");
  const [sorting, setSorting] = useState<SortingState>([]);
  const [formOpen, setFormOpen] = useState(false);
  const [deleting, setDeleting] = useState<InvoiceRow | null>(null);
  const [busy, startTransition] = useTransition();

  const stats = useMemo(() => {
    let total = 0;
    let outstanding = 0;
    let paid = 0;
    let overdue = 0;
    for (const i of invoices) {
      total += i.total;
      if (i.status === "paid") paid += i.total;
      else if (i.status === "overdue") {
        outstanding += i.total;
        overdue += i.total;
      } else if (i.status === "sent" || i.status === "draft") outstanding += i.total;
    }
    return { total, outstanding, paid, overdue };
  }, [invoices]);

  const columns = useMemo<ColumnDef<InvoiceRow>[]>(
    () => [
      {
        accessorKey: "number",
        header: "Numara",
        cell: ({ row }) => (
          <Link
            href={`/invoices/${row.original.id}`}
            className="hover:text-primary inline-flex items-center gap-1 font-mono text-sm font-medium"
          >
            {row.original.number}
            <ExternalLink className="size-3 opacity-0 transition-opacity group-hover:opacity-100" />
          </Link>
        ),
      },
      {
        accessorKey: "customerName",
        header: "Müşteri",
        cell: ({ row }) => row.original.customerName,
      },
      {
        accessorKey: "issueDate",
        header: "Tarih",
        cell: ({ row }) => (
          <span className="text-muted-foreground">{formatDate(row.original.issueDate)}</span>
        ),
      },
      {
        accessorKey: "dueDate",
        header: "Vade",
        cell: ({ row }) => {
          const overdue =
            row.original.status !== "paid" &&
            row.original.status !== "cancelled" &&
            new Date(row.original.dueDate) < new Date();
          return (
            <span
              className={cn(
                "text-muted-foreground",
                overdue && "text-destructive font-medium",
              )}
            >
              {formatDate(row.original.dueDate)}
            </span>
          );
        },
      },
      {
        accessorKey: "status",
        header: "Durum",
        cell: ({ row }) => (
          <Badge variant="outline" className={cn("border-0", STATUS_COLOR[row.original.status])}>
            {STATUS_LABEL[row.original.status]}
          </Badge>
        ),
      },
      {
        accessorKey: "total",
        header: "Toplam",
        cell: ({ row }) => (
          <span className="font-medium tabular-nums">{formatTRY(row.original.total)}</span>
        ),
      },
      {
        id: "actions",
        cell: ({ row }) => (
          <div className="flex justify-end">
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button variant="ghost" size="icon" className="size-8">
                  <MoreHorizontal className="size-4" />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end">
                <DropdownMenuItem asChild>
                  <Link href={`/invoices/${row.original.id}`}>
                    <ArrowUpRight className="size-3.5" />
                    Aç
                  </Link>
                </DropdownMenuItem>
                <DropdownMenuItem
                  variant="destructive"
                  onClick={() => setDeleting(row.original)}
                >
                  <Trash2 className="size-3.5" />
                  Sil
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </div>
        ),
      },
    ],
    [],
  );

  const table = useReactTable({
    data: invoices,
    columns,
    state: { globalFilter: search, sorting },
    onGlobalFilterChange: setSearch,
    onSortingChange: setSorting,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    initialState: { pagination: { pageSize: 25 } },
    globalFilterFn: (row, _id, fv) => {
      const v = String(fv).toLowerCase();
      return [row.original.number, row.original.customerName, row.original.notes]
        .join(" ")
        .toLowerCase()
        .includes(v);
    },
  });

  const handleDelete = () => {
    if (!deleting) return;
    startTransition(async () => {
      const fd = new FormData();
      fd.set("id", deleting.id);
      const result = await deleteInvoiceAction(fd);
      if (result.ok) {
        toast.success("Fatura silindi.");
        setDeleting(null);
      } else {
        toast.error(result.error ?? "Silme başarısız.");
      }
    });
  };

  return (
    <>
      <div className="grid grid-cols-2 gap-3 md:grid-cols-4">
        <Card>
          <CardContent className="p-4">
            <p className="text-muted-foreground text-xs">Toplam</p>
            <p className="mt-1 text-xl font-semibold">{formatTRY(stats.total)}</p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="p-4">
            <p className="text-muted-foreground text-xs">Tahsil edildi</p>
            <p className="mt-1 text-xl font-semibold text-emerald-600 dark:text-emerald-400">
              {formatTRY(stats.paid)}
            </p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="p-4">
            <p className="text-muted-foreground text-xs">Bekleyen</p>
            <p className="mt-1 text-xl font-semibold text-blue-600 dark:text-blue-400">
              {formatTRY(stats.outstanding)}
            </p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="p-4">
            <p className="text-muted-foreground text-xs">Gecikmiş</p>
            <p className="mt-1 text-xl font-semibold text-red-600 dark:text-red-400">
              {formatTRY(stats.overdue)}
            </p>
          </CardContent>
        </Card>
      </div>

      <Card>
        <CardContent className="p-0">
          <div className="flex flex-col gap-3 p-4 md:flex-row md:items-center md:justify-between">
            <div className="relative md:max-w-xs md:flex-1">
              <Search className="text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2" />
              <Input
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                placeholder="Numara, müşteri, not..."
                className="pl-9"
              />
            </div>
            <Button onClick={() => setFormOpen(true)} disabled={customers.length === 0}>
              <Plus className="size-4" />
              Yeni fatura
            </Button>
          </div>

          <Table>
            <TableHeader>
              {table.getHeaderGroups().map((hg) => (
                <TableRow key={hg.id}>
                  {hg.headers.map((h) => (
                    <TableHead key={h.id}>
                      {h.isPlaceholder
                        ? null
                        : flexRender(h.column.columnDef.header, h.getContext())}
                    </TableHead>
                  ))}
                </TableRow>
              ))}
            </TableHeader>
            <TableBody>
              {table.getRowModel().rows.length ? (
                table.getRowModel().rows.map((r) => (
                  <TableRow key={r.id} className="group">
                    {r.getVisibleCells().map((c) => (
                      <TableCell key={c.id}>
                        {flexRender(c.column.columnDef.cell, c.getContext())}
                      </TableCell>
                    ))}
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell colSpan={columns.length} className="h-32 text-center">
                    <div className="text-muted-foreground flex flex-col items-center gap-2">
                      <Receipt className="size-6" />
                      <p className="text-sm">
                        {customers.length === 0
                          ? "Önce müşteri ekleyin, sonra fatura kesebilirsiniz."
                          : "Henüz fatura yok."}
                      </p>
                    </div>
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>

          <div className="flex items-center justify-between border-t px-4 py-3">
            <p className="text-muted-foreground text-sm">
              Toplam {table.getFilteredRowModel().rows.length} fatura
            </p>
            <div className="flex items-center gap-2">
              <Button
                variant="outline"
                size="icon"
                className="size-8"
                onClick={() => table.previousPage()}
                disabled={!table.getCanPreviousPage()}
              >
                <ChevronLeft className="size-4" />
              </Button>
              <span className="text-muted-foreground text-sm">
                Sayfa {table.getState().pagination.pageIndex + 1} /{" "}
                {Math.max(table.getPageCount(), 1)}
              </span>
              <Button
                variant="outline"
                size="icon"
                className="size-8"
                onClick={() => table.nextPage()}
                disabled={!table.getCanNextPage()}
              >
                <ChevronRight className="size-4" />
              </Button>
            </div>
          </div>
        </CardContent>
      </Card>

      <InvoiceFormSheet
        open={formOpen}
        onOpenChange={setFormOpen}
        customers={customers}
      />

      <Dialog open={Boolean(deleting)} onOpenChange={(v) => !v && setDeleting(null)}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Faturayı sil</DialogTitle>
            <DialogDescription>
              <strong>{deleting?.number}</strong> ve tüm kalemleri silinecek. Bu işlem geri alınamaz.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleting(null)} disabled={busy}>
              Vazgeç
            </Button>
            <Button variant="destructive" onClick={handleDelete} disabled={busy}>
              {busy ? <Loader2 className="size-4 animate-spin" /> : <Trash2 className="size-4" />}
              Sil
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
