"use client";

import React, { type ReactNode, useState } from "react";
import { cx } from "../lib/utils";
import { OnboardingButton } from "../primitives/onboarding-button";
import { OnboardingLabel } from "../primitives/onboarding-label";
import {
	OnboardingRadioCardGroup,
	OnboardingRadioCardItem,
} from "../primitives/onboarding-radio-card";
import {
	OnboardingSelect,
	OnboardingSelectContent,
	OnboardingSelectItem,
	OnboardingSelectTrigger,
	OnboardingSelectValue,
} from "../primitives/onboarding-select";

export interface CardOption {
	/** Unique identifier */
	id: string;
	/** Display name */
	name: string;
	/** Icon or logo - can be a ReactNode (e.g., Iconify icon) */
	icon?: ReactNode;
	/** Optional description text */
	description?: string;
	/** Optional badge text (e.g., "Popular", "New") */
	badge?: string;
	/** Optional dropdown options for this card */
	dropdown?: {
		label: string;
		placeholder?: string;
		options: { value: string; label: string }[];
		defaultValue?: string;
	};
}

export interface CardGridConfig {
	selectedId: string;
	dropdownValues: Record<string, string>;
}

export interface CardGridStepProps {
	/** Title displayed at the top of the step */
	title?: string;
	/** Description text below the title */
	description?: string;
	/** Array of card options to display */
	options: CardOption[];
	/** Number of columns in the grid (default: 2) */
	columns?: 1 | 2 | 3 | 4;
	/** Card layout orientation (default: 'vertical') */
	layout?: "vertical" | "horizontal";
	/** Initially selected option id */
	defaultSelected?: string;
	/** Initial dropdown values */
	defaultDropdownValues?: Record<string, string>;
	/** Called when selection or dropdown changes */
	onChange?: (config: CardGridConfig) => void;
	/** Called when the user submits the form */
	onSubmit: (config: CardGridConfig) => void | Promise<void>;
	/** Text for the submit button */
	submitText?: string;
	/** Text shown while submitting */
	loadingText?: string;
	/** Optional back button config */
	backButton?: {
		text: string;
		onClick: () => void;
	};
}

const columnClasses = {
	1: "",
	2: "md:grid-cols-2",
	3: "md:grid-cols-3",
	4: "md:grid-cols-4",
};

export function CardGridStep({
	title = "Select an option",
	description = "Choose the option that best fits your needs.",
	options,
	columns = 2,
	layout = "vertical",
	defaultSelected = "",
	defaultDropdownValues = {},
	onChange,
	onSubmit,
	submitText = "Continue",
	loadingText = "Submitting...",
	backButton,
}: CardGridStepProps) {
	const [selectedId, setSelectedId] = useState(defaultSelected);
	const [dropdownValues, setDropdownValues] = useState<Record<string, string>>(
		defaultDropdownValues,
	);
	const [loading, setLoading] = useState(false);

	const handleSelectionChange = (id: string) => {
		setSelectedId(id);
		onChange?.({ selectedId: id, dropdownValues });
	};

	const handleDropdownChange = (optionId: string, value: string) => {
		const newValues = { ...dropdownValues, [optionId]: value };
		setDropdownValues(newValues);
		onChange?.({ selectedId, dropdownValues: newValues });
	};

	const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
		e.preventDefault();
		setLoading(true);
		try {
			await onSubmit({ selectedId, dropdownValues });
		} finally {
			setLoading(false);
		}
	};

	// Check if selected option has a required dropdown
	const selectedOption = options.find((opt) => opt.id === selectedId);
	const hasRequiredDropdown =
		selectedOption?.dropdown && !dropdownValues[selectedId];
	const isValid = selectedId && !hasRequiredDropdown;

	return (
		<main className="mx-auto p-4">
			<div
				style={{ animationDuration: "500ms" }}
				className="motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-4"
			>
				<h1 className="text-2xl font-semibold text-foreground sm:text-xl">
					{title}
				</h1>
				<p className="mt-6 text-muted-foreground sm:text-sm">{description}</p>
			</div>

			<form onSubmit={handleSubmit} className="mt-8">
				<fieldset>
					<legend className="sr-only">{title}</legend>
					<OnboardingRadioCardGroup
						value={selectedId}
						onValueChange={handleSelectionChange}
						className={cx("grid grid-cols-1 gap-4", columnClasses[columns])}
						aria-label={title}
					>
						{options.map((option, index) => (
							<div
								key={option.id}
								className="motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-4"
								style={{
									animationDuration: "600ms",
									animationDelay: `${100 + index * 75}ms`,
									animationFillMode: "backwards",
								}}
							>
								<OnboardingRadioCardItem
									value={option.id}
									className={cx(
										"relative p-4",
										layout === "horizontal"
											? "flex flex-row items-center gap-4 text-left"
											: "flex flex-col items-center p-6 text-center",
									)}
								>
									{option.badge && (
										<span className="absolute right-2 top-2 rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary">
											{option.badge}
										</span>
									)}
									{option.icon && (
										<div
											className={cx(
												"flex items-center justify-center shrink-0",
												layout === "horizontal"
													? "h-10 w-10 text-3xl"
													: "mb-3 h-12 w-12 text-4xl",
											)}
										>
											{option.icon}
										</div>
									)}
									<div
										className={layout === "horizontal" ? "flex-1 min-w-0" : ""}
									>
										<span className="font-semibold text-foreground">
											{option.name}
										</span>
										{option.description && (
											<p
												className={cx(
													"text-muted-foreground",
													layout === "horizontal"
														? "text-sm mt-0.5"
														: "mt-1 text-xs",
												)}
											>
												{option.description}
											</p>
										)}
									</div>
								</OnboardingRadioCardItem>

								{/* Dropdown appears below the card when selected */}
								{option.dropdown && selectedId === option.id && (
									<div
										className="mt-3 motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-top-2"
										style={{ animationDuration: "200ms" }}
									>
										<OnboardingLabel
											className="mb-2 block text-sm font-medium text-foreground"
											htmlFor={`dropdown-${option.id}`}
										>
											{option.dropdown.label}
										</OnboardingLabel>
										<OnboardingSelect
											value={dropdownValues[option.id] || ""}
											onValueChange={(value) =>
												handleDropdownChange(option.id, value)
											}
										>
											<OnboardingSelectTrigger
												id={`dropdown-${option.id}`}
												className="w-full"
											>
												<OnboardingSelectValue
													placeholder={
														option.dropdown.placeholder || "Select..."
													}
												/>
											</OnboardingSelectTrigger>
											<OnboardingSelectContent>
												{option.dropdown.options.map((opt) => (
													<OnboardingSelectItem
														key={opt.value}
														value={opt.value}
													>
														{opt.label}
													</OnboardingSelectItem>
												))}
											</OnboardingSelectContent>
										</OnboardingSelect>
									</div>
								)}
							</div>
						))}
					</OnboardingRadioCardGroup>
				</fieldset>

				<div
					className={cx(
						"mt-8 flex",
						backButton ? "justify-between" : "justify-end",
					)}
				>
					{backButton && (
						<OnboardingButton
							type="button"
							variant="ghost"
							onClick={backButton.onClick}
						>
							{backButton.text}
						</OnboardingButton>
					)}
					<OnboardingButton
						className="disabled:bg-muted disabled:text-muted-foreground"
						type="submit"
						disabled={!isValid || loading}
						aria-disabled={!isValid || loading}
						isLoading={loading}
					>
						{loading ? loadingText : submitText}
					</OnboardingButton>
				</div>
			</form>
		</main>
	);
}
