import { programsApi, type ProgramSession } from '@/admin/api/programs';
import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogTitle,
	AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import {
	Dialog,
	DialogContent,
	DialogFooter,
	DialogHeader,
	DialogTitle,
} from '@/components/ui/dialog';
import { FieldError } from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Separator } from '@/components/ui/separator';
import {
	Tooltip,
	TooltipContent,
	TooltipTrigger,
} from '@/components/ui/tooltip';
import { cn } from '@/lib/utils';
import { useForm } from '@tanstack/react-form';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { __ } from '@wordpress/i18n';
import { CalendarDays, Pencil, Plus, Trash2 } from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';

type Props = {
	programId: string;
	session: ProgramSession | null;
};

const DURATION_OPTIONS = [15, 30, 60, 90, 120] as const;
type DurationOption = (typeof DURATION_OPTIONS)[number] | 'custom';

// ---------- inner form (mounts fresh each time dialog opens) ----------

type SessionFormProps = {
	programId: string;
	session: ProgramSession | null;
	onClose: () => void;
	onSaved: (updated: Awaited<ReturnType<typeof programsApi.update>>) => void;
};

const SessionForm = ({
	programId,
	session,
	onClose,
	onSaved,
}: SessionFormProps) => {
	const getDefaultValues = () => {
		if (session !== null) {
			const isPreset = (DURATION_OPTIONS as readonly number[]).includes(
				session.duration_minutes,
			);
			return {
				appointments: String(session.repetition_count),
				duration: (isPreset
					? session.duration_minutes
					: 'custom') as DurationOption,
				customDuration: isPreset ? '' : String(session.duration_minutes),
			};
		}
		return {
			appointments: '',
			duration: 60 as DurationOption,
			customDuration: '',
		};
	};

	const saveMutation = useMutation({
		mutationFn: (data: {
			session_duration_minutes: number;
			session_repetition_count: number;
		}) => programsApi.update(Number(programId), data),
		onSuccess: (updated) => {
			toast.success(__('Session saved.', 'allcoach'));
			onSaved(updated);
		},
		onError: () => toast.error(__('Failed to save session.', 'allcoach')),
	});

	const form = useForm({
		defaultValues: getDefaultValues(),
		onSubmit: async ({ value }) => {
			const count = parseInt(value.appointments, 10);
			const mins =
				value.duration === 'custom'
					? parseInt(value.customDuration, 10)
					: value.duration;
			await saveMutation.mutateAsync({
				session_repetition_count: count,
				session_duration_minutes: mins,
			});
		},
	});

	return (
		<form
			onSubmit={(e) => {
				e.preventDefault();
				form.handleSubmit();
			}}
		>
			<DialogHeader className="flex-row items-center justify-between px-6 py-5">
				<DialogTitle className="text-[15px] font-semibold text-gray-900">
					{__('Add 1-on-1 Session', 'allcoach')}
				</DialogTitle>
				<Button
					type="button"
					variant="outline"
					size="icon-sm"
					className="cursor-pointer text-gray-400 hover:text-gray-600"
					onClick={onClose}
				>
					<span className="sr-only">{__('Close', 'allcoach')}</span>×
				</Button>
			</DialogHeader>

			<Separator />

			<div className="space-y-5 px-6 py-5">
				{/* Number of appointments */}
				<form.Field
					name="appointments"
					validators={{
						onBlur: ({ value }) => {
							if (!value)
								return __('Number of appointments is required.', 'allcoach');
							const n = parseInt(value, 10);
							if (isNaN(n) || n < 1)
								return __('Must be a whole number of at least 1.', 'allcoach');
							return undefined;
						},
					}}
				>
					{(field) => {
						const isInvalid =
							field.state.meta.isTouched && !field.state.meta.isValid;
						return (
							<div>
								<Label
									htmlFor={field.name}
									className="mb-1 text-[13px] font-semibold text-gray-900"
								>
									{__('Number of appointments', 'allcoach')}
									<span className="text-destructive">*</span>
								</Label>
								<p className="mb-2.5 text-[12px] text-gray-400">
									{__(
										'Total sessions included in this program package.',
										'allcoach',
									)}
								</p>
								<Input
									id={field.name}
									type="number"
									min={1}
									placeholder="e.g. 8"
									value={field.state.value}
									onChange={(e) => field.handleChange(e.target.value)}
									onBlur={field.handleBlur}
									className={cn(
										'w-40 text-[13px]',
										isInvalid && 'border-red-400 focus-visible:ring-red-200',
									)}
								/>
								{isInvalid && (
									<FieldError
										className="mt-1.5 text-[12px]"
										errors={field.state.meta.errors.map((e) =>
											typeof e === 'string' ? { message: e } : e,
										)}
									/>
								)}
							</div>
						);
					}}
				</form.Field>

				<Separator />

				{/* Duration */}
				<form.Field name="duration">
					{(durationField) => (
						<form.Field
							name="customDuration"
							validators={{
								onBlur: ({ value }) => {
									if (durationField.state.value !== 'custom') return undefined;
									if (!value)
										return __('Custom duration is required.', 'allcoach');
									const n = parseInt(value, 10);
									if (isNaN(n) || n < 1)
										return __('Must be at least 1 minute.', 'allcoach');
									return undefined;
								},
							}}
						>
							{(customField) => {
								const customInvalid =
									durationField.state.value === 'custom' &&
									customField.state.meta.isTouched &&
									!customField.state.meta.isValid;
								return (
									<div>
										<Label className="mb-1 text-[13px] font-semibold text-gray-900">
											{__('Duration', 'allcoach')}
											<span className="text-destructive">*</span>
										</Label>
										<p className="mb-3 text-[12px] text-gray-400">
											{__('Length of each individual session.', 'allcoach')}
										</p>
										<div className="flex flex-wrap items-center gap-2">
											{DURATION_OPTIONS.map((opt) => (
												<button
													key={opt}
													type="button"
													onClick={() => durationField.handleChange(opt)}
													className={cn(
														'rounded-full border px-4 py-1.5 text-[13px] font-medium transition-colors',
														durationField.state.value === opt
															? 'border-teal-600 bg-teal-600 text-white'
															: 'border-gray-200 bg-white text-gray-700 hover:border-gray-300',
													)}
												>
													{opt} {__('min', 'allcoach')}
												</button>
											))}
											<button
												type="button"
												onClick={() => durationField.handleChange('custom')}
												className={cn(
													'rounded-full border px-4 py-1.5 text-[13px] font-medium transition-colors',
													durationField.state.value === 'custom'
														? 'border-teal-600 bg-teal-600 text-white'
														: 'border-gray-200 bg-white text-gray-700 hover:border-gray-300',
												)}
											>
												{__('Custom', 'allcoach')}
											</button>
											{durationField.state.value === 'custom' && (
												<div className="flex items-center gap-1.5">
													<Input
														type="number"
														min={1}
														placeholder="e.g. 45"
														value={customField.state.value}
														onChange={(e) =>
															customField.handleChange(e.target.value)
														}
														onBlur={customField.handleBlur}
														className={cn(
															'w-24 text-[13px]',
															customInvalid &&
																'border-red-400 focus-visible:ring-red-200',
														)}
													/>
													<span className="text-[13px] text-gray-500">
														{__('min', 'allcoach')}
													</span>
												</div>
											)}
										</div>
										{customInvalid && (
											<FieldError
												className="mt-1.5 text-[12px]"
												errors={customField.state.meta.errors.map((e) =>
													typeof e === 'string' ? { message: e } : e,
												)}
											/>
										)}
									</div>
								);
							}}
						</form.Field>
					)}
				</form.Field>
			</div>

			<Separator />

			<DialogFooter className="px-6 py-4">
				<Button
					type="button"
					variant="outline"
					size="sm"
					className="cursor-pointer text-[13px]"
					onClick={onClose}
				>
					{__('Cancel', 'allcoach')}
				</Button>
				<form.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}
						>
							{__('Save Session', 'allcoach')}
						</Button>
					)}
				</form.Subscribe>
			</DialogFooter>
		</form>
	);
};

const ProgramSessions = ({ programId, session }: Props) => {
	const queryClient = useQueryClient();
	const [open, setOpen] = useState(false);

	const deleteMutation = useMutation({
		mutationFn: () =>
			programsApi.update(Number(programId), { remove_session: true }),
		onSuccess: (updated) => {
			queryClient.setQueryData(['program', programId], updated);
			queryClient.invalidateQueries({ queryKey: ['programs'] });
			toast.success(__('Session removed.', 'allcoach'));
		},
		onError: () => toast.error(__('Failed to remove session.', 'allcoach')),
	});

	const handleSaved = (
		updated: Awaited<ReturnType<typeof programsApi.update>>,
	) => {
		queryClient.setQueryData(['program', programId], updated);
		queryClient.invalidateQueries({ queryKey: ['programs'] });
		setOpen(false);
	};

	return (
		<div>
			{session !== null ? (
				<div className="rounded-xl border border-gray-200 bg-white p-4">
					<div className="flex items-center justify-between gap-3">
						<div className="flex min-w-0 items-center gap-4">
							<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-teal-50">
								<CalendarDays className="size-5 text-teal-500" />
							</div>

							<div>
								<p className="!text-[11px] font-semibold tracking-widest text-gray-400 uppercase">
									{__('Duration', 'allcoach')}
								</p>
								<p className="!text-[14px] font-bold text-teal-600">
									{session.duration_minutes} {__('min', 'allcoach')}
								</p>
							</div>

							<div>
								<p className="!text-[11px] font-semibold tracking-widest text-gray-400 uppercase">
									{__('Appointments', 'allcoach')}
								</p>
								<p className="!text-[14px] font-bold text-gray-700">
									{session.repetition_count}
								</p>
							</div>
						</div>
						<div className="flex shrink-0 items-center gap-1">
							<Tooltip>
								<TooltipTrigger asChild>
									<Button
										variant="outline"
										size="icon-sm"
										className="cursor-pointer text-gray-400 hover:text-gray-600"
										onClick={() => setOpen(true)}
									>
										<Pencil className="size-3.5" />
									</Button>
								</TooltipTrigger>
								<TooltipContent side="top" className="!z-[999999]">
									{__('Edit session', 'allcoach')}
								</TooltipContent>
							</Tooltip>

							<AlertDialog>
								<Tooltip>
									<TooltipTrigger asChild>
										<span className="inline-flex">
											<AlertDialogTrigger asChild>
												<Button
													variant="outline"
													size="icon-sm"
													className="cursor-pointer text-gray-400 hover:border-red-200 hover:text-red-500"
													disabled={deleteMutation.isPending}
												>
													<Trash2 className="size-3.5" />
												</Button>
											</AlertDialogTrigger>
										</span>
									</TooltipTrigger>
									<TooltipContent side="top" className="!z-[999999]">
										{__('Delete session', 'allcoach')}
									</TooltipContent>
								</Tooltip>
								<AlertDialogContent
									size="sm"
									className="!z-[999999]"
									overlayClassName="!z-[999998]"
								>
									<AlertDialogHeader>
										<AlertDialogTitle className="text-[15px]">
											{__('Delete session?', 'allcoach')}
										</AlertDialogTitle>
										<AlertDialogDescription className="text-[13px]">
											{__(
												'This will remove the session from this program.',
												'allcoach',
											)}
										</AlertDialogDescription>
									</AlertDialogHeader>
									<AlertDialogFooter>
										<AlertDialogCancel
											size="sm"
											className="cursor-pointer text-[13px]"
										>
											{__('Cancel', 'allcoach')}
										</AlertDialogCancel>
										<AlertDialogAction
											size="sm"
											variant="destructive"
											className="cursor-pointer text-[13px]"
											onClick={() => deleteMutation.mutate()}
										>
											{deleteMutation.isPending
												? __('Deleting...', 'allcoach')
												: __('Delete', 'allcoach')}
										</AlertDialogAction>
									</AlertDialogFooter>
								</AlertDialogContent>
							</AlertDialog>
						</div>
					</div>
				</div>
			) : (
				<div className="flex items-center justify-between rounded-xl border border-dashed border-gray-200 bg-white px-5 py-4">
					<div className="flex items-center gap-3">
						<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-teal-50">
							<CalendarDays className="size-4 text-teal-500" />
						</div>
						<div>
							<p className="text-[13px] font-semibold text-gray-800">
								{__('No session added yet', 'allcoach')}
							</p>
							<p className="text-[12px] text-gray-400">
								{__('Define duration and number of appointments.', 'allcoach')}
							</p>
						</div>
					</div>
					<Button
						size="sm"
						className="cursor-pointer bg-teal-600 text-[13px] hover:bg-teal-700"
						onClick={() => setOpen(true)}
					>
						<Plus className="size-3.5" />
						{__('Add Session', 'allcoach')}
					</Button>
				</div>
			)}

			<Dialog open={open} onOpenChange={setOpen}>
				<DialogContent
					className="!z-[999999] gap-0 p-0 sm:!max-w-xl"
					overlayClassName="!z-[999998]"
					showCloseButton={false}
				>
					<SessionForm
						programId={programId}
						session={session}
						onClose={() => setOpen(false)}
						onSaved={handleSaved}
					/>
				</DialogContent>
			</Dialog>
		</div>
	);
};

export default ProgramSessions;
