/**
 * JellyseerRequestsTable — sortable/filterable table of Jellyseerr requests.
 *
 * Uses TanStack Table directly (the shared DataTable is deliberately
 * visibility-only). Defaults: status filter = "open" (pending/approved/
 * processing), sorted by date added (newest first). Client-side sort + filter
 * + pagination over the backend's fetched set.
 */
import { useMemo, useState } from "react";
import {
	type ColumnDef,
	type SortingState,
	flexRender,
	getCoreRowModel,
	getPaginationRowModel,
	getSortedRowModel,
	useReactTable,
} from "@tanstack/react-table";
import { ArrowDown, ArrowUp, ChevronsUpDown, Search } from "lucide-react";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import {
	Select,
	SelectContent,
	SelectItem,
	SelectTrigger,
	SelectValue,
} from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
import {
	Table,
	TableBody,
	TableCell,
	TableHead,
	TableHeader,
	TableRow,
} from "@/components/ui/table";
import { TablePagination } from "@/components/ui/table-pagination";
import { useJellyseerRequests } from "../hooks/useJellyseer";
import type { JellyseerRequest } from "../api/jellyseerr";

const OPEN_STATUSES = new Set(["pending", "approved", "processing"]);
type StatusFilter = "open" | "pending" | "approved";

function formatDate(v?: number | string): string {
	if (!v) return "—";
	const n = Number(v);
	const ms = n > 1e12 ? n : n * 1000; // seconds -> ms
	const d = new Date(ms);
	return Number.isNaN(d.getTime())
		? String(v)
		: d.toLocaleDateString(undefined, {
				year: "numeric",
				month: "short",
				day: "numeric",
			});
}

const columns: ColumnDef<JellyseerRequest>[] = [
	{
		accessorKey: "name",
		header: "Name",
		cell: ({ row }) => (
			<span className="truncate font-medium">{row.original.name ?? "—"}</span>
		),
	},
	{
		accessorKey: "type",
		header: "Type",
		cell: ({ row }) => (
			<span className="capitalize">{row.original.type ?? "—"}</span>
		),
	},
	{
		accessorKey: "status",
		header: "Status",
		cell: ({ row }) => (
			<Badge variant="secondary">{row.original.status ?? "—"}</Badge>
		),
	},
	{
		accessorKey: "media_status",
		header: "Media",
		cell: ({ row }) =>
			row.original.media_status ? (
				<Badge variant="outline">{row.original.media_status}</Badge>
			) : (
				"—"
			),
	},
	{
		accessorKey: "created_at",
		header: "Requested",
		cell: ({ row }) => formatDate(row.original.created_at),
		sortDescFirst: true,
	},
];

export function JellyseerRequestsTable({ serviceId }: { serviceId: string }) {
	const {
		data: requests = [],
		isLoading,
		error,
	} = useJellyseerRequests(serviceId);
	const [sorting, setSorting] = useState<SortingState>([
		{ id: "created_at", desc: true },
	]);
	const [search, setSearch] = useState("");
	const [statusFilter, setStatusFilter] = useState<StatusFilter>("open");

	const filtered = useMemo(() => {
		const q = search.trim().toLowerCase();
		return requests.filter((r) => {
			const status = String(r.status ?? "");
			if (statusFilter === "open") {
				if (!OPEN_STATUSES.has(status)) return false;
			} else if (status !== statusFilter) {
				return false;
			}
			if (
				q &&
				!String(r.name ?? "")
					.toLowerCase()
					.includes(q)
			)
				return false;
			return true;
		});
	}, [requests, statusFilter, search]);

	/* eslint-disable react-hooks/incompatible-library -- TanStack's useReactTable
	   intentionally returns non-memoizable updater fns (controlled state). */
	const table = useReactTable({
		data: filtered,
		columns,
		state: { sorting },
		onSortingChange: setSorting,
		getCoreRowModel: getCoreRowModel(),
		getSortedRowModel: getSortedRowModel(),
		getPaginationRowModel: getPaginationRowModel(),
		initialState: { pagination: { pageSize: 10 } },
	});

	if (isLoading) {
		return <Skeleton className="h-48 w-full" />;
	}
	if (error) {
		return (
			<Alert variant="destructive">
				<AlertDescription>{error.message}</AlertDescription>
			</Alert>
		);
	}

	return (
		<div className="flex flex-col gap-3">
			<div className="flex flex-wrap items-center gap-2">
				<div className="relative min-w-[180px] flex-1">
					<Search className="absolute left-2 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
					<Input
						placeholder="Search requests…"
						value={search}
						onChange={(e) => setSearch(e.target.value)}
						className="pl-8"
					/>
				</div>
				<Select
					value={statusFilter}
					onValueChange={(v) => setStatusFilter(v as StatusFilter)}
				>
					<SelectTrigger className="w-[140px]">
						<SelectValue />
					</SelectTrigger>
					<SelectContent>
						<SelectItem value="open">Open</SelectItem>
						<SelectItem value="pending">Pending</SelectItem>
						<SelectItem value="approved">Approved</SelectItem>
					</SelectContent>
				</Select>
			</div>

			<div className="overflow-hidden rounded-lg border">
				<Table>
					<TableHeader>
						{table.getHeaderGroups().map((hg) => (
							<TableRow key={hg.id} className="hover:bg-transparent">
								{hg.headers.map((header) => (
									<TableHead key={header.id}>
										{header.isPlaceholder ? null : (
											<button
												type="button"
												className="inline-flex items-center gap-1"
												onClick={header.column.getToggleSortingHandler()}
											>
												{flexRender(
													header.column.columnDef.header,
													header.getContext(),
												)}
												{header.column.getIsSorted() === "asc" ? (
													<ArrowUp className="size-3" />
												) : header.column.getIsSorted() === "desc" ? (
													<ArrowDown className="size-3" />
												) : (
													<ChevronsUpDown className="size-3 opacity-40" />
												)}
											</button>
										)}
									</TableHead>
								))}
							</TableRow>
						))}
					</TableHeader>
					<TableBody>
						{table.getRowModel().rows.length ? (
							table.getRowModel().rows.map((row) => (
								<TableRow key={String(row.original.id ?? row.index)}>
									{row.getVisibleCells().map((cell) => (
										<TableCell key={cell.id}>
											{flexRender(
												cell.column.columnDef.cell,
												cell.getContext(),
											)}
										</TableCell>
									))}
								</TableRow>
							))
						) : (
							<TableRow className="hover:bg-transparent">
								<TableCell
									colSpan={columns.length}
									className="h-16 text-center text-muted-foreground"
								>
									No requests.
								</TableCell>
							</TableRow>
						)}
					</TableBody>
				</Table>
			</div>

			<TablePagination
				pageIndex={table.getState().pagination.pageIndex}
				pageSize={table.getState().pagination.pageSize}
				pageSizeOptions={[10, 20, 50]}
				totalRows={table.getRowModel().rows.length}
				pageCount={table.getPageCount()}
				onPaginationChange={table.setPagination}
			/>
		</div>
	);
}
