"use client";

import {
  ColumnDef,
  SortingState,
  flexRender,
  getCoreRowModel,
  useReactTable,
} from "@tanstack/react-table";
import {
  ArrowUpDown,
  Check,
  ChevronDown,
  ChevronUp,
  MoreHorizontal,
  Pencil,
  Trash2,
} from "lucide-react";
import Link from "next/link";
import * as React from "react";

import { deleteCommissionRequest } from "@/actions/commissions/deleteCommissionRequest";
import { getCommissionRequestsTablePage } from "@/actions/commissions/getCommissionRequestsTablePage";
import { setCommissionRequestStatus } from "@/actions/commissions/setCommissionRequestStatus";
import type {
  CommissionRequestTableRow,
  CommissionStatus,
} from "@/schemas/commissions/tableSchema";

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  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";

type TriState = "any" | "true" | "false";

function useDebouncedValue<T>(value: T, delayMs: number) {
  const [debounced, setDebounced] = React.useState(value);
  React.useEffect(() => {
    const t = setTimeout(() => setDebounced(value), delayMs);
    return () => clearTimeout(t);
  }, [value, delayMs]);
  return debounced;
}

function SortHeader(props: { title: string; column: any }) {
  const sorted = props.column.getIsSorted() as false | "asc" | "desc";

  return (
    <button
      type="button"
      onClick={() => props.column.toggleSorting(sorted === "asc")}
      className="group inline-flex items-center gap-2 font-semibold text-foreground/90 hover:text-foreground"
    >
      <span>{props.title}</span>
      {sorted === "asc" ? (
        <ChevronUp className="h-4 w-4" />
      ) : sorted === "desc" ? (
        <ChevronDown className="h-4 w-4" />
      ) : (
        <ArrowUpDown className="h-4 w-4 opacity-60 group-hover:opacity-100" />
      )}
    </button>
  );
}

function StatusBadge({ status }: { status: CommissionStatus }) {
  const variant =
    status === "COMPLETED"
      ? "default"
      : status === "REJECTED" || status === "SPAM"
        ? "destructive"
        : "secondary";

  return (
    <Badge variant={variant as any} className="px-2 py-0.5">
      {status}
    </Badge>
  );
}

function TriSelectInline(props: { value: TriState; onChange: (v: TriState) => void }) {
  return (
    <Select value={props.value} onValueChange={(v) => props.onChange(v as TriState)}>
      <SelectTrigger className="h-9">
        <SelectValue />
      </SelectTrigger>
      <SelectContent>
        <SelectItem value="any">Any</SelectItem>
        <SelectItem value="true">Yes</SelectItem>
        <SelectItem value="false">No</SelectItem>
      </SelectContent>
    </Select>
  );
}

const STATUS_OPTIONS: CommissionStatus[] = [
  "NEW",
  "REVIEWING",
  "ACCEPTED",
  "REJECTED",
  "COMPLETED",
  "SPAM",
];

type Filters = {
  q: string;
  email: string;
  status: "any" | CommissionStatus;
  hasFiles: TriState;
};

export function CommissionRequestsTable() {
  const [sorting, setSorting] = React.useState<SortingState>([
    { id: "createdAt", desc: true },
  ]);
  const [pageIndex, setPageIndex] = React.useState(0);
  const [pageSize, setPageSize] = React.useState(25);

  const [filters, setFilters] = React.useState<Filters>({
    q: "",
    email: "",
    status: "any",
    hasFiles: "any",
  });

  const debouncedQ = useDebouncedValue(filters.q, 300);
  const debouncedEmail = useDebouncedValue(filters.email, 300);

  const [rows, setRows] = React.useState<CommissionRequestTableRow[]>([]);
  const [total, setTotal] = React.useState(0);

  const [isPending, startTransition] = React.useTransition();

  // Delete dialog
  const [deleteOpen, setDeleteOpen] = React.useState(false);
  const [deleteTarget, setDeleteTarget] = React.useState<{
    id: string;
    label: string;
  } | null>(null);

  const pageCount = Math.max(1, Math.ceil(total / pageSize));

  const refresh = React.useCallback(() => {
    startTransition(async () => {
      const res = await getCommissionRequestsTablePage({
        pagination: { pageIndex, pageSize },
        sorting,
        filters: {
          q: debouncedQ || undefined,
          email: debouncedEmail || undefined,
          status: filters.status,
          hasFiles: filters.hasFiles,
        },
      });

      setRows(res.rows);
      setTotal(res.total);
    });
  }, [
    pageIndex,
    pageSize,
    sorting,
    debouncedQ,
    debouncedEmail,
    filters.status,
    filters.hasFiles,
  ]);

  React.useEffect(() => {
    refresh();
  }, [refresh]);

  const columns = React.useMemo<ColumnDef<CommissionRequestTableRow>[]>(
    () => [
      {
        accessorKey: "createdAt",
        header: ({ column }) => <SortHeader title="Submitted" column={column} />,
        cell: ({ row }) => (
          <span className="text-sm text-foreground/80">
            {new Date(row.original.createdAt).toLocaleString()}
          </span>
        ),
      },
      {
        accessorKey: "filesCount",
        header: ({ column }) => <SortHeader title="Files" column={column} />,
        cell: ({ row }) => (
          <span className="text-sm font-medium tabular-nums">{row.original.filesCount}</span>
        ),
      },
      {
        id: "requestor",
        header: "Requestor",
        enableSorting: false,
        cell: ({ row }) => {
          const r = row.original;
          return (
            <div className="min-w-0 max-w-[420px]">
              <div className="truncate text-sm font-medium">{r.customerName}</div>
              <div className="truncate text-[11px] leading-4 text-muted-foreground">
                {r.customerEmail}
                {r.customerSocials ? ` · ${r.customerSocials}` : ""}
              </div>
            </div>
          );
        },
      },
      {
        accessorKey: "status",
        header: ({ column }) => <SortHeader title="Status" column={column} />,
        cell: ({ row }) => <StatusBadge status={row.original.status} />,
      },
      {
        id: "complete",
        header: "",
        enableSorting: false,
        cell: ({ row }) => {
          const r = row.original;
          const isCompleted = r.status === "COMPLETED";

          return (
            <div className="flex justify-center">
              <Button
                variant={isCompleted ? "secondary" : "outline"}
                size="icon"
                className="h-9 w-9"
                disabled={isPending || isCompleted}
                title={isCompleted ? "Completed" : "Mark as completed"}
                onClick={() => {
                  if (isCompleted) return;
                  startTransition(async () => {
                    await setCommissionRequestStatus({ id: r.id, status: "COMPLETED" });
                    refresh();
                  });
                }}
              >
                <Check className="h-4 w-4" />
                <span className="sr-only">Mark complete</span>
              </Button>
            </div>
          );
        },
      },
      {
        id: "actions",
        header: "",
        enableSorting: false,
        cell: ({ row }) => {
          const r = row.original;

          return (
            <div className="flex justify-end">
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button variant="ghost" size="icon" className="h-9 w-9">
                    <MoreHorizontal className="h-4 w-4" />
                    <span className="sr-only">Open row actions</span>
                  </Button>
                </DropdownMenuTrigger>

                <DropdownMenuContent align="end" className="w-56">
                  {/* status changes */}
                  <div className="px-2 py-1.5 text-xs font-semibold text-muted-foreground">
                    Set status
                  </div>
                  {STATUS_OPTIONS.filter((s) => s !== "COMPLETED").map((s) => (
                    <DropdownMenuItem
                      key={s}
                      className="cursor-pointer"
                      onSelect={(e) => {
                        e.preventDefault();
                        startTransition(async () => {
                          await setCommissionRequestStatus({ id: r.id, status: s });
                          refresh();
                        });
                      }}
                    >
                      {s}
                    </DropdownMenuItem>
                  ))}

                  <DropdownMenuSeparator />

                  <DropdownMenuItem asChild>
                    <Link href={`/commissions/requests/${r.id}`} className="cursor-pointer">
                      <Pencil className="mr-2 h-4 w-4" />
                      Edit
                    </Link>
                  </DropdownMenuItem>

                  <DropdownMenuSeparator />

                  <DropdownMenuItem
                    className="cursor-pointer text-destructive focus:text-destructive"
                    onSelect={(e) => {
                      e.preventDefault();
                      setDeleteTarget({
                        id: r.id,
                        label: `${r.customerName} (${r.customerEmail})`,
                      });
                      setDeleteOpen(true);
                    }}
                  >
                    <Trash2 className="mr-2 h-4 w-4" />
                    Delete
                  </DropdownMenuItem>
                </DropdownMenuContent>
              </DropdownMenu>
            </div>
          );
        },
      },
    ],
    [isPending, refresh],
  );

  const table = useReactTable({
    data: rows,
    columns,
    state: { sorting },
    manualPagination: true,
    manualSorting: true,
    pageCount,
    onSortingChange: (updater) => {
      setSorting((prev) => (typeof updater === "function" ? updater(prev) : updater));
      setPageIndex(0);
    },
    getCoreRowModel: getCoreRowModel(),
  });

  const headerGroup = table.getHeaderGroups()[0];

  return (
    <div className="space-y-4">
      <div className="overflow-hidden rounded-2xl border border-border/60 bg-card shadow-sm ring-1 ring-border/40">
        <div className="relative">
          <div className="pointer-events-none absolute inset-x-0 top-0 z-10 h-6 bg-gradient-to-b from-background/60 to-transparent" />
          <Table>
            <TableHeader className="sticky top-0 z-20 bg-card">
              <TableRow className="hover:bg-transparent">
                {headerGroup.headers.map((header) => (
                  <TableHead
                    key={header.id}
                    className="whitespace-nowrap border-b border-border/70 bg-muted/40 py-3 text-xs font-semibold uppercase tracking-wide text-foreground/80"
                  >
                    {header.isPlaceholder
                      ? null
                      : flexRender(header.column.columnDef.header, header.getContext())}
                  </TableHead>
                ))}
              </TableRow>

              {/* filter row */}
              <TableRow className="hover:bg-transparent">
                {headerGroup.headers.map((header) => {
                  const colId = header.column.id;

                  return (
                    <TableHead key={header.id} className="border-b border-border/70 bg-muted/30 py-2">
                      {colId === "createdAt" ? (
                        <div className="h-9" />
                      ) : colId === "filesCount" ? (
                        <TriSelectInline
                          value={filters.hasFiles}
                          onChange={(v) => {
                            setFilters((f) => ({ ...f, hasFiles: v }));
                            setPageIndex(0);
                          }}
                        />
                      ) : colId === "requestor" ? (
                        <div className="flex gap-2">
                          <Input
                            className="h-9"
                            placeholder="Search name/message…"
                            value={filters.q}
                            onChange={(e) => {
                              setFilters((f) => ({ ...f, q: e.target.value }));
                              setPageIndex(0);
                            }}
                          />
                          <Input
                            className="h-9"
                            placeholder="Email…"
                            value={filters.email}
                            onChange={(e) => {
                              setFilters((f) => ({ ...f, email: e.target.value }));
                              setPageIndex(0);
                            }}
                          />
                        </div>
                      ) : colId === "status" ? (
                        <Select
                          value={filters.status}
                          onValueChange={(v) => {
                            setFilters((f) => ({ ...f, status: v as any }));
                            setPageIndex(0);
                          }}
                        >
                          <SelectTrigger className="h-9">
                            <SelectValue placeholder="Any" />
                          </SelectTrigger>
                          <SelectContent>
                            <SelectItem value="any">Any</SelectItem>
                            {STATUS_OPTIONS.map((s) => (
                              <SelectItem key={s} value={s}>
                                {s}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      ) : (
                        <div className="h-9" />
                      )}
                    </TableHead>
                  );
                })}
              </TableRow>
            </TableHeader>

            <TableBody>
              {rows.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={columns.length} className="py-14 text-center">
                    <div className="text-sm font-medium">
                      {isPending ? "Loading…" : "No results."}
                    </div>
                    <div className="mt-1 text-xs text-muted-foreground">
                      Adjust filters or change page size.
                    </div>
                  </TableCell>
                </TableRow>
              ) : (
                table.getRowModel().rows.map((r, idx) => (
                  <TableRow
                    key={r.id}
                    className={[
                      "transition-colors",
                      "hover:bg-muted/50",
                      idx % 2 === 0 ? "bg-background" : "bg-muted/10",
                    ].join(" ")}
                  >
                    {r.getVisibleCells().map((cell) => (
                      <TableCell key={cell.id} className="py-3 align-top border-b border-border/40">
                        {flexRender(cell.column.columnDef.cell, cell.getContext())}
                      </TableCell>
                    ))}
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </div>
      </div>

      {/* pagination */}
      <div className="flex items-center justify-between gap-3">
        <div className="text-sm text-muted-foreground">
          {isPending ? "Updating…" : null} Total: {total}
        </div>

        <div className="flex items-center gap-2">
          <Select
            value={String(pageSize)}
            onValueChange={(v) => {
              setPageSize(Number(v));
              setPageIndex(0);
            }}
          >
            <SelectTrigger className="h-9 w-[120px]">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {[10, 25, 50, 100].map((n) => (
                <SelectItem key={n} value={String(n)}>
                  {n} / page
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          <Button
            variant="outline"
            className="h-9"
            onClick={() => setPageIndex(0)}
            disabled={pageIndex === 0 || isPending}
          >
            First
          </Button>
          <Button
            variant="outline"
            className="h-9"
            onClick={() => setPageIndex((p) => Math.max(0, p - 1))}
            disabled={pageIndex === 0 || isPending}
          >
            Prev
          </Button>

          <div className="min-w-[120px] text-center text-sm tabular-nums">
            Page {pageIndex + 1} / {pageCount}
          </div>

          <Button
            variant="outline"
            className="h-9"
            onClick={() => setPageIndex((p) => Math.min(pageCount - 1, p + 1))}
            disabled={pageIndex >= pageCount - 1 || isPending}
          >
            Next
          </Button>
          <Button
            variant="outline"
            className="h-9"
            onClick={() => setPageIndex(Math.max(0, pageCount - 1))}
            disabled={pageIndex >= pageCount - 1 || isPending}
          >
            Last
          </Button>
        </div>
      </div>

      {/* delete confirmation */}
      <AlertDialog open={deleteOpen} onOpenChange={setDeleteOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete request?</AlertDialogTitle>
            <AlertDialogDescription>
              This will delete{" "}
              <span className="font-medium">{deleteTarget?.label}</span>. This action cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>
            <AlertDialogAction
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
              disabled={isPending || !deleteTarget}
              onClick={() => {
                const target = deleteTarget;
                if (!target) return;

                startTransition(async () => {
                  await deleteCommissionRequest(target.id);
                  setDeleteOpen(false);
                  setDeleteTarget(null);

                  // If current page becomes empty after delete, clamp page index.
                  setPageIndex((p) => (p > 0 && rows.length === 1 ? p - 1 : p));
                  refresh();
                });
              }}
            >
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
