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

/**
 * Timeline component for displaying chronological events
 *
 * @example
 * ```tsx
 * <Timeline>
 *   <TimelineItem
 *     date="2023"
 *     title="Published Eugene Onegin"
 *     description="A milestone in Russian literature"
 *     icon={BookOpen}
 *   />
 *   <TimelineItem
 *     date="2024"
 *     title="New translation released"
 *     variant="highlight"
 *   />
 * </Timeline>
 * ```
 */

const timelineVariants = cva("relative", {
	variants: {
		variant: {
			default: "",
			compact: "",
			detailed: "",
		},
		orientation: {
			vertical: "pl-6",
			horizontal: "flex",
		},
	},
	defaultVariants: {
		variant: "default",
		orientation: "vertical",
	},
});

export interface TimelineProps
	extends React.HTMLAttributes<HTMLDivElement>,
		VariantProps<typeof timelineVariants> {}

const Timeline = forwardRef<HTMLDivElement, TimelineProps>(
	({ className, variant, orientation, ...props }, ref) => {
		return (
			<div
				className={cn(timelineVariants({ variant, orientation, className }))}
				ref={ref}
				{...props}
			/>
		);
	},
);

Timeline.displayName = "Timeline";

const timelineItemVariants = cva("relative mb-8 last:mb-0", {
	variants: {
		variant: {
			default: "",
			highlight: "bg-muted/20 rounded-md p-4 border-l-2 border-primary",
			muted: "text-muted-foreground",
			card: "bg-card rounded-md p-4 shadow-sm border",
		},
		orientation: {
			vertical: "pl-0",
			horizontal: "flex-1",
		},
	},
	defaultVariants: {
		variant: "default",
		orientation: "vertical",
	},
});

export interface TimelineItemProps
	extends Omit<React.HTMLAttributes<HTMLDivElement>, "title">,
		VariantProps<typeof timelineItemVariants> {
	/**
	 * The date or time of the event
	 */
	date?: string;
	/**
	 * The title of the event (can be text or a React component)
	 */
	title?: React.ReactNode;
	/**
	 * Optional description of the event
	 */
	description?: React.ReactNode;
	/**
	 * Optional icon to display
	 */
	icon?: LucideIcon;
	/**
	 * Whether this is the active event
	 */
	active?: boolean;
	/**
	 * Custom dot/indicator content
	 */
	customDot?: React.ReactNode;
}

const TimelineItem = forwardRef<HTMLDivElement, TimelineItemProps>(
	(
		{
			className,
			variant,
			orientation,
			date,
			title,
			description,
			icon: Icon,
			active = false,
			customDot,
			children,
			...props
		},
		ref,
	) => {
		const isVertical = orientation !== "horizontal";

		return (
			<div
				className={cn(
					timelineItemVariants({ variant, orientation, className }),
				)}
				ref={ref}
				{...props}
			>
				{/* Connector line (for vertical orientation) */}
				{isVertical && (
					<div className="absolute top-0 left-0 h-full w-px bg-border ml-1.5 -z-10" />
				)}

				{/* Date indicator (for vertical orientation) */}
				{isVertical && date && (
					<div className="text-sm font-medium text-muted-foreground mb-1">
						{date}
					</div>
				)}

				<div className="flex items-start gap-4">
					{/* Dot/indicator */}
					{isVertical && (
						<div className="flex-shrink-0 relative -left-[18px] mt-1">
							{customDot || (
								<div
									className={cn(
										"w-3 h-3 rounded-full border-2",
										active
											? "bg-primary border-background"
											: "bg-background border-primary",
										Icon && "mt-1",
									)}
								>
									{Icon && (
										<div className="bg-muted h-6 w-6 rounded-full flex items-center justify-center -mt-1.5 -ml-1.5">
											<Icon className="h-3 w-3" />
										</div>
									)}
								</div>
							)}
						</div>
					)}

					{/* Content */}
					<div className={cn("flex-1 min-w-0", isVertical ? "-mt-0.5" : "")}>
						{/* Date (for horizontal orientation) */}
						{!isVertical && date && (
							<div className="text-sm font-medium text-muted-foreground mb-1">
								{date}
							</div>
						)}

						{/* Title */}
						{title && (
							<h4
								className={cn(
									"font-medium text-base",
									active && "text-primary",
								)}
							>
								{title}
							</h4>
						)}

						{/* Description */}
						{description && (
							<div className="text-sm text-muted-foreground mt-1">
								{description}
							</div>
						)}

						{/* Additional content */}
						{children && (
							<div className={cn(title || description ? "mt-2" : "")}>
								{children}
							</div>
						)}
					</div>
				</div>
			</div>
		);
	},
);

TimelineItem.displayName = "TimelineItem";

export { Timeline, TimelineItem, timelineVariants, timelineItemVariants };
