import type { WeeklySchedule } from '@/admin/api/availabilities';
import { availabilitiesApi } from '@/admin/api/availabilities';
import { availabilitiesQuery } from '@/admin/queries/availabilities';
import { generateTimeOptions, to12h, to24h, today } from '@/admin/utils/time';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import {
	Select,
	SelectContent,
	SelectItem,
	SelectTrigger,
	SelectValue,
} from '@/components/ui/select';
import { Skeleton } from '@/components/ui/skeleton';
import { Spinner } from '@/components/ui/spinner';
import { Switch } from '@/components/ui/switch';
import { useForm } from '@tanstack/react-form';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { __ } from '@wordpress/i18n';
import { CalendarDays } from 'lucide-react';
import { useEffect, useState } from 'react';
import { toast } from 'sonner';

const DAYS = [
	'Sunday',
	'Monday',
	'Tuesday',
	'Wednesday',
	'Thursday',
	'Friday',
	'Saturday',
] as const;
const DAY_NAMES = [
	'sunday',
	'monday',
	'tuesday',
	'wednesday',
	'thursday',
	'friday',
	'saturday',
] as const;
type DayName = (typeof DAY_NAMES)[number];

type DayHours = {
	enabled: boolean;
	start: string;
	end: string;
};

const TIME_OPTIONS = generateTimeOptions();

const AvailabilitySettings = () => {
	const queryClient = useQueryClient();
	const [weeklyHours, setWeeklyHours] = useState<DayHours[]>([]);

	const form = useForm({
		defaultValues: {
			timezone: 'UTC',
		},
	});

	// ─── Load availabilities ────────────────────────────────────────────────
	const { data, isLoading } = useQuery(availabilitiesQuery());

	const applyAvailability = (
		avail: NonNullable<typeof data>['availabilities'][number],
	) => {
		if (avail.timezone) {
			form.setFieldValue('timezone', avail.timezone);
		}
		setWeeklyHours(
			DAY_NAMES.map((day) => {
				const d = avail.schedule?.[day as DayName];
				return d?.repeat && d.start_time && d.end_time
					? {
							enabled: true,
							start: to12h(d.start_time),
							end: to12h(d.end_time),
						}
					: { enabled: false, start: '9:00am', end: '5:00pm' };
			}),
		);
	};

	useEffect(() => {
		const avail = data?.availabilities?.[0];
		if (avail) applyAvailability(avail);
	}, [data]);

	// ─── Save mutation ───────────────────────────────────────────────────────
	const save = useMutation({
		mutationFn: async () => {
			const existingAvailability = data?.availabilities?.[0];
			const timezone = form.state.values.timezone;

			const schedule = Object.fromEntries(
				DAY_NAMES.map((day, i) => [
					day,
					{
						repeat: weeklyHours[i].enabled,
						start_time: weeklyHours[i].enabled
							? to24h(weeklyHours[i].start)
							: '',
						end_time: weeklyHours[i].enabled ? to24h(weeklyHours[i].end) : '',
					},
				]),
			) as WeeklySchedule;

			const currentUserId = __ALLCOACH_ADMIN__.currentUserId;

			if (existingAvailability?.id) {
				await availabilitiesApi.update(existingAvailability.id, {
					user_id: currentUserId,
					timezone,
					schedule,
				});
			} else {
				await availabilitiesApi.create({
					user_id: currentUserId,
					start_date: today(),
					timezone,
					schedule,
				});
			}
		},
		onSuccess: () => {
			queryClient.invalidateQueries({ queryKey: ['availabilities'] });
			toast.success(__('Availability saved.', 'allcoach'));
		},
		onError: () => {
			toast.error(
				__('Failed to save availability. Please try again.', 'allcoach'),
			);
		},
	});

	const updateDay = (index: number, patch: Partial<DayHours>) =>
		setWeeklyHours((prev) =>
			prev.map((d, i) => (i === index ? { ...d, ...patch } : d)),
		);

	const handleReset = () => {
		const avail = data?.availabilities?.[0];
		if (avail) applyAvailability(avail);
	};

	return (
		<div className="flex flex-col">
			{/* Header */}
			<div className="flex items-center gap-2 border-b border-gray-100 px-5 py-5 md:px-8">
				<CalendarDays className="size-4 text-teal-600" />
				<h2 className="text-[15px] font-semibold text-gray-900">
					{__('Availability', 'allcoach')}
				</h2>
			</div>

			{isLoading || weeklyHours.length === 0 ? (
				<div className="space-y-6 px-5 py-6 md:px-8">
					<div>
						<Skeleton className="mb-1.5 h-4 w-20" />
						<Skeleton className="h-9 w-full" />
					</div>
					<div className="h-px bg-gray-100" />
					<div>
						<Skeleton className="mb-4 h-4 w-28" />
						<div className="space-y-2.5">
							{Array.from({ length: 7 }).map((_, i) => (
								<div key={i} className="flex items-center gap-3">
									<Skeleton className="h-5 w-9 shrink-0 rounded-full" />
									<Skeleton className="h-4 w-24 shrink-0" />
									<Skeleton className="h-9 flex-1" />
								</div>
							))}
						</div>
					</div>
				</div>
			) : (
				<div className="space-y-6 px-5 py-6 md:px-8">
					{/* Timezone */}
					<div>
						<Label className="mb-1.5 block text-[13px] font-semibold text-gray-900">
							{__('Time zone', 'allcoach')}
						</Label>
						<form.Field name="timezone">
							{(field) => (
								<Select
									value={field.state.value}
									onValueChange={field.handleChange}
								>
									<SelectTrigger className="w-full text-[13px]">
										<SelectValue />
									</SelectTrigger>
									<SelectContent className="!z-[999999]">
										{__ALLCOACH_ADMIN__.timezones.map((tz) => (
											<SelectItem
												key={`${tz.value}-${tz.abbr}`}
												value={tz.value}
												className="text-[13px]"
											>
												{tz.text}
											</SelectItem>
										))}
									</SelectContent>
								</Select>
							)}
						</form.Field>
					</div>

					<div className="h-px bg-gray-100" />

					{/* Weekly hours */}
					<div>
						<p className="mb-4 text-[13px] font-semibold text-gray-900">
							{__('Weekly hours', 'allcoach')}
						</p>

						<div className="space-y-2.5">
							{/* Column headers */}
							<div className="ms-[152px] grid grid-cols-[1fr_12px_1fr] items-center gap-2 pb-1">
								<span className="text-[11px] font-semibold tracking-widest text-gray-400 uppercase">
									{__('START', 'allcoach')}
								</span>
								<div />
								<span className="text-[11px] font-semibold tracking-widest text-gray-400 uppercase">
									{__('END', 'allcoach')}
								</span>
							</div>

							{DAYS.map((day, i) => {
								const hours = weeklyHours[i];
								return (
									<div key={day} className="flex items-center gap-3">
										<Switch
											checked={hours.enabled}
											onCheckedChange={(checked) =>
												updateDay(i, { enabled: checked })
											}
											className="shrink-0 data-[state=checked]:!bg-teal-600"
										/>
										<span
											className={`w-24 shrink-0 text-[13px] font-medium ${hours.enabled ? 'text-gray-700' : 'text-gray-400'}`}
										>
											{day}
										</span>

										{hours.enabled ? (
											<div className="grid flex-1 grid-cols-[1fr_12px_1fr] items-center gap-2">
												<Select
													value={hours.start}
													onValueChange={(v) => updateDay(i, { start: v })}
												>
													<SelectTrigger className="w-full text-[13px]">
														<SelectValue />
													</SelectTrigger>
													<SelectContent className="!z-[999999] max-h-60">
														{TIME_OPTIONS.map((t) => (
															<SelectItem
																key={t.value}
																value={t.value}
																className="text-[13px]"
															>
																{t.label}
															</SelectItem>
														))}
													</SelectContent>
												</Select>

												<span className="text-center text-[13px] text-gray-400">
													–
												</span>

												<Select
													value={hours.end}
													onValueChange={(v) => updateDay(i, { end: v })}
												>
													<SelectTrigger className="w-full text-[13px]">
														<SelectValue />
													</SelectTrigger>
													<SelectContent className="!z-[999999] max-h-60">
														{TIME_OPTIONS.map((t) => (
															<SelectItem
																key={t.value}
																value={t.value}
																className="text-[13px]"
															>
																{t.label}
															</SelectItem>
														))}
													</SelectContent>
												</Select>
											</div>
										) : (
											<span className="text-[13px] text-gray-400">
												{__('Unavailable', 'allcoach')}
											</span>
										)}
									</div>
								);
							})}
						</div>
					</div>
				</div>
			)}

			{/* Footer */}
			<div className="flex justify-end gap-2 border-t border-gray-100 px-5 py-4 md:px-8">
				<Button
					type="button"
					size="sm"
					className="cursor-pointer bg-teal-600 text-[13px] hover:bg-teal-700"
					disabled={save.isPending}
					onClick={() => save.mutate()}
				>
					{save.isPending && <Spinner className="size-3.5" />}
					{__('Save', 'allcoach')}
				</Button>
			</div>
		</div>
	);
};

export default AvailabilitySettings;
