"use client";

import { useMemo, useState, useTransition } from "react";
import {
  type ColumnDef,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  useReactTable,
  type SortingState,
} from "@tanstack/react-table";
import {
  ArrowDownCircle,
  ArrowUpCircle,
  CircleAlert,
  CircleDollarSign,
  Loader2,
  MoreHorizontal,
  Pencil,
  Plus,
  Search,
  Trash2,
  Wallet,
} 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 {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { deleteFinanceEntryAction } from "@/lib/appwrite/finance-actions";
import { formatDate, formatTRY } from "@/lib/format";
import { cn } from "@/lib/utils";

import { FinanceFormSheet } from "./finance-form-sheet";
import {
  type BankAccountOption,
  type Customer,
  type FinanceRow,
  type FinanceType,
  PAYMENT_METHOD_LABEL,
  TYPE_COLOR,
  TYPE_LABEL,
} from "./types";

type Props = {
  entries: FinanceRow[];
  customers: Customer[];
  bankAccounts: BankAccountOption[];
};

function StatCard({
  label,
  amount,
  icon: Icon,
  tone,
}: {
  label: string;
  amount: number;
  icon: typeof Wallet;
  tone: "income" | "expense" | "receivable" | "debt" | "net";
}) {
  const toneClass = {
    income: "text-emerald-600 dark:text-emerald-400",
    expense: "text-red-600 dark:text-red-400",
    receivable: "text-blue-600 dark:text-blue-400",
    debt: "text-amber-600 dark:text-amber-400",
    net: amount >= 0 ? "text-emerald-600 dark:text-emerald-400" : "text-red-600 dark:text-red-400",
  }[tone];
  return (
    <Card>
      <CardContent className="flex items-start justify-between p-4">
        <div>
          <p className="text-muted-foreground text-xs">{label}</p>
          <p className={cn("mt-1 text-xl font-semibold", toneClass)}>{formatTRY(amount)}</p>
        </div>
        <Icon className={cn("size-5", toneClass)} />
      </CardContent>
    </Card>
  );
}

export function FinanceClient({ entries, customers, bankAccounts }: Props) {
  const [tab, setTab] = useState<FinanceType | "all">("all");
  const [search, setSearch] = useState("");
  const [sorting, setSorting] = useState<SortingState>([]);
  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<FinanceRow | null>(null);
  const [defaultType, setDefaultType] = useState<FinanceType>("income");
  const [deleting, setDeleting] = useState<FinanceRow | null>(null);
  const [busy, startTransition] = useTransition();

  const stats = useMemo(() => {
    let income = 0,
      expense = 0,
      receivable = 0,
      debt = 0;
    for (const e of entries) {
      if (e.type === "income") income += e.amount;
      else if (e.type === "expense") expense += e.amount;
      else if (e.type === "receivable") receivable += e.amount;
      else if (e.type === "debt") debt += e.amount;
    }
    return { income, expense, receivable, debt, net: income - expense };
  }, [entries]);

  const filtered = useMemo(
    () => (tab === "all" ? entries : entries.filter((e) => e.type === tab)),
    [entries, tab],
  );

  const columns = useMemo<ColumnDef<FinanceRow>[]>(
    () => [
      {
        accessorKey: "type",
        header: "Tür",
        cell: ({ row }) => (
          <Badge variant="outline" className={cn("border-0", TYPE_COLOR[row.original.type])}>
            {TYPE_LABEL[row.original.type]}
          </Badge>
        ),
      },
      {
        accessorKey: "amount",
        header: "Tutar",
        cell: ({ row }) => {
          const sign =
            row.original.type === "income" || row.original.type === "receivable" ? "+" : "−";
          return (
            <span className="font-medium tabular-nums">
              {sign} {formatTRY(row.original.amount)}
            </span>
          );
        },
      },
      {
        accessorKey: "date",
        header: "Tarih",
        cell: ({ row }) => (
          <span className="text-muted-foreground">{formatDate(row.original.date)}</span>
        ),
      },
      {
        accessorKey: "customerName",
        header: "Müşteri",
        cell: ({ row }) =>
          row.original.customerName ? (
            <span>{row.original.customerName}</span>
          ) : (
            <span className="text-muted-foreground">—</span>
          ),
      },
      {
        accessorKey: "paymentMethod",
        header: "Ödeme",
        cell: ({ row }) => (
          <span className="text-muted-foreground text-sm">
            {PAYMENT_METHOD_LABEL[row.original.paymentMethod]}
          </span>
        ),
      },
      {
        accessorKey: "description",
        header: "Açıklama",
        cell: ({ row }) => (
          <div className="flex max-w-[300px] items-center gap-2">
            <span className="text-muted-foreground line-clamp-1 text-sm">
              {row.original.description || "—"}
            </span>
            {row.original.invoiceId && (
              <Badge variant="outline" className="shrink-0 text-[10px]">
                Faturadan
              </Badge>
            )}
          </div>
        ),
      },
      {
        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
                  onClick={() => {
                    setEditing(row.original);
                    setFormOpen(true);
                  }}
                >
                  <Pencil className="size-3.5" />
                  Düzenle
                </DropdownMenuItem>
                <DropdownMenuItem
                  variant="destructive"
                  onClick={() => setDeleting(row.original)}
                >
                  <Trash2 className="size-3.5" />
                  Sil
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </div>
        ),
      },
    ],
    [],
  );

  const table = useReactTable({
    data: filtered,
    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.description, row.original.customerName, row.original.amount.toString()]
        .join(" ")
        .toLowerCase()
        .includes(v);
    },
  });

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

  const openCreate = (type: FinanceType) => {
    setEditing(null);
    setDefaultType(type);
    setFormOpen(true);
  };

  return (
    <>
      <div className="grid grid-cols-2 gap-3 md:grid-cols-5">
        <StatCard
          label="Gelir"
          amount={stats.income}
          icon={ArrowUpCircle}
          tone="income"
        />
        <StatCard
          label="Gider"
          amount={stats.expense}
          icon={ArrowDownCircle}
          tone="expense"
        />
        <StatCard label="Net" amount={stats.net} icon={CircleDollarSign} tone="net" />
        <StatCard
          label="Alacaklar"
          amount={stats.receivable}
          icon={Wallet}
          tone="receivable"
        />
        <StatCard label="Borçlar" amount={stats.debt} icon={CircleAlert} tone="debt" />
      </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="flex items-center gap-2">
              <Select value={tab} onValueChange={(v) => setTab(v as typeof tab)}>
                <SelectTrigger className="w-[160px]">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Tümü</SelectItem>
                  <SelectItem value="income">Gelir</SelectItem>
                  <SelectItem value="expense">Gider</SelectItem>
                  <SelectItem value="receivable">Alacaklar</SelectItem>
                  <SelectItem value="debt">Borçlar</SelectItem>
                </SelectContent>
              </Select>
              <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="Açıklama, müşteri, tutar..."
                  className="pl-9"
                />
              </div>
            </div>
            <div className="flex flex-wrap gap-2">
              <Button variant="outline" size="sm" onClick={() => openCreate("income")}>
                <Plus className="size-3.5" />
                Gelir
              </Button>
              <Button variant="outline" size="sm" onClick={() => openCreate("expense")}>
                <Plus className="size-3.5" />
                Gider
              </Button>
              <Button variant="outline" size="sm" onClick={() => openCreate("receivable")}>
                <Plus className="size-3.5" />
                Alacak
              </Button>
              <Button variant="outline" size="sm" onClick={() => openCreate("debt")}>
                <Plus className="size-3.5" />
                Borç
              </Button>
            </div>
          </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}>
                    {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">
                    <p className="text-muted-foreground text-sm">Kayıt yok.</p>
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </CardContent>
      </Card>

      <FinanceFormSheet
        open={formOpen}
        onOpenChange={(v) => {
          setFormOpen(v);
          if (!v) setEditing(null);
        }}
        entry={editing}
        defaultType={defaultType}
        customers={customers}
        bankAccounts={bankAccounts}
        onRequestDelete={(e) => {
          setFormOpen(false);
          setDeleting(e);
        }}
      />

      <Dialog open={Boolean(deleting)} onOpenChange={(v) => !v && setDeleting(null)}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Kaydı sil</DialogTitle>
            <DialogDescription>
              {deleting && (
                <>
                  <strong>{TYPE_LABEL[deleting.type]}</strong> — {formatTRY(deleting.amount)} (
                  {formatDate(deleting.date)}) silinecek.
                </>
              )}
            </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>
    </>
  );
}
