import type { ProgramCategory } from '@/admin/api/program-categories';
import { programCategoriesApi } from '@/admin/api/program-categories';
import { Button } from '@/components/ui/button';
import {
	Combobox,
	ComboboxChip,
	ComboboxChips,
	ComboboxChipsInput,
	ComboboxContent,
	ComboboxEmpty,
	ComboboxItem,
	ComboboxList,
	ComboboxValue,
	useComboboxAnchor,
} from '@/components/ui/combobox';
import {
	Dialog,
	DialogContent,
	DialogFooter,
	DialogHeader,
	DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
	Select,
	SelectContent,
	SelectItem,
	SelectTrigger,
	SelectValue,
} from '@/components/ui/select';
import { Separator } from '@/components/ui/separator';
import { useForm } from '@tanstack/react-form';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { __ } from '@wordpress/i18n';
import { Info, Plus } from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';
import {
	defaultSettingsValues,
	useTypedAppFormContext,
} from './program-form-context';

export type ProgramSettingsValues = {
	category_ids: number[];
	max_enrollments: number;
	price_is_free: boolean;
	price_amount: number;
};

type Props = {
	currency: string;
};

const ProgramSettings = ({ currency }: Props) => {
	const form = useTypedAppFormContext({ defaultValues: defaultSettingsValues });
	const queryClient = useQueryClient();
	const [addOpen, setAddOpen] = useState(false);

	const { data } = useQuery({
		queryKey: ['program-categories'],
		queryFn: () => programCategoriesApi.list({ per_page: 100 }),
	});

	const currencyData = __ALLCOACH_ADMIN__.currencies.find(
		(c) => c.code === currency,
	);
	const currencySymbol = currencyData
		? `${currency} (${currencyData.symbol})`
		: currency;

	const allCategories = data?.program_categories ?? [];

	const createCategory = useMutation({
		mutationFn: (name: string) => programCategoriesApi.create({ name }),
		onSuccess: (newCat: ProgramCategory) => {
			queryClient.invalidateQueries({ queryKey: ['program-categories'] });
			form.setFieldValue('category_ids', [
				...form.getFieldValue('category_ids'),
				newCat.id,
			]);
			newCategoryForm.reset();
			setAddOpen(false);
		},
		onError: () => toast.error(__('Failed to create category.', 'allcoach')),
	});

	const newCategoryForm = useForm({
		defaultValues: { name: '' },
		onSubmit: async ({ value }) => {
			await createCategory.mutateAsync(value.name.trim());
		},
	});

	const anchor = useComboboxAnchor();

	return (
		<div className="flex flex-col gap-4">
			<div className="rounded-xl border border-gray-200 bg-white p-6">
				<p className="text-[11px] font-semibold tracking-widest text-gray-400 uppercase">
					{__('General', 'allcoach')}
				</p>

				<div className="mt-5 flex flex-col gap-5">
					{/* Category */}
					<div>
						<div className="mb-1.5 flex items-center justify-between">
							<Label className="text-[13px] font-semibold text-gray-900">
								{__('Category', 'allcoach')}
							</Label>
							<Button
								type="button"
								variant="secondary"
								size="sm"
								className="bg-secondary h-auto cursor-pointer gap-1 px-2 py-0.5 text-[11px]"
								onClick={() => setAddOpen(true)}
							>
								<Plus className="size-3" />
								{__('Add New', 'allcoach')}
							</Button>
						</div>
						<p className="mb-1.5 text-[12px] leading-none text-gray-400">
							{__('Organize this program under a category.', 'allcoach')}
						</p>
						<form.Field name="category_ids">
							{(field) => (
								<Combobox
									multiple
									autoHighlight
									items={allCategories}
									value={allCategories.filter((cat) =>
										field.state.value.includes(cat.id),
									)}
									onValueChange={(selected) =>
										field.handleChange(selected.map((cat) => cat.id))
									}
								>
									<ComboboxChips ref={anchor} className="w-full">
										<ComboboxValue>
											{(selected) => (
												<>
													{selected.map((cat: ProgramCategory) => (
														<ComboboxChip key={cat.id}>
															{cat.name}
														</ComboboxChip>
													))}
													<ComboboxChipsInput
														placeholder={
															selected.length === 0
																? __('Search categories…', 'allcoach')
																: __('Add more…', 'allcoach')
														}
														className="border-0! shadow-none!"
													/>
												</>
											)}
										</ComboboxValue>
									</ComboboxChips>
									<ComboboxContent anchor={anchor}>
										<ComboboxEmpty>
											{__('No categories found.', 'allcoach')}
										</ComboboxEmpty>
										<ComboboxList>
											{(item: ProgramCategory) => (
												<ComboboxItem value={item}>
													{item.name}
												</ComboboxItem>
											)}
										</ComboboxList>
									</ComboboxContent>
								</Combobox>
							)}
						</form.Field>
					</div>

					{/* Limit spots */}
					<div>
						<Label className="text-[13px] font-semibold text-gray-900">
							{__('Limit spots', 'allcoach')}
						</Label>
						<p className="mb-1.5 text-[12px] text-gray-400">
							{__(
								'Max number of clients who can enrol. Use 0 for unlimited.',
								'allcoach',
							)}
						</p>
						<form.Field name="max_enrollments">
							{(field) => (
								<Input
									type="number"
									min={0}
									value={field.state.value}
									onChange={(e) => {
										field.handleChange(
											Math.max(0, parseInt(e.target.value, 10) || 0),
										);
									}}
									className="w-full text-[13px]"
									placeholder="0"
								/>
							)}
						</form.Field>
					</div>
				</div>
			</div>

			{/* Pricing */}
			<div className="rounded-xl border border-gray-200 bg-white p-6">
				<p className="text-[11px] font-semibold tracking-widest text-gray-400 uppercase">
					{__('Pricing', 'allcoach')}
				</p>

				<div className="mt-5 flex flex-col gap-5">
					{/* Free / Paid */}
					<div>
						<Label className="text-[13px] font-semibold text-gray-900">
							{__('Price type', 'allcoach')}
						</Label>
						<p className="mb-1.5 text-[12px] text-gray-400">
							{__('Set whether this program is free or paid.', 'allcoach')}
						</p>
						<form.Field name="price_is_free">
							{(field) => (
								<>
									<Select
										value={field.state.value ? 'free' : 'paid'}
										onValueChange={(value) =>
											field.handleChange(value === 'free')
										}
									>
										<SelectTrigger className="!z-auto w-full text-[13px]">
											<SelectValue />
										</SelectTrigger>
										<SelectContent className="!z-[999999]">
											<SelectItem value="free" className="text-[13px]">
												{__('Free', 'allcoach')}
											</SelectItem>
											<SelectItem value="paid" className="text-[13px]">
												{__('Paid', 'allcoach')}
											</SelectItem>
										</SelectContent>
									</Select>
									{field.state.value && (
										<div className="mt-2 flex max-w-sm items-center gap-2 rounded-md border border-blue-100 bg-blue-50 px-3 py-2">
											<Info className="size-4 shrink-0 text-blue-400" />
											<p className="text-[12px] text-blue-600">
												{__(
													'Users need to register to enrol in this program.',
													'allcoach',
												)}
											</p>
										</div>
									)}
								</>
							)}
						</form.Field>
					</div>

					{/* Price amount — shown when paid */}
					<form.Subscribe selector={(state) => state.values.price_is_free}>
						{(isFree) =>
							!isFree && (
								<div>
									<Label className="text-[13px] font-semibold text-gray-900">
										{__('Amount', 'allcoach')}
									</Label>
									<p className="mb-1.5 text-[12px] text-gray-400">
										{__('Price clients will pay to enrol.', 'allcoach')}
									</p>
									<form.Field name="price_amount">
										{(field) => (
											<div className="flex items-center gap-2">
												<Input
													type="number"
													min={0}
													step={0.01}
													value={field.state.value || ''}
													onChange={(e) =>
														field.handleChange(parseFloat(e.target.value) || 0)
													}
													className="w-full text-[13px]"
													placeholder="0.00"
												/>
												<span className="shrink-0 text-[13px] whitespace-nowrap text-gray-500">
													{currencySymbol}
												</span>
											</div>
										)}
									</form.Field>
								</div>
							)
						}
					</form.Subscribe>
				</div>
			</div>

			{/* Add New Category dialog */}
			{/* Add New Category dialog */}
			<Dialog
				open={addOpen}
				onOpenChange={(open) => {
					setAddOpen(open);
					if (!open) newCategoryForm.reset();
				}}
			>
				<DialogContent
					className="!z-[999999] gap-0 p-0 sm:!max-w-sm"
					overlayClassName="!z-[999998]"
				>
					<form
						onSubmit={(e) => {
							e.preventDefault();
							newCategoryForm.handleSubmit();
						}}
					>
						<DialogHeader className="px-6 py-4 pe-12">
							<DialogTitle className="text-[15px] font-semibold text-gray-900">
								{__('New Category', 'allcoach')}
							</DialogTitle>
						</DialogHeader>
						<Separator />
						<div className="px-6 py-5">
							<newCategoryForm.Field
								name="name"
								validators={{
									onBlur: ({ value }) =>
										!value.trim()
											? __('Name is required.', 'allcoach')
											: undefined,
									onSubmit: ({ value }) =>
										!value.trim()
											? __('Name is required.', 'allcoach')
											: undefined,
								}}
							>
								{(field) => {
									const error = field.state.meta.errors[0];
									return (
										<>
											<Label className="mb-1.5 block text-[13px] font-semibold text-gray-900">
												{__('Name', 'allcoach')}
											</Label>
											<Input
												autoFocus
												placeholder={__('e.g. Strength Training', 'allcoach')}
												value={field.state.value}
												onChange={(e) => field.handleChange(e.target.value)}
												onBlur={field.handleBlur}
												className={`text-[13px] ${error ? 'border-red-400 focus-visible:ring-red-200' : ''}`}
											/>
											{error && (
												<p className="mt-1.5 text-[12px] text-red-500">
													{String(error)}
												</p>
											)}
										</>
									);
								}}
							</newCategoryForm.Field>
						</div>
						<Separator />
						<DialogFooter className="px-6 py-4">
							<Button
								type="button"
								variant="outline"
								size="sm"
								className="cursor-pointer text-[13px]"
								onClick={() => setAddOpen(false)}
							>
								{__('Cancel', 'allcoach')}
							</Button>
							<newCategoryForm.Subscribe selector={(s) => s.isSubmitting}>
								{(isSubmitting) => (
									<Button
										type="submit"
										size="sm"
										className="cursor-pointer bg-teal-600 text-[13px] hover:bg-teal-700"
										disabled={isSubmitting}
									>
										{isSubmitting
											? __('Creating…', 'allcoach')
											: __('Create', 'allcoach')}
									</Button>
								)}
							</newCategoryForm.Subscribe>
						</DialogFooter>
					</form>
				</DialogContent>
			</Dialog>
		</div>
	);
};

export default ProgramSettings;
