"use client";

import React, { type ReactNode, useState } from "react";
import { cx } from "../lib/utils";
import { OnboardingButton } from "../primitives/onboarding-button";
import { OnboardingCard } from "../primitives/onboarding-card";
import { OnboardingCheckbox } from "../primitives/onboarding-checkbox";
import { OnboardingLabel } from "../primitives/onboarding-label";

export interface IconOption {
	/** 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;
}

export interface IconSelectStepProps {
	/** Title displayed at the top of the step */
	title?: string;
	/** Description text below the title */
	description?: string;
	/** Array of options to display */
	options: IconOption[];
	/** Selection mode: single or multiple */
	selectionMode?: "single" | "multiple";
	/** Initially selected option id(s) */
	defaultSelected?: string[];
	/** Called when selection changes */
	onSelectionChange?: (selectedIds: string[]) => void;
	/** Called when the user submits the form */
	onSubmit: (selectedIds: string[]) => 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;
	};
}

export function IconSelectStep({
	title = "Select an option",
	description = "Choose the options that apply to you.",
	options,
	selectionMode = "multiple",
	defaultSelected = [],
	onSelectionChange,
	onSubmit,
	submitText = "Continue",
	loadingText = "Submitting...",
	backButton,
}: IconSelectStepProps) {
	const [selectedIds, setSelectedIds] = useState<string[]>(defaultSelected);
	const [loading, setLoading] = useState(false);

	const handleToggle = (id: string, checked: boolean) => {
		let newSelected: string[];

		if (selectionMode === "single") {
			newSelected = checked ? [id] : [];
		} else {
			newSelected = checked
				? [...selectedIds, id]
				: selectedIds.filter((selectedId) => selectedId !== id);
		}

		setSelectedIds(newSelected);
		onSelectionChange?.(newSelected);
	};

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

	const isValid = selectedIds.length > 0;

	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>
					<div className="space-y-3">
						{options.map((option, index) => {
							const isSelected = selectedIds.includes(option.id);

							return (
								<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 * 50}ms`,
										animationFillMode: "backwards",
									}}
								>
									<OnboardingCard
										asChild
										className={cx(
											"cursor-pointer border-border p-4 transition-all active:scale-[99%]",
											isSelected && "border-primary",
											"focus-within:ring-2",
											"focus-within:ring-ring/30",
											"focus-within:border-primary",
										)}
									>
										<OnboardingLabel
											className="flex items-center gap-4"
											htmlFor={option.id}
										>
											<OnboardingCheckbox
												id={option.id}
												checked={isSelected}
												onCheckedChange={(checked) =>
													handleToggle(option.id, checked === true)
												}
											/>
											{option.icon && (
												<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted p-1.5 text-2xl ring-1 ring-border">
													{option.icon}
												</div>
											)}
											<div className="flex-1 min-w-0">
												<span className="font-medium text-foreground">
													{option.name}
												</span>
												{option.description && (
													<p className="text-sm text-muted-foreground mt-0.5">
														{option.description}
													</p>
												)}
											</div>
										</OnboardingLabel>
									</OnboardingCard>
								</div>
							);
						})}
					</div>
				</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>
	);
}
