import { formatDistanceToNow } from "date-fns";
import {
	ArrowRight,
	Bookmark,
	BookmarkCheck,
	type LucideIcon,
	MoreVertical,
} from "lucide-react";
import React from "react";
import { Link } from "wouter";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
	Card,
	CardContent,
	CardDescription,
	CardFooter,
	CardHeader,
	CardTitle,
} from "@/components/ui/card";
import {
	DropdownMenu,
	DropdownMenuContent,
	DropdownMenuItem,
	DropdownMenuSeparator,
	DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";

/**
 * Work preview component for displaying works in lists and grids
 *
 * @example
 * ```tsx
 * <WorkPreview
 *   work={{
 *     id: 1,
 *     title: "Eugene Onegin",
 *     slug: "eugene-onegin",
 *     excerpt: "A classic work of Russian literature...",
 *     author: { name: "Alexander Pushkin" },
 *     tags: [{ id: 1, name: "Poetry" }],
 *     translationCount: 3,
 *     createdAt: new Date(2023, 0, 15),
 *   }}
 *   isBookmarked={false}
 *   onToggleBookmark={() => {}}
 * />
 * ```
 */

// Placeholder image component (replace with your own image component)
const PlaceholderImage = ({ className }: { className?: string }) => (
	<div className={cn("bg-muted flex items-center justify-center", className)}>
		<span className="text-muted-foreground">No Image</span>
	</div>
);

export interface WorkPreviewProps {
	/**
	 * Work data to display
	 */
	work: {
		id: number;
		title: string;
		slug: string;
		excerpt?: string | null;
		author?: {
			name: string;
			slug?: string;
		};
		coverImage?: string | null;
		tags?: Array<{
			id: number;
			name: string;
		}>;
		translationCount?: number;
		createdAt?: Date | string;
		language?: string;
		isFeatured?: boolean;
	};
	/**
	 * Whether this work is bookmarked by the current user
	 */
	isBookmarked?: boolean;
	/**
	 * Callback when bookmark is toggled
	 */
	onToggleBookmark?: (id: number) => void;
	/**
	 * Callback when more menu option is selected
	 */
	onAction?: (action: string, id: number) => void;
	/**
	 * Layout variant
	 */
	variant?: "default" | "compact" | "grid" | "featured";
	/**
	 * Custom action button
	 */
	actionButton?: React.ReactNode;
	/**
	 * Dropdown menu options
	 */
	menuOptions?: Array<{
		label: string;
		action: string;
		icon?: LucideIcon;
		variant?: "default" | "destructive";
	}>;
	/**
	 * Additional CSS classes
	 */
	className?: string;
	/**
	 * Whether the preview is in a loading state
	 */
	isLoading?: boolean;
}

export function WorkPreview({
	work,
	isBookmarked,
	onToggleBookmark,
	onAction,
	variant = "default",
	actionButton,
	menuOptions = [
		{ label: "View details", action: "view" },
		{ label: "Edit work", action: "edit" },
		{ label: "Add to collection", action: "add-to-collection" },
		{ label: "Delete", action: "delete", variant: "destructive" },
	],
	className,
	isLoading = false,
}: WorkPreviewProps) {
	// Format date
	const formattedDate = work.createdAt
		? formatDistanceToNow(new Date(work.createdAt), { addSuffix: true })
		: "";

	// Determine if we should show tags based on variant
	const showTags = variant !== "compact";

	// Limit number of tags based on variant
	const maxTags = variant === "grid" ? 2 : variant === "featured" ? 4 : 3;
	const displayTags = work.tags?.slice(0, maxTags) || [];
	const hasMoreTags = (work.tags?.length || 0) > maxTags;

	if (isLoading) {
		return <WorkPreviewSkeleton variant={variant} className={className} />;
	}

	return (
		<Card
			className={cn(
				"",
				variant === "featured" && "overflow-hidden border-0 shadow",
				variant === "compact" && "border-0 shadow-none",
				className,
			)}
		>
			{/* Cover Image - Only for grid and featured variants */}
			{(variant === "grid" || variant === "featured") && (
				<div
					className={cn(
						"relative aspect-[16/9] overflow-hidden",
						variant === "featured" && "aspect-[21/9]",
					)}
				>
					{work.coverImage ? (
						<img
							src={work.coverImage}
							alt={work.title}
							className="object-cover w-full h-full"
						/>
					) : (
						<PlaceholderImage className="w-full h-full" />
					)}

					{/* Bookmark button - Overlay on image for grid/featured */}
					{onToggleBookmark && (
						<Button
							variant="ghost"
							size="icon"
							className="absolute top-2 right-2 bg-background/80 backdrop-blur-sm hover:bg-background/90"
							onClick={(e) => {
								e.preventDefault();
								e.stopPropagation();
								onToggleBookmark(work.id);
							}}
						>
							{isBookmarked ? (
								<BookmarkCheck className="h-5 w-5 text-primary" />
							) : (
								<Bookmark className="h-5 w-5" />
							)}
							<span className="sr-only">
								{isBookmarked ? "Remove bookmark" : "Bookmark"}
							</span>
						</Button>
					)}

					{/* Featured badge */}
					{work.isFeatured && variant === "featured" && (
						<Badge className="absolute top-2 left-2 bg-primary text-primary-foreground">
							Featured
						</Badge>
					)}
				</div>
			)}

			<CardHeader
				className={cn(
					variant === "compact" && "px-2 py-3",
					variant === "grid" && "px-4 py-3",
				)}
			>
				<div className="flex items-start justify-between">
					<div className="space-y-1">
						{/* Author name - for all except compact */}
						{work.author && variant !== "compact" && (
							<CardDescription>
								{work.author.slug ? (
									<Link
										href={`/authors/${work.author.slug}`}
										className="hover:underline"
									>
										{work.author.name}
									</Link>
								) : (
									work.author.name
								)}
							</CardDescription>
						)}

						{/* Title */}
						<CardTitle
							className={cn(
								variant === "compact" && "text-base",
								variant === "featured" && "text-2xl",
							)}
						>
							<Link href={`/works/${work.slug}`} className="hover:underline">
								{work.title}
							</Link>
						</CardTitle>

						{/* Language - if available */}
						{work.language && (
							<CardDescription className="text-xs">
								{work.language}
							</CardDescription>
						)}
					</div>

					{/* Actions dropdown */}
					{onAction && (
						<DropdownMenu>
							<DropdownMenuTrigger asChild>
								<Button variant="ghost" size="icon" className="h-8 w-8">
									<MoreVertical className="h-4 w-4" />
									<span className="sr-only">More options</span>
								</Button>
							</DropdownMenuTrigger>
							<DropdownMenuContent align="end">
								{menuOptions.map((option, index) => (
									<React.Fragment key={option.action}>
										{index > 0 && option.variant === "destructive" && (
											<DropdownMenuSeparator />
										)}
										<DropdownMenuItem
											className={cn(
												option.variant === "destructive" &&
													"text-destructive focus:text-destructive",
											)}
											onClick={() => onAction(option.action, work.id)}
										>
											{option.icon && <option.icon className="mr-2 h-4 w-4" />}
											{option.label}
										</DropdownMenuItem>
									</React.Fragment>
								))}
							</DropdownMenuContent>
						</DropdownMenu>
					)}

					{/* Bookmark button - For default and compact when not on image */}
					{onToggleBookmark &&
						(variant === "default" || variant === "compact") && (
							<Button
								variant="ghost"
								size="icon"
								className="h-8 w-8"
								onClick={(e) => {
									e.preventDefault();
									e.stopPropagation();
									onToggleBookmark(work.id);
								}}
							>
								{isBookmarked ? (
									<BookmarkCheck className="h-4 w-4 text-primary" />
								) : (
									<Bookmark className="h-4 w-4" />
								)}
								<span className="sr-only">
									{isBookmarked ? "Remove bookmark" : "Bookmark"}
								</span>
							</Button>
						)}
				</div>
			</CardHeader>

			{/* Content - Only for default and featured variants */}
			{(variant === "default" || variant === "featured") && work.excerpt && (
				<CardContent
					className={cn("text-sm", variant === "featured" && "text-base")}
				>
					<p className="text-muted-foreground line-clamp-3">{work.excerpt}</p>
				</CardContent>
			)}

			<CardFooter
				className={cn(
					"flex items-center justify-between flex-wrap gap-2 pt-0",
					variant === "compact" && "px-2 py-2",
					variant === "grid" && "px-4 py-3",
				)}
			>
				{/* Tags */}
				{showTags && displayTags.length > 0 && (
					<div className="flex flex-wrap gap-1">
						{displayTags.map((tag) => (
							<Badge key={tag.id} variant="secondary" className="text-xs">
								{tag.name}
							</Badge>
						))}
						{hasMoreTags && (
							<Badge variant="outline" className="text-xs">
								+{(work.tags?.length || 0) - maxTags} more
							</Badge>
						)}
					</div>
				)}

				{/* Translations count and date */}
				<div className="flex items-center gap-4 ml-auto text-xs text-muted-foreground">
					{work.translationCount !== undefined && (
						<span>
							{work.translationCount} translation
							{work.translationCount !== 1 && "s"}
						</span>
					)}

					{formattedDate && variant !== "compact" && (
						<span>{formattedDate}</span>
					)}

					{/* Custom action button or default view button */}
					{actionButton || (
						<Button
							variant="ghost"
							size="sm"
							className="ml-auto flex items-center gap-1"
							asChild
						>
							<Link href={`/works/${work.slug}`}>
								View
								<ArrowRight className="h-3 w-3 ml-1" />
							</Link>
						</Button>
					)}
				</div>
			</CardFooter>
		</Card>
	);
}

// Skeleton loading state
export function WorkPreviewSkeleton({
	variant = "default",
	className,
}: {
	variant?: "default" | "compact" | "grid" | "featured";
	className?: string;
}) {
	// Determine if we should show tags based on variant
	const showTags = variant !== "compact";

	return (
		<Card
			className={cn(
				"animate-pulse",
				variant === "featured" && "overflow-hidden border-0 shadow",
				variant === "compact" && "border-0 shadow-none",
				className,
			)}
		>
			{/* Image skeleton */}
			{(variant === "grid" || variant === "featured") && (
				<div
					className={cn(
						"aspect-[16/9] bg-muted",
						variant === "featured" && "aspect-[21/9]",
					)}
				/>
			)}

			<CardHeader
				className={cn(
					variant === "compact" && "px-2 py-3",
					variant === "grid" && "px-4 py-3",
				)}
			>
				{variant !== "compact" && <Skeleton className="h-4 w-40" />}
				<Skeleton
					className={cn("h-6 w-full", variant === "featured" && "h-8")}
				/>
			</CardHeader>

			{(variant === "default" || variant === "featured") && (
				<CardContent>
					<div className="space-y-2">
						<Skeleton className="h-4 w-full" />
						<Skeleton className="h-4 w-2/3" />
					</div>
				</CardContent>
			)}

			<CardFooter
				className={cn(
					"flex items-center justify-between pt-0",
					variant === "compact" && "px-2 py-2",
					variant === "grid" && "px-4 py-3",
				)}
			>
				{showTags && (
					<div className="flex gap-1">
						<Skeleton className="h-5 w-14 rounded-full" />
						<Skeleton className="h-5 w-16 rounded-full" />
					</div>
				)}
				<div className="ml-auto flex items-center gap-2">
					<Skeleton className="h-4 w-24" />
					<Skeleton className="h-8 w-16 rounded-md" />
				</div>
			</CardFooter>
		</Card>
	);
}
