"use client"

import {
	type ColumnDef,
	type ColumnFiltersState,
	type ExpandedState,
	flexRender,
	getCoreRowModel,
	getExpandedRowModel,
	getFilteredRowModel,
	getSortedRowModel,
	type SortingState,
	useReactTable,
} from "@tanstack/react-table"
import dayjs from "dayjs"
import relativeTime from "dayjs/plugin/relativeTime"
import { Check, ChevronDown, ChevronRight, Filter, ImageIcon, Search, SortDesc, X } from "lucide-react"
import * as React from "react"
import { SubmissionDetails } from "@/components/submission-details"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { UserDisplay } from "@/components/user-display"
import { pb, type Submission } from "@/lib/pb"
import { cn } from "@/lib/utils"

// Initialize dayjs relative time plugin
dayjs.extend(relativeTime)

// Utility function to get display name with priority: username > email > created_by field
const getDisplayName = (submission: Submission, expandedData?: any): string => {
	// Check if we have expanded user data
	if (expandedData && expandedData.created_by) {
		const user = expandedData.created_by

		// Priority: username > email
		if (user.username) {
			return user.username
		}
		if (user.email) {
			return user.email
		}
	}

	// Fallback to created_by field (could be user ID or username)
	return submission.created_by
}

interface SubmissionsDataTableProps {
	data: Submission[]
	isAdmin: boolean
	currentUserId: string
	onApprove: (id: string) => void
	onReject: (id: string) => void
	isApproving?: boolean
	isRejecting?: boolean
}

// Group submissions by status with priority order
const groupAndSortSubmissions = (submissions: Submission[]): Submission[] => {
	const statusPriority = { pending: 0, approved: 1, added_to_collection: 2, rejected: 3 }

	return [...submissions].sort((a, b) => {
		// First, sort by status priority
		const statusDiff = statusPriority[a.status] - statusPriority[b.status]
		if (statusDiff !== 0) return statusDiff

		// Within same status, sort by updated time (most recent first)
		return new Date(b.updated).getTime() - new Date(a.updated).getTime()
	})
}

const getStatusColor = (status: Submission["status"]) => {
	switch (status) {
		case "approved":
			return "bg-blue-500/10 text-blue-400 font-bold border-blue-500/20"
		case "rejected":
			return "bg-red-500/10 text-red-500 border-red-500/20"
		case "pending":
			return "bg-yellow-500/10 text-yellow-500 border-yellow-500/20"
		case "added_to_collection":
			return "bg-green-500/10 text-green-500 border-green-500/20"
		default:
			return "bg-gray-500/10 text-gray-500 border-gray-500/20"
	}
}

const getStatusDisplayName = (status: Submission["status"]) => {
	switch (status) {
		case "pending":
			return "Pending"
		case "approved":
			return "Approved"
		case "rejected":
			return "Rejected"
		case "added_to_collection":
			return "Added to Collection"
		default:
			return status
	}
}

export function SubmissionsDataTable({
	data,
	isAdmin,
	currentUserId,
	onApprove,
	onReject,
	isApproving,
	isRejecting,
}: SubmissionsDataTableProps) {
	const [sorting, setSorting] = React.useState<SortingState>([])
	const [expanded, setExpanded] = React.useState<ExpandedState>({})
	const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])
	const [globalFilter, setGlobalFilter] = React.useState("")
	const [userFilter, setUserFilter] = React.useState<{ userId: string; displayName: string } | null>(null)

	// Handle row expansion - only one row can be expanded at a time
	const handleRowToggle = React.useCallback((rowId: string, isExpanded: boolean) => {
		setExpanded(isExpanded ? {} : { [rowId]: true })
	}, [])

	// Group and sort data by status and updated time
	const groupedData = React.useMemo(() => {
		return groupAndSortSubmissions(data)
	}, [data])

	// Handle user filter - filter by user ID but display username
	const handleUserFilter = React.useCallback(
		(userId: string, displayName: string) => {
			if (userFilter?.userId === userId) {
				setUserFilter(null)
				setColumnFilters((prev) => prev.filter((filter) => filter.id !== "created_by"))
			} else {
				setUserFilter({ userId, displayName })
				setColumnFilters((prev) => [...prev.filter((filter) => filter.id !== "created_by"), { id: "created_by", value: userId }])
			}
		},
		[userFilter],
	)

	const columns: ColumnDef<Submission>[] = React.useMemo(() => [
		{
			id: "expander",
			header: () => null,
			cell: ({ row }) => {
				return (
					<button
						onClick={(e) => {
							e.stopPropagation()
							handleRowToggle(row.id, row.getIsExpanded())
						}}
						className="flex items-center justify-center w-8 h-8 hover:bg-muted rounded transition-colors"
					>
						{row.getIsExpanded() ? (
							<ChevronDown className="h-4 w-4 text-muted-foreground" />
						) : (
							<ChevronRight className="h-4 w-4 text-muted-foreground" />
						)}
					</button>
				)
			},
		},
		{
			accessorKey: "name",
			header: ({ column }) => {
				return (
					<Button
						variant="ghost"
						onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
						className="h-auto p-0 font-semibold hover:bg-transparent"
					>
						Name
						<SortDesc className="ml-2 h-4 w-4" />
					</Button>
				)
			},
			cell: ({ row }) => <div className="font-medium capitalize">{row.getValue("name")}</div>,
		},
		{
			accessorKey: "status",
			header: ({ column }) => {
				return (
					<Button
						variant="ghost"
						onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
						className="h-auto p-0 font-semibold hover:bg-transparent"
					>
						Status
						<SortDesc className="ml-2 h-4 w-4" />
					</Button>
				)
			},
			cell: ({ row }) => {
				const status = row.getValue("status") as Submission["status"]
				return (
					<Badge variant="outline" className={getStatusColor(status)}>
						{getStatusDisplayName(status)}
					</Badge>
				)
			},
		},
		{
			accessorKey: "created_by",
			header: ({ column }) => {
				return (
					<Button
						variant="ghost"
						onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
						className="h-auto p-0 font-semibold hover:bg-transparent"
					>
						Submitted By
						<SortDesc className="ml-2 h-4 w-4" />
					</Button>
				)
			},
			cell: ({ row }) => {
				const submission = row.original
				const expandedData = (submission as any).expand
				const displayName = getDisplayName(submission, expandedData)
				const userId = submission.created_by

				return (
					<div className="flex items-center gap-1">
						<UserDisplay
							userId={userId}
							avatar={expandedData.created_by.avatar}
							displayName={displayName}
							onClick={handleUserFilter}
							size="md"
						/>
						{userFilter?.userId === userId && <X className="h-3 w-3 text-muted-foreground" />}
					</div>
				)
			},
		},
		{
			accessorKey: "updated",
			header: ({ column }) => {
				return (
					<Button
						variant="ghost"
						onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
						className="h-auto p-0 font-semibold hover:bg-transparent"
					>
						Updated
						<SortDesc className="ml-2 h-4 w-4" />
					</Button>
				)
			},
			cell: ({ row }) => {
				const date = row.getValue("updated") as string
				return (
					<div className="text-sm text-muted-foreground" title={dayjs(date).format("MMMM D, YYYY h:mm A")}>
						{dayjs(date).fromNow()}
					</div>
				)
			},
		},
		{
			accessorKey: "assets",
			header: "Preview",
			cell: ({ row }) => {
				const assets = row.getValue("assets") as string[]
				const name = row.getValue("name") as string
				if (assets.length > 0) {
					return (
						<div className="w-12 h-12 rounded border flex items-center justify-center bg-background p-2">
							<img
								src={`${pb.baseUrl}/api/files/submissions/${row.original.id}/${assets[0]}?thumb=100x100` || "/placeholder.svg"}
								alt={name}
								className="w-full h-full object-contain"
							/>
						</div>
					)
				}
				return (
					<div className="w-12 h-12 rounded border flex items-center justify-center bg-muted">
						<ImageIcon className="w-6 h-6 text-muted-foreground" />
					</div>
				)
			},
		},
	], [handleRowToggle, handleUserFilter, userFilter])

	const table = useReactTable({
		data: groupedData,
		columns,
		getCoreRowModel: getCoreRowModel(),
		getSortedRowModel: getSortedRowModel(),
		getExpandedRowModel: getExpandedRowModel(),
		getFilteredRowModel: getFilteredRowModel(),
		onSortingChange: setSorting,
		onExpandedChange: setExpanded,
		onColumnFiltersChange: setColumnFilters,
		onGlobalFilterChange: setGlobalFilter,
		state: {
			sorting,
			expanded,
			columnFilters,
			globalFilter,
		},
		getRowCanExpand: () => true,
		globalFilterFn: (row, columnId, value) => {
			const searchValue = value.toLowerCase()
			const name = row.getValue("name") as string
			const status = row.getValue("status") as string
			const submission = row.original
			const expandedData = (submission as any).expand
			const displayName = getDisplayName(submission, expandedData)

			return (
				name.toLowerCase().includes(searchValue) ||
				status.toLowerCase().includes(searchValue) ||
				displayName.toLowerCase().includes(searchValue)
			)
		},
	})

	return (
		<div className="space-y-4">
			{/* Search and Filters */}
			<div className="flex flex-col sm:flex-row gap-4">
				<div className="relative flex-1  border rounded-md bg-background">
					<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-4 w-4" />
					<Input
						placeholder="Search submissions..."
						autoFocus
						value={globalFilter ?? ""}
						onChange={(event) => setGlobalFilter(String(event.target.value))}
						className="pl-10"
					/>
				</div>

				{userFilter && (
					<div className="flex items-center gap-2">
						<Filter className="h-4 w-4 text-muted-foreground" />
						<Badge variant="secondary" className="gap-1">
							User: {userFilter.displayName}
							<Button
								variant="ghost"
								size="sm"
								className="h-auto p-0 hover:bg-transparent"
								onClick={() => {
									setUserFilter(null)
									setColumnFilters((prev) => prev.filter((filter) => filter.id !== "created_by"))
								}}
							>
								<X className="h-3 w-3" />
							</Button>
						</Badge>
					</div>
				)}
			</div>

			{/* Table */}
			<div className="rounded-md border">
				<Table>
					<TableHeader>
						{table.getHeaderGroups().map((headerGroup) => (
							<TableRow key={headerGroup.id}>
								{headerGroup.headers.map((header) => {
									return (
										<TableHead key={header.id}>
											{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
										</TableHead>
									)
								})}
							</TableRow>
						))}
					</TableHeader>
					<TableBody className="bg-background">
						{table.getRowModel().rows?.length ? (
							(() => {
								let lastStatus: string | null = null
								return table.getRowModel().rows.map((row, index) => {
									const currentStatus = row.original.status
									const showStatusHeader = currentStatus !== lastStatus
									lastStatus = currentStatus

									return (
										<React.Fragment key={row.id}>
											{showStatusHeader && (
												<TableRow className="bg-muted/40 hover:bg-muted/40">
													<TableCell colSpan={columns.length} className="py-2 font-semibold text-sm">
														<div className="flex items-center gap-2">
															<Badge variant="outline" className={getStatusColor(currentStatus)}>
																{getStatusDisplayName(currentStatus)}
															</Badge>
															<span className="text-xs text-muted-foreground">
																{table.getRowModel().rows.filter((r) => r.original.status === currentStatus).length}
																{table.getRowModel().rows.filter((r) => r.original.status === currentStatus).length === 1
																	? " submission"
																	: " submissions"}
															</span>
														</div>
													</TableCell>
												</TableRow>
											)}
											<TableRow
												data-state={row.getIsSelected() && "selected"}
												className={cn("cursor-pointer hover:bg-muted/50 transition-colors", row.getIsExpanded() && "bg-muted/30")}
												onClick={() => handleRowToggle(row.id, row.getIsExpanded())}
											>
												{row.getVisibleCells().map((cell) => (
													<TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
												))}
											</TableRow>
											{row.getIsExpanded() && (
												<TableRow>
													<TableCell colSpan={columns.length} className="p-6 bg-muted/20 border-t">
														<SubmissionDetails
															submission={row.original}
															isAdmin={isAdmin}
															onUserClick={handleUserFilter}
															onApprove={row.original.status === "pending" && isAdmin ? () => onApprove(row.original.id) : undefined}
															onReject={row.original.status === "pending" && isAdmin ? () => onReject(row.original.id) : undefined}
															isApproving={isApproving}
															isRejecting={isRejecting}
														/>
													</TableCell>
												</TableRow>
											)}
										</React.Fragment>
									)
								})
							})()
						) : (
							<TableRow>
								<TableCell colSpan={columns.length} className="h-24 text-center">
									{globalFilter || userFilter ? "No submissions found matching your search" : "No submissions found"}
								</TableCell>
							</TableRow>
						)}
					</TableBody>
				</Table>
			</div>
		</div>
	)
}
