"use client";

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

export interface DropdownOption {
	value: string;
	label: string;
	disabled?: boolean;
}

export interface DropdownOptionGroup {
	label: string;
	options: DropdownOption[];
}

export interface DropdownField {
	/** Unique identifier for the field */
	id: string;
	/** Label displayed above the dropdown */
	label: string;
	/** Placeholder text when no value selected */
	placeholder?: string;
	/** Optional description/helper text */
	description?: string;
	/** Whether the field is required */
	required?: boolean;
	/** Options (flat array or grouped) */
	options: DropdownOption[] | DropdownOptionGroup[];
	/** Default value */
	defaultValue?: string;
}

export interface DropdownSelectStepProps {
	/** Title displayed at the top of the step */
	title?: string;
	/** Description text below the title */
	description?: string;
	/** Array of dropdown fields */
	fields: DropdownField[];
	/** Called when any value changes */
	onValuesChange?: (values: Record<string, string>) => void;
	/** Called when the user submits the form */
	onSubmit: (values: Record<string, 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;
	};
}

function isGroupedOptions(
	options: DropdownOption[] | DropdownOptionGroup[],
): options is DropdownOptionGroup[] {
	return options.length > 0 && "options" in options[0];
}

export function DropdownSelectStep({
	title = "Select your preferences",
	description = "Please make your selections below.",
	fields,
	onValuesChange,
	onSubmit,
	submitText = "Continue",
	loadingText = "Submitting...",
	backButton,
}: DropdownSelectStepProps) {
	const [values, setValues] = useState<Record<string, string>>(() => {
		const initial: Record<string, string> = {};
		fields.forEach((field) => {
			initial[field.id] = field.defaultValue ?? "";
		});
		return initial;
	});
	const [loading, setLoading] = useState(false);

	const handleChange = (fieldId: string, value: string) => {
		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.required && !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-6">
					{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 * 100}ms`,
								animationFillMode: "backwards",
							}}
						>
							<OnboardingLabel
								className="mb-2 block text-sm font-medium text-foreground"
								htmlFor={field.id}
							>
								{field.label}
								{field.required && (
									<span className="ml-1 text-destructive">*</span>
								)}
							</OnboardingLabel>

							{field.description && (
								<p className="mb-2 text-sm text-muted-foreground">
									{field.description}
								</p>
							)}

							<OnboardingSelect
								value={values[field.id]}
								onValueChange={(value) => handleChange(field.id, value)}
							>
								<OnboardingSelectTrigger id={field.id} className="w-full">
									<OnboardingSelectValue
										placeholder={field.placeholder || "Select..."}
									/>
								</OnboardingSelectTrigger>
								<OnboardingSelectContent>
									{isGroupedOptions(field.options)
										? field.options.map((group) => (
												<OnboardingSelectGroup key={group.label}>
													<OnboardingLabel className="px-2 py-1.5 text-xs font-semibold text-muted-foreground">
														{group.label}
													</OnboardingLabel>
													{group.options.map((option) => (
														<OnboardingSelectItem
															key={option.value}
															value={option.value}
															disabled={option.disabled}
														>
															{option.label}
														</OnboardingSelectItem>
													))}
												</OnboardingSelectGroup>
											))
										: field.options.map((option) => (
												<OnboardingSelectItem
													key={option.value}
													value={option.value}
													disabled={option.disabled}
												>
													{option.label}
												</OnboardingSelectItem>
											))}
								</OnboardingSelectContent>
							</OnboardingSelect>
						</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>
	);
}
