"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";
import {
	OnboardingRadioCardGroup,
	OnboardingRadioCardItem,
} from "../primitives/onboarding-radio-card";

export interface BooleanField {
	/** Unique identifier for the field */
	id: string;
	/** Label/question text */
	label: string;
	/** Optional description/helper text */
	description?: string;
	/** Display mode: 'toggle' for checkbox, 'yesno' for Yes/No radio buttons */
	mode?: "toggle" | "yesno";
	/** Default value */
	defaultValue?: boolean;
	/** Whether this field is required to be true (e.g., terms acceptance) */
	requiredTrue?: boolean;
	/** Custom yes/no labels */
	yesLabel?: string;
	noLabel?: string;
}

export interface BooleanStepProps {
	/** Title displayed at the top of the step */
	title?: string;
	/** Description text below the title */
	description?: string | ReactNode;
	/** Array of boolean fields */
	fields: BooleanField[];
	/** Called when any value changes */
	onValuesChange?: (values: Record<string, boolean>) => void;
	/** Called when the user submits the form */
	onSubmit: (values: Record<string, boolean>) => 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 BooleanStep({
	title = "Confirm your preferences",
	description = "Please review and confirm the options below.",
	fields,
	onValuesChange,
	onSubmit,
	submitText = "Continue",
	loadingText = "Submitting...",
	backButton,
}: BooleanStepProps) {
	const [values, setValues] = useState<Record<string, boolean>>(() => {
		const initial: Record<string, boolean> = {};
		fields.forEach((field) => {
			initial[field.id] = field.defaultValue ?? false;
		});
		return initial;
	});
	const [loading, setLoading] = useState(false);

	const handleChange = (fieldId: string, value: boolean) => {
		const newValues = { ...values, [fieldId]: value };
		setValues(newValues);
		onValuesChange?.(newValues);
	};

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

	const isValid = fields.every((field) => {
		if (field.requiredTrue && !values[field.id]) return false;
		return true;
	});

	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">
				<div className="flex flex-col gap-4">
					{fields.map((field, index) => (
						<div
							key={field.id}
							className="motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-4"
							style={{
								animationDuration: "500ms",
								animationDelay: `${100 + index * 75}ms`,
								animationFillMode: "backwards",
							}}
						>
							{field.mode === "yesno" ? (
								<div>
									<OnboardingLabel className="mb-3 block text-sm font-medium text-foreground">
										{field.label}
										{field.requiredTrue && (
											<span className="ml-1 text-destructive">*</span>
										)}
									</OnboardingLabel>
									{field.description && (
										<p className="mb-3 text-sm text-muted-foreground">
											{field.description}
										</p>
									)}
									<OnboardingRadioCardGroup
										value={values[field.id] ? "yes" : "no"}
										onValueChange={(value) =>
											handleChange(field.id, value === "yes")
										}
										className="grid grid-cols-2 gap-3"
									>
										<OnboardingRadioCardItem
											value="yes"
											className="flex items-center justify-center p-4"
										>
											<span className="font-medium">
												{field.yesLabel || "Yes"}
											</span>
										</OnboardingRadioCardItem>
										<OnboardingRadioCardItem
											value="no"
											className="flex items-center justify-center p-4"
										>
											<span className="font-medium">
												{field.noLabel || "No"}
											</span>
										</OnboardingRadioCardItem>
									</OnboardingRadioCardGroup>
								</div>
							) : (
								<OnboardingCard
									asChild
									className={cx(
										"cursor-pointer border-border p-4 transition-all",
										values[field.id] && "border-primary",
										"focus-within:ring-2 focus-within:ring-ring/30 focus-within:border-primary",
									)}
								>
									<OnboardingLabel
										className="flex items-start gap-4"
										htmlFor={field.id}
									>
										<OnboardingCheckbox
											id={field.id}
											checked={values[field.id]}
											onCheckedChange={(checked) =>
												handleChange(field.id, checked === true)
											}
											className="mt-0.5"
										/>
										<div className="flex-1">
											<span className="font-medium text-foreground">
												{field.label}
												{field.requiredTrue && (
													<span className="ml-1 text-destructive">*</span>
												)}
											</span>
											{field.description && (
												<p className="mt-1 text-sm text-muted-foreground">
													{field.description}
												</p>
											)}
										</div>
									</OnboardingLabel>
								</OnboardingCard>
							)}
						</div>
					))}
				</div>

				<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>
	);
}
