<script lang="ts">
	import {
		calendarService,
		type CalendarEvent,
		type Attendee,
		type CreateEventInput,
		type EventReminder,
		type EventReminders,
		EVENT_COLORS
	} from '$lib/services/calendar';
	import { offCanvas } from '$lib/stores/offCanvas.svelte';
	import { SvelteDate, SvelteSet } from 'svelte/reactivity';

	interface TeamProfile {
		id: string;
		fullName: string;
		email?: string | null;
		role: string;
		status: string;
	}

	interface InitialValues {
		summary?: string;
		location?: string;
		date?: string;
	}

	interface Props {
		teamProfiles: TeamProfile[];
		event?: CalendarEvent | null;
		initialValues?: InitialValues;
		onSuccess?: (eventId: string) => void;
		onCancel?: () => void;
	}

	let { teamProfiles, event = null, initialValues, onSuccess, onCancel }: Props = $props();

	let submitting = $state(false);
	let error = $state('');

	// Form fields - prioritize event (edit mode), then initialValues (pre-population), then defaults
	let summary = $state(event?.summary ?? initialValues?.summary ?? '');
	let description = $state(event?.description ?? '');
	let location = $state(event?.location ?? initialValues?.location ?? '');
	let isAllDay = $state(event ? !event.start.dateTime && !!event.start.date : false);

	// After midnight toggle - for when work starts after midnight but belongs to previous business day
	let isAfterMidnight = $state(false);

	// Helper to increment a date string by 1 day
	function incrementDate(dateStr: string): string {
		const date = new SvelteDate(dateStr + 'T12:00:00'); // noon to avoid DST issues
		date.setDate(date.getDate() + 1);
		return date.toISOString().split('T')[0];
	}

	// Parse existing event dates/times
	function parseDateTime(eventDateTime: { dateTime?: string; date?: string } | undefined): {
		date: string;
		time: string;
	} {
		if (!eventDateTime) {
			const now = new Date();
			return {
				date: now.toISOString().split('T')[0],
				time: '09:00'
			};
		}

		if (eventDateTime.dateTime) {
			const dt = new Date(eventDateTime.dateTime);
			return {
				date: dt.toISOString().split('T')[0],
				time: dt.toTimeString().slice(0, 5)
			};
		}

		if (eventDateTime.date) {
			return {
				date: eventDateTime.date,
				time: '09:00'
			};
		}

		const now = new Date();
		return {
			date: now.toISOString().split('T')[0],
			time: '09:00'
		};
	}

	const startParsed = parseDateTime(event?.start);
	const endParsed = parseDateTime(event?.end);

	// Use initialValues for date if no event is provided
	let startDate = $state(event ? startParsed.date : (initialValues?.date ?? startParsed.date));
	let startTime = $state(startParsed.time);
	let endDate = $state(event ? endParsed.date : (initialValues?.date ?? endParsed.date));
	let endTime = $state(endParsed.time);

	// Actual calendar dates (incremented by 1 day if after midnight is checked)
	let actualStartDate = $derived(
		isAfterMidnight && !isAllDay ? incrementDate(startDate) : startDate
	);
	let actualEndDate = $derived(isAfterMidnight && !isAllDay ? incrementDate(endDate) : endDate);

	// Selected attendees (set of email addresses)
	let selectedAttendeeEmails = new SvelteSet<string>(event?.attendees?.map((a) => a.email) ?? []);

	// Reminder settings
	let useDefaultReminders = $state(event?.reminders?.useDefault ?? true);
	let customReminders = $state<EventReminder[]>(event?.reminders?.overrides ?? []);

	// Event color
	let selectedColorId = $state<string | undefined>(event?.colorId);

	// Active team members with emails (ensure email is non-null)
	let availableAttendees = $derived(
		teamProfiles.filter(
			(p): p is typeof p & { email: string } => p.status === 'ACTIVE' && !!p.email
		)
	);

	function toggleAttendee(email: string) {
		if (selectedAttendeeEmails.has(email)) {
			selectedAttendeeEmails.delete(email);
		} else {
			selectedAttendeeEmails.add(email);
		}
	}

	function isAttendeeSelected(email: string): boolean {
		return selectedAttendeeEmails.has(email);
	}

	// Reminder helper functions
	const reminderPresets = [
		{ label: '10 minutes before', minutes: 10 },
		{ label: '30 minutes before', minutes: 30 },
		{ label: '1 hour before', minutes: 60 },
		{ label: '1 day before', minutes: 1440 },
		{ label: '1 week before', minutes: 10080 }
	];

	function addReminder() {
		customReminders = [...customReminders, { method: 'popup', minutes: 30 }];
	}

	function removeReminder(index: number) {
		customReminders = customReminders.filter((_, i) => i !== index);
	}

	function handleReminderMethodChange(index: number, e: Event) {
		const method = (e.currentTarget as HTMLSelectElement).value as 'email' | 'popup';
		customReminders = customReminders.map((r, i) => (i === index ? { ...r, method } : r));
	}

	function handleReminderMinutesChange(index: number, e: Event) {
		const minutes = parseInt((e.currentTarget as HTMLSelectElement).value);
		customReminders = customReminders.map((r, i) => (i === index ? { ...r, minutes } : r));
	}

	// Convert local date/time to UTC ISO string for the API
	function toUtcIsoString(date: string, time: string): string {
		// Parse as local time (browser's timezone - US/Eastern for our team)
		const localDateTime = new Date(`${date}T${time}:00`);
		// Convert to UTC ISO string (includes Z suffix)
		return localDateTime.toISOString();
	}

	async function handleSubmit(e: SubmitEvent) {
		e.preventDefault();
		submitting = true;
		error = '';

		try {
			if (!summary.trim()) {
				error = 'Please enter an event title';
				return;
			}

			// Build attendees from selected emails
			const attendees: Attendee[] = Array.from(selectedAttendeeEmails).map((email) => {
				const profile = teamProfiles.find((p) => p.email === email);
				return {
					email,
					displayName: profile?.fullName
				};
			});

			// Build reminders
			const reminders: EventReminders | undefined = useDefaultReminders
				? { useDefault: true }
				: customReminders.length > 0
					? { useDefault: false, overrides: customReminders }
					: undefined;

			// Build event input - use actualStartDate/actualEndDate for timed events (handles after-midnight shift)
			// For timed events, convert to UTC ISO string so the scheduler API can parse it
			const input: CreateEventInput = {
				summary: summary.trim(),
				description: description.trim() || undefined,
				location: location.trim() || undefined,
				start: isAllDay
					? { date: startDate }
					: { dateTime: toUtcIsoString(actualStartDate, startTime) },
				end: isAllDay
					? { date: endDate }
					: { dateTime: toUtcIsoString(actualEndDate, endTime) },
				attendees: attendees.length > 0 ? attendees : undefined,
				reminders,
				colorId: selectedColorId
			};

			let eventId: string;

			if (event) {
				// Update existing event
				const result = await calendarService.updateEvent(event.id, input);

				if (result.error) {
					error = result.error.message;
					return;
				}
				eventId = event.id;
			} else {
				// Create new event
				const result = await calendarService.createEvent(input);

				if (result.error) {
					error = result.error.message;
					return;
				}
				eventId = result.data!.id;
			}

			offCanvas.closeRight();
			onSuccess?.(eventId);
		} catch (err) {
			error = err instanceof Error ? err.message : 'Failed to save event';
		} finally {
			submitting = false;
		}
	}

	function handleCancel() {
		offCanvas.closeRight();
		onCancel?.();
	}
</script>

<form onsubmit={handleSubmit} class="flex h-full flex-col">
	<div class="flex-1 space-y-6 overflow-y-auto p-6">
		<!-- Event Title -->
		<div>
			<label for="summary" class="mb-1.5 block text-sm font-medium text-theme">Event Title</label>
			<input
				type="text"
				id="summary"
				bind:value={summary}
				placeholder="e.g., Team Meeting"
				class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-accent7-500 focus:ring-1 focus:ring-accent7-500"
				required
			/>
		</div>

		<!-- All Day Toggle -->
		<div class="flex items-center gap-3">
			<input
				type="checkbox"
				id="allDay"
				bind:checked={isAllDay}
				class="h-4 w-4 rounded border-theme text-accent7-500 focus:ring-accent7-500"
			/>
			<label for="allDay" class="text-sm font-medium text-theme">All-day event</label>
		</div>

		<!-- After Midnight Toggle (only for timed events) -->
		{#if !isAllDay}
			<div
				class="flex items-center gap-3 rounded-lg border border-amber-400/50 bg-amber-50 p-3 dark:border-amber-500/30 dark:bg-amber-900/20"
			>
				<input
					type="checkbox"
					id="afterMidnight"
					bind:checked={isAfterMidnight}
					class="h-4 w-4 rounded border-amber-400 text-amber-500 focus:ring-amber-500"
				/>
				<label for="afterMidnight" class="flex-1">
					<span class="block text-sm font-medium text-amber-800 dark:text-amber-200">
						Work begins after midnight
					</span>
					{#if isAfterMidnight}
						<span class="block text-xs text-amber-600 dark:text-amber-400">
							Calendar event will be scheduled for {actualStartDate} (next calendar day)
						</span>
					{:else}
						<span class="block text-xs text-amber-600 dark:text-amber-400">
							Check if work starts after midnight but belongs to the previous business day
						</span>
					{/if}
				</label>
			</div>
		{/if}

		<!-- Date/Time Fields -->
		<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
			<!-- Start -->
			<div>
				<label for="startDate" class="mb-1.5 block text-sm font-medium text-theme">Start</label>
				<input
					type="date"
					id="startDate"
					bind:value={startDate}
					class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-accent7-500 focus:ring-1 focus:ring-accent7-500"
					required
				/>
				{#if !isAllDay}
					<input
						type="time"
						id="startTime"
						bind:value={startTime}
						class="mt-2 w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-accent7-500 focus:ring-1 focus:ring-accent7-500"
						required
					/>
				{/if}
			</div>

			<!-- End -->
			<div>
				<label for="endDate" class="mb-1.5 block text-sm font-medium text-theme">End</label>
				<input
					type="date"
					id="endDate"
					bind:value={endDate}
					class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-accent7-500 focus:ring-1 focus:ring-accent7-500"
					required
				/>
				{#if !isAllDay}
					<input
						type="time"
						id="endTime"
						bind:value={endTime}
						class="mt-2 w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-accent7-500 focus:ring-1 focus:ring-accent7-500"
						required
					/>
				{/if}
			</div>
		</div>

		<!-- Location -->
		<div>
			<label for="location" class="mb-1.5 block text-sm font-medium text-theme"
				>Location (optional)</label
			>
			<input
				type="text"
				id="location"
				bind:value={location}
				placeholder="e.g., Conference Room A"
				class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-accent7-500 focus:ring-1 focus:ring-accent7-500"
			/>
		</div>

		<!-- Description -->
		<div>
			<label for="description" class="mb-1.5 block text-sm font-medium text-theme"
				>Description (optional)</label
			>
			<textarea
				id="description"
				bind:value={description}
				rows="3"
				placeholder="Add event details..."
				class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-accent7-500 focus:ring-1 focus:ring-accent7-500"
			></textarea>
		</div>

		<!-- Event Color -->
		<div>
			<span class="mb-2 block text-sm font-medium text-theme">Color (optional)</span>
			<div class="flex flex-wrap gap-2">
				<!-- No color option -->
				<button
					type="button"
					onclick={() => (selectedColorId = undefined)}
					class="flex h-8 w-8 items-center justify-center rounded-full border-2 transition-all
						{selectedColorId === undefined
						? 'border-accent7-500 ring-2 ring-accent7-500/30'
						: 'border-theme hover:border-theme-secondary'}"
					aria-label="No color"
					title="No color"
				>
					<svg class="h-4 w-4 text-theme-muted" style="fill: none" stroke="currentColor" viewBox="0 0 24 24">
						<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
					</svg>
				</button>
				{#each EVENT_COLORS as color (color.id)}
					<button
						type="button"
						onclick={() => (selectedColorId = color.id)}
						class="h-8 w-8 rounded-full border-2 transition-all {color.bg}
							{selectedColorId === color.id
							? 'border-accent7-500 ring-2 ring-accent7-500/30'
							: 'border-transparent hover:scale-110'}"
						aria-label={color.name}
						title={color.name}
					></button>
				{/each}
			</div>
		</div>

		<!-- Attendees -->
		<div>
			<span class="mb-2 block text-sm font-medium text-theme">Attendees</span>
			{#if availableAttendees.length > 0}
				<div
					class="max-h-48 space-y-2 overflow-y-auto rounded-lg border border-theme bg-theme-secondary p-3"
				>
					{#each availableAttendees as profile (profile.id)}
						{@const selected = isAttendeeSelected(profile.email)}
						<button
							type="button"
							onclick={() => toggleAttendee(profile.email)}
							class="flex w-full items-center gap-3 rounded-lg p-2 text-left transition-colors {selected
								? 'bg-accent7-500/20 text-accent7-700 dark:text-accent7-300'
								: 'hover:bg-black/5 dark:hover:bg-white/10'}"
						>
							<span
								class="flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full {selected
									? 'bg-accent7-500 text-white'
									: 'border border-theme bg-theme'}"
							>
								{#if selected}
									<svg class="h-4 w-4" style="fill: none" stroke="currentColor" viewBox="0 0 24 24">
										<path
											stroke-linecap="round"
											stroke-linejoin="round"
											stroke-width="2"
											d="M5 13l4 4L19 7"
										/>
									</svg>
								{/if}
							</span>
							<span class="min-w-0 flex-1">
								<span class="block truncate text-sm font-medium text-theme">{profile.fullName}</span
								>
								<span class="block truncate text-xs text-theme-muted">{profile.email}</span>
							</span>
						</button>
					{/each}
				</div>
				{#if selectedAttendeeEmails.size > 0}
					<p class="mt-2 text-xs text-theme-muted">
						{selectedAttendeeEmails.size} attendee{selectedAttendeeEmails.size !== 1 ? 's' : ''} selected
					</p>
				{/if}
			{:else}
				<p class="text-sm text-theme-muted italic">
					No team members with email addresses available.
				</p>
			{/if}
		</div>

		<!-- Reminders -->
		<div>
			<span class="mb-2 block text-sm font-medium text-theme">Reminders</span>

			<!-- Use Default Toggle -->
			<div class="mb-3 flex items-center gap-3">
				<input
					type="checkbox"
					id="useDefaultReminders"
					bind:checked={useDefaultReminders}
					class="h-4 w-4 rounded border-theme text-accent7-500 focus:ring-accent7-500"
				/>
				<label for="useDefaultReminders" class="text-sm text-theme">
					Use default reminders (30 minutes before via popup)
				</label>
			</div>

			<!-- Custom Reminders -->
			{#if !useDefaultReminders}
				<div class="space-y-3 rounded-lg border border-theme bg-theme-secondary p-3">
					{#if customReminders.length === 0}
						<p class="text-sm text-theme-muted italic">No reminders set. Add one below.</p>
					{:else}
						{#each customReminders as reminder, index (index)}
							<div class="flex items-center gap-2">
								<!-- Reminder Method -->
								<select
									onchange={(e) => handleReminderMethodChange(index, e)}
									class="rounded-lg border border-theme bg-theme px-3 py-2 text-sm text-theme focus:border-accent7-500 focus:ring-1 focus:ring-accent7-500"
								>
									<option value="popup" selected={reminder.method === 'popup'}>Popup</option>
									<option value="email" selected={reminder.method === 'email'}>Email</option>
								</select>

								<!-- Reminder Time -->
								<select
									onchange={(e) => handleReminderMinutesChange(index, e)}
									class="flex-1 rounded-lg border border-theme bg-theme px-3 py-2 text-sm text-theme focus:border-accent7-500 focus:ring-1 focus:ring-accent7-500"
								>
									{#each reminderPresets as preset (preset.minutes)}
										<option value={preset.minutes} selected={reminder.minutes === preset.minutes}
											>{preset.label}</option
										>
									{/each}
								</select>

								<!-- Remove Button -->
								<button
									type="button"
									onclick={() => removeReminder(index)}
									aria-label="Remove reminder"
									class="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-lg text-theme-muted transition-colors hover:bg-error-500/10 hover:text-error-500"
								>
									<svg class="h-5 w-5" style="fill: none" stroke="currentColor" viewBox="0 0 24 24">
										<path
											stroke-linecap="round"
											stroke-linejoin="round"
											stroke-width="2"
											d="M6 18L18 6M6 6l12 12"
										/>
									</svg>
								</button>
							</div>
						{/each}
					{/if}

					<!-- Add Reminder Button -->
					<button
						type="button"
						onclick={addReminder}
						class="flex w-full items-center justify-center gap-2 rounded-lg border border-dashed border-theme py-2 text-sm text-theme-muted transition-colors hover:border-accent7-500 hover:text-accent7-500"
					>
						<svg class="h-4 w-4" style="fill: none" stroke="currentColor" viewBox="0 0 24 24">
							<path
								stroke-linecap="round"
								stroke-linejoin="round"
								stroke-width="2"
								d="M12 4v16m8-8H4"
							/>
						</svg>
						Add Reminder
					</button>
				</div>
			{/if}
		</div>

		{#if error}
			<div class="rounded-lg bg-error-500/10 p-4">
				<p class="text-sm text-error-600 dark:text-error-400">{error}</p>
			</div>
		{/if}
	</div>

	<!-- Footer -->
	<div class="flex items-center justify-end gap-3 border-t border-theme bg-theme p-6">
		<button type="button" onclick={handleCancel} class="btn-ghost" disabled={submitting}>
			Cancel
		</button>
		<button
			type="submit"
			class="inline-flex items-center gap-2 rounded-lg bg-accent7-500 px-4 py-2 font-medium text-white transition-colors hover:bg-accent7-600 disabled:opacity-50"
			disabled={submitting || !summary.trim()}
		>
			{#if submitting}
				{event ? 'Updating...' : 'Creating...'}
			{:else}
				{event ? 'Update Event' : 'Create Event'}
			{/if}
		</button>
	</div>
</form>
