<script lang="ts">
	import { client } from '$lib/graphql/client';
	import { CREATE_SCHEDULE, UPDATE_SCHEDULE } from '$lib/graphql/mutations/location';
	import type { AddressSchedule } from '$lib/graphql/queries/account';

	interface Props {
		schedule?: AddressSchedule | null;
		accountAddressId: string;
		existingSchedules?: AddressSchedule[];
		onSuccess: () => void;
		onCancel: () => void;
	}

	let { schedule, accountAddressId, existingSchedules = [], onSuccess, onCancel }: Props = $props();

	let isEdit = $derived(!!schedule);

	// Form state - use $effect to sync from props
	let name = $state('');
	let monday = $state(false);
	let tuesday = $state(false);
	let wednesday = $state(false);
	let thursday = $state(false);
	let friday = $state(false);
	let saturday = $state(false);
	let sunday = $state(false);
	let weekendService = $state(false);
	let scheduleException = $state('');
	let startDate = $state('');
	let endDate = $state('');

	// Sync form state from props
	$effect(() => {
		name = schedule?.name ?? '';
		monday = schedule?.monday ?? false;
		tuesday = schedule?.tuesday ?? false;
		wednesday = schedule?.wednesday ?? false;
		thursday = schedule?.thursday ?? false;
		friday = schedule?.friday ?? false;
		saturday = schedule?.saturday ?? false;
		sunday = schedule?.sunday ?? false;
		weekendService = schedule?.weekendService ?? false;
		scheduleException = schedule?.scheduleException ?? '';
		startDate = schedule?.startDate ?? new Date().toISOString().split('T')[0];
		endDate = schedule?.endDate ?? '';
	});

	let loading = $state(false);
	let error = $state<string | null>(null);

	// Check for date range overlaps with existing schedules
	function checkOverlap(): string | null {
		if (!startDate) return null;

		const newStart = startDate;
		const newEnd = endDate || null;

		for (const existing of existingSchedules) {
			// Skip the schedule being edited
			if (isEdit && schedule && existing.id === schedule.id) continue;

			const existingStart = existing.startDate;
			const existingEnd = existing.endDate;

			// Check for overlap
			// Two ranges overlap if: start1 <= end2 AND start2 <= end1
			// Handle null end dates as "infinity"
			const newEndsAfterExistingStarts = !existingStart || !newEnd || newEnd >= existingStart;
			const existingEndsAfterNewStarts = !newStart || !existingEnd || existingEnd >= newStart;
			const newStartsBeforeExistingEnds = !existingEnd || newStart <= existingEnd;
			const existingStartsBeforeNewEnds = !newEnd || !existingStart || existingStart <= newEnd;

			if (
				newEndsAfterExistingStarts &&
				existingEndsAfterNewStarts &&
				newStartsBeforeExistingEnds &&
				existingStartsBeforeNewEnds
			) {
				const existingName = existing.name || 'Service Schedule';
				const existingRange = existing.startDate
					? `${existing.startDate}${existing.endDate ? ` to ${existing.endDate}` : ' (ongoing)'}`
					: 'ongoing';
				return `Date range overlaps with "${existingName}" (${existingRange})`;
			}
		}

		return null;
	}

	// When weekend service is toggled, clear individual weekend days
	$effect(() => {
		if (weekendService) {
			friday = false;
			saturday = false;
			sunday = false;
		}
	});

	async function handleSubmit(event: SubmitEvent) {
		event.preventDefault();
		loading = true;
		error = null;

		// Check for overlapping schedules
		const overlapError = checkOverlap();
		if (overlapError) {
			error = overlapError;
			loading = false;
			return;
		}

		try {
			const input = {
				name: name || undefined,
				monday,
				tuesday,
				wednesday,
				thursday,
				friday: weekendService ? false : friday,
				saturday: weekendService ? false : saturday,
				sunday: weekendService ? false : sunday,
				weekendService,
				scheduleException: scheduleException || undefined,
				startDate: startDate || undefined,
				endDate: endDate || undefined
			};

			if (isEdit && schedule) {
				await client.mutate({
					mutation: UPDATE_SCHEDULE,
					variables: { id: schedule.id, input }
				});
			} else {
				await client.mutate({
					mutation: CREATE_SCHEDULE,
					variables: { accountAddressId, input }
				});
			}

			onSuccess();
		} catch (err) {
			error = err instanceof Error ? err.message : 'An error occurred';
		} finally {
			loading = false;
		}
	}

	// Preset helpers
	function setWeekdays() {
		monday = true;
		tuesday = true;
		wednesday = true;
		thursday = true;
		friday = true;
		saturday = false;
		sunday = false;
		weekendService = false;
	}

	function clearAll() {
		monday = false;
		tuesday = false;
		wednesday = false;
		thursday = false;
		friday = false;
		saturday = false;
		sunday = false;
		weekendService = false;
	}

	function getDayValue(key: string): boolean {
		switch (key) {
			case 'monday':
				return monday;
			case 'tuesday':
				return tuesday;
			case 'wednesday':
				return wednesday;
			case 'thursday':
				return thursday;
			case 'friday':
				return friday;
			case 'saturday':
				return saturday;
			case 'sunday':
				return sunday;
			default:
				return false;
		}
	}
</script>

<form onsubmit={handleSubmit} class="space-y-5">
	{#if error}
		<div class="rounded-lg border border-error-500/30 bg-error-50/50 p-3 dark:bg-error-950/30">
			<p class="text-sm text-error-700 dark:text-error-400">{error}</p>
		</div>
	{/if}

	<div>
		<label for="name" class="form-label">Schedule Name</label>
		<input
			id="name"
			type="text"
			bind:value={name}
			class="input-base"
			disabled={loading}
			placeholder="e.g., Service Schedule"
		/>
	</div>

	<div>
		<div class="mb-2 flex items-center justify-between">
			<span class="form-label mb-0">Service Days</span>
			<div class="flex gap-2">
				<button
					type="button"
					onclick={setWeekdays}
					class="text-xs text-primary-600 hover:text-primary-700 dark:text-primary-400"
					disabled={loading}
				>
					Weekdays
				</button>
				<span class="text-theme-muted">|</span>
				<button
					type="button"
					onclick={clearAll}
					class="text-xs text-theme-muted hover:text-theme"
					disabled={loading}
				>
					Clear
				</button>
			</div>
		</div>

		<div class="grid grid-cols-4 gap-2 sm:grid-cols-7">
			{#each [{ key: 'monday', label: 'Mon', short: 'M' }, { key: 'tuesday', label: 'Tue', short: 'T' }, { key: 'wednesday', label: 'Wed', short: 'W' }, { key: 'thursday', label: 'Thu', short: 'Th' }, { key: 'friday', label: 'Fri', short: 'F', isWeekend: true }, { key: 'saturday', label: 'Sat', short: 'Sa', isWeekend: true }, { key: 'sunday', label: 'Sun', short: 'Su', isWeekend: true }] as day}
				<button
					type="button"
					onclick={() => {
						if (day.key === 'monday') monday = !monday;
						else if (day.key === 'tuesday') tuesday = !tuesday;
						else if (day.key === 'wednesday') wednesday = !wednesday;
						else if (day.key === 'thursday') thursday = !thursday;
						else if (day.key === 'friday') friday = !friday;
						else if (day.key === 'saturday') saturday = !saturday;
						else if (day.key === 'sunday') sunday = !sunday;
					}}
					class="flex h-12 flex-col items-center justify-center rounded-lg border text-sm font-medium transition-colors
						{getDayValue(day.key)
						? 'border-primary-500 bg-primary-500 text-white'
						: 'bg-theme-secondary/30 hover:bg-theme-secondary/50 border-theme text-theme-muted'}
						{loading || (day.isWeekend && weekendService) ? 'cursor-not-allowed opacity-50' : ''}"
					disabled={loading || (day.isWeekend && weekendService)}
				>
					<span class="hidden sm:inline">{day.label}</span>
					<span class="sm:hidden">{day.short}</span>
				</button>
			{/each}
		</div>
	</div>

	<div class="bg-theme-secondary/30 rounded-lg border border-theme p-4">
		<div class="flex items-start gap-3">
			<input
				id="weekendService"
				type="checkbox"
				bind:checked={weekendService}
				class="mt-0.5 h-4 w-4 rounded border-theme text-primary-600 focus:ring-primary-500"
				disabled={loading}
			/>
			<div>
				<label for="weekendService" class="font-medium text-theme">Weekend Service</label>
				<p class="mt-0.5 text-sm text-theme-muted">
					Service can be completed anytime Friday through Sunday
				</p>
			</div>
		</div>
	</div>

	<div>
		<label for="scheduleException" class="form-label">Schedule Exceptions</label>
		<textarea
			id="scheduleException"
			bind:value={scheduleException}
			class="textarea-base"
			rows="2"
			disabled={loading}
			placeholder="e.g., No service on holidays, alternate Fridays only"
		></textarea>
	</div>

	<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
		<div>
			<label for="startDate" class="form-label">
				Start Date <span class="required-indicator">*</span>
			</label>
			<input
				id="startDate"
				type="date"
				bind:value={startDate}
				class="input-base"
				required
				disabled={loading}
			/>
		</div>
		<div>
			<label for="endDate" class="form-label">End Date</label>
			<input
				id="endDate"
				type="date"
				bind:value={endDate}
				class="input-base"
				min={startDate || undefined}
				disabled={loading}
			/>
			<p class="mt-1 text-xs text-theme-muted">Leave blank for ongoing schedule</p>
		</div>
	</div>

	<div class="rounded-lg border border-primary-500/30 bg-primary-50/50 p-3 dark:bg-primary-950/30">
		<p class="text-sm text-primary-700 dark:text-primary-400">
			Schedules cannot have overlapping date ranges. Each schedule must have a unique time period.
		</p>
	</div>

	<div class="form-actions border-t border-theme pt-5">
		<button type="button" class="btn-cancel" onclick={onCancel} disabled={loading}>Cancel</button>
		<button type="submit" class="btn-submit" disabled={loading}>
			{#if loading}
				Saving...
			{:else if isEdit}
				Update Schedule
			{:else}
				Add Schedule
			{/if}
		</button>
	</div>
</form>
