"use client";

import type React from "react";
import { useState } from "react";
import { cx } from "../lib/utils";
import { OnboardingBadge } from "../primitives/onboarding-badge";
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 ProductCategory {
	id: string;
	title: string;
	subcategories: string[];
}

export interface ProductSelectionStepProps {
	/** Title displayed at the top of the step */
	title?: string;
	/** Description text below the title */
	description?: string;
	/** Array of product categories to display */
	categories: ProductCategory[];
	/** Initially selected category IDs */
	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;
	};
}

interface CategoryItemProps {
	category: ProductCategory;
	checked: boolean;
	onCheckedChange: (categoryId: string, checked: boolean) => void;
}

function CategoryItem({
	category,
	checked,
	onCheckedChange,
}: CategoryItemProps) {
	return (
		<OnboardingCard
			asChild
			className={cx(
				"cursor-pointer border-border p-5 transition-all active:scale-[99%]",
				"has-checked:border-primary",
				"focus-within:ring-2",
				"focus-within:ring-ring/30",
				"focus-within:border-primary",
			)}
		>
			<OnboardingLabel className="block" htmlFor={category.id}>
				<div className="mb-2 flex items-center gap-2.5">
					<OnboardingCheckbox
						id={category.id}
						name={category.title}
						checked={checked}
						onCheckedChange={(isChecked) =>
							onCheckedChange(category.id, isChecked === true)
						}
					/>
					<span className="text-base font-medium sm:text-sm">
						{category.title}
					</span>
				</div>
				{category.subcategories.length > 0 && (
					<ul className="ml-6 mt-2 flex flex-wrap gap-1.5">
						{category.subcategories.map((subcategory) => (
							<li key={subcategory}>
								<OnboardingBadge variant="neutral">
									{subcategory}
								</OnboardingBadge>
							</li>
						))}
					</ul>
				)}
			</OnboardingLabel>
		</OnboardingCard>
	);
}

export function ProductSelectionStep({
	title = "Which products are you interested in?",
	description = "You can choose multiple. This will help us customize the experience.",
	categories,
	defaultSelected = [],
	onSelectionChange,
	onSubmit,
	submitText = "Continue",
	loadingText = "Submitting...",
	backButton,
}: ProductSelectionStepProps) {
	const [checkedItems, setCheckedItems] = useState<Record<string, boolean>>(
		() => {
			const initial: Record<string, boolean> = {};
			defaultSelected.forEach((id) => {
				initial[id] = true;
			});
			return initial;
		},
	);
	const [loading, setLoading] = useState(false);

	const handleCheckedChange = (categoryId: string, isChecked: boolean) => {
		const newCheckedItems = {
			...checkedItems,
			[categoryId]: isChecked,
		};
		setCheckedItems(newCheckedItems);

		if (onSelectionChange) {
			const selectedIds = Object.entries(newCheckedItems)
				.filter(([, checked]) => checked)
				.map(([id]) => id);
			onSelectionChange(selectedIds);
		}
	};

	const selectedIds = Object.entries(checkedItems)
		.filter(([, checked]) => checked)
		.map(([id]) => id);

	const isAnyItemChecked = selectedIds.length > 0;

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

	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-4">
				<fieldset>
					<legend className="sr-only">{title}</legend>
					<div className="space-y-2">
						{categories.map((category, index) => (
							<div
								className="motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-4"
								key={category.id}
								style={{
									animationDuration: "600ms",
									animationDelay: `${100 + index * 50}ms`,
									animationFillMode: "backwards",
								}}
							>
								<CategoryItem
									category={category}
									checked={checkedItems[category.id] || false}
									onCheckedChange={handleCheckedChange}
								/>
							</div>
						))}
					</div>
				</fieldset>
				<div
					className={cx(
						"mt-6 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={!isAnyItemChecked || loading}
						aria-disabled={!isAnyItemChecked || loading}
						isLoading={loading}
					>
						{loading ? loadingText : submitText}
					</OnboardingButton>
				</div>
			</form>
		</main>
	);
}
