import { cva, type VariantProps } from "class-variance-authority";
import type { LucideIcon } from "lucide-react";
import { cn } from "@/lib/utils";

/**
 * Stat Card component for displaying statistics and metrics
 *
 * @example
 * ```tsx
 * <StatCard
 *   title="Total Readers"
 *   value="12,345"
 *   description="+12% from last month"
 *   trend="up"
 *   icon={Users}
 * />
 * ```
 */

const statCardVariants = cva(
	"relative overflow-hidden rounded-lg p-6 shadow-sm",
	{
		variants: {
			variant: {
				default: "bg-card border",
				filled: "bg-primary text-primary-foreground",
				outline: "border border-primary/20 bg-background",
				ghost: "bg-muted/30 border-none shadow-none",
				destructive: "bg-destructive text-destructive-foreground",
				success:
					"bg-emerald-50 dark:bg-emerald-950/20 border-emerald-200 dark:border-emerald-900/50 border",
			},
			size: {
				default: "p-6",
				sm: "p-4",
				lg: "p-8",
			},
		},
		defaultVariants: {
			variant: "default",
			size: "default",
		},
	},
);

export interface StatCardProps
	extends React.HTMLAttributes<HTMLDivElement>,
		VariantProps<typeof statCardVariants> {
	/**
	 * Title or label for the stat
	 */
	title?: string;
	/**
	 * The value/data to display
	 */
	value?: React.ReactNode;
	/**
	 * Optional description or context for the value
	 */
	description?: React.ReactNode;
	/**
	 * Optional icon to display
	 */
	icon?: LucideIcon;
	/**
	 * Direction of the trend (up, down, or none)
	 */
	trend?: "up" | "down" | "none";
	/**
	 * Whether the trend is positive (green) or negative (red)
	 * By default, "up" is positive and "down" is negative
	 */
	trendIsPositive?: boolean;
	/**
	 * Whether the card is in a loading state
	 */
	loading?: boolean;
	/**
	 * Optional footer content
	 */
	footer?: React.ReactNode;
	/**
	 * Optional badge content (displayed in the top right)
	 */
	badge?: React.ReactNode;
}

export function StatCard({
	className,
	variant,
	size,
	title,
	value,
	description,
	icon: Icon,
	trend,
	trendIsPositive,
	loading = false,
	footer,
	badge,
	children,
	...props
}: StatCardProps) {
	// Determine if trend is positive based on direction and trendIsPositive prop
	const isPositive =
		trendIsPositive !== undefined ? trendIsPositive : trend === "up";

	const trendColor =
		trend === "none"
			? "text-muted-foreground"
			: isPositive
				? "text-emerald-600 dark:text-emerald-400"
				: "text-destructive";

	return (
		<div
			className={cn(statCardVariants({ variant, size, className }))}
			{...props}
		>
			{/* Optional badge */}
			{badge && <div className="absolute top-2 right-2">{badge}</div>}

			<div className="flex items-start justify-between">
				<div className="space-y-2">
					{/* Title/label */}
					{title && (
						<h3
							className={cn(
								"text-sm font-medium text-muted-foreground",
								variant === "filled" && "text-primary-foreground/80",
								variant === "destructive" && "text-destructive-foreground/80",
								loading && "animate-pulse",
							)}
						>
							{title}
						</h3>
					)}

					{/* Value */}
					<div
						className={cn(
							"text-2xl font-bold",
							loading && "animate-pulse bg-muted/40 rounded h-8 w-24",
							typeof value === "undefined" && loading && "animate-pulse",
						)}
					>
						{loading && typeof value === "undefined" ? null : value}
					</div>

					{/* Description with trend indicator */}
					{description && (
						<p
							className={cn(
								"text-sm",
								trend ? trendColor : "text-muted-foreground",
								loading && "animate-pulse",
							)}
						>
							{description}
						</p>
					)}

					{/* Custom content */}
					{children && (
						<div className={cn(loading && "animate-pulse")}>{children}</div>
					)}
				</div>

				{/* Icon */}
				{Icon && (
					<div
						className={cn(
							"h-9 w-9 rounded-lg flex items-center justify-center",
							variant === "default" && "bg-primary/10 text-primary",
							variant === "filled" &&
								"bg-primary-foreground/10 text-primary-foreground",
							variant === "outline" && "bg-muted/50 text-muted-foreground",
							variant === "ghost" && "bg-muted/50 text-muted-foreground",
							variant === "destructive" &&
								"bg-destructive-foreground/10 text-destructive-foreground",
							variant === "success" &&
								"bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-400",
						)}
					>
						<Icon className="h-5 w-5" />
					</div>
				)}
			</div>

			{/* Footer */}
			{footer && (
				<div
					className={cn(
						"mt-4 pt-4 border-t",
						variant === "filled" && "border-primary-foreground/10",
						variant === "destructive" && "border-destructive-foreground/10",
						loading && "animate-pulse",
					)}
				>
					{footer}
				</div>
			)}
		</div>
	);
}

export interface StatGroupProps extends React.HTMLAttributes<HTMLDivElement> {
	/**
	 * Number of columns for larger screens
	 */
	cols?: 1 | 2 | 3 | 4;
	/**
	 * Whether to apply gap between cards
	 */
	gap?: boolean;
}

export function StatGroup({
	className,
	cols = 4,
	gap = true,
	children,
	...props
}: StatGroupProps) {
	return (
		<div
			className={cn(
				"grid grid-cols-1 md:grid-cols-2",
				cols === 3 && "lg:grid-cols-3",
				cols === 4 && "lg:grid-cols-4",
				gap && "gap-4 md:gap-6",
				className,
			)}
			{...props}
		>
			{children}
		</div>
	);
}

export { statCardVariants };
