<script lang="ts">
	import { SvelteSet } from 'svelte/reactivity';
	import { client } from '$lib/graphql/client';
	import {
		CREATE_CALENDAR_EVENT,
		type CreateCalendarEventInput,
		type CreateCalendarEventResult,
		type AttendeeInput,
		type EventRemindersInput,
		type EventReminderInput
	} from '$lib/graphql/mutations/calendar';
	import { EVENT_COLORS } from '$lib/graphql/queries/calendar';

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

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

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

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

	// Get initial values from props (computed once when component mounts)
	function getInitialValue<T>(key: keyof NonNullable<Props['initialValues']>, fallback: T): T {
		return (initialValues?.[key] as T) ?? fallback;
	}

	const defaultDate = new Date().toISOString().split('T')[0];

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

	// Form fields - initialized from props.initialValues
	let summary = $state(getInitialValue('summary', ''));
	let description = $state(getInitialValue('description', '') ?? '');
	let location = $state(getInitialValue('location', '') ?? '');
	let isAllDay = $state(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 Date(dateStr + 'T12:00:00'); // noon to avoid DST issues
		date.setDate(date.getDate() + 1);
		return date.toISOString().split('T')[0];
	}

	// Date/time fields - initialized from props.initialValues
	let startDate = $state(getInitialValue('date', defaultDate));
	let startTime = $state('09:00');
	let endDate = $state(getInitialValue('date', defaultDate));
	let endTime = $state('10:00');

	// 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>();

	// Reminder settings
	let useDefaultReminders = $state(true);
	let customReminders = $state<EventReminderInput[]>([]);

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

	// Active team members with emails, excluding admins (it's the admin's calendar)
	let availableAttendees = $derived(
		teamProfiles.filter(
			(p: TeamProfile): p is TeamProfile & { email: string } =>
				p.status === 'ACTIVE' && !!p.email && p.role !== 'ADMIN'
		)
	);

	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;
		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 {
		const localDateTime = new Date(`${date}T${time}:00`);
		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: AttendeeInput[] = Array.from(selectedAttendeeEmails).map((email) => {
				const profile = teamProfiles.find((p: TeamProfile) => p.email === email);
				return {
					email,
					displayName: profile?.fullName
				};
			});

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

			// Build event input
			const input: CreateCalendarEventInput = {
				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
			};

			const result = await client.mutate<CreateCalendarEventResult>({
				mutation: CREATE_CALENDAR_EVENT,
				variables: { input }
			});

			if (result.data?.createCalendarEvent?.id) {
				onSuccess(result.data.createCalendarEvent.id);
			} else {
				throw new Error('Failed to create event');
			}
		} catch (err) {
			error = err instanceof Error ? err.message : 'Failed to save event';
		} finally {
			submitting = false;
		}
	}
</script>

<form onsubmit={handleSubmit} class="space-y-6">
	<!-- Event Title -->
	<label class="block">
		<span class="text-sm font-medium text-theme"
			>Event Title <span class="text-error-500">*</span></span
		>
		<input
			type="text"
			bind:value={summary}
			placeholder="e.g., Team Meeting"
			class="placeholder-theme-muted mt-1 block 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 focus:outline-none"
			required
			disabled={submitting}
		/>
	</label>

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

	<!-- 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"
				bind:checked={isAfterMidnight}
				class="h-4 w-4 rounded border-amber-400 text-amber-500 focus:ring-amber-500"
				disabled={submitting}
			/>
			<span 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}
			</span>
		</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 focus:outline-none"
				required
				disabled={submitting}
			/>
			{#if !isAllDay}
				<input
					type="time"
					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 focus:outline-none"
					required
					disabled={submitting}
				/>
			{/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 focus:outline-none"
				required
				disabled={submitting}
			/>
			{#if !isAllDay}
				<input
					type="time"
					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 focus:outline-none"
					required
					disabled={submitting}
				/>
			{/if}
		</div>
	</div>

	<!-- Location -->
	<label class="block">
		<span class="text-sm font-medium text-theme">Location (optional)</span>
		<input
			type="text"
			bind:value={location}
			placeholder="e.g., Conference Room A"
			class="placeholder-theme-muted mt-1 block 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 focus:outline-none"
			disabled={submitting}
		/>
	</label>

	<!-- Description -->
	<label class="block">
		<span class="text-sm font-medium text-theme">Description (optional)</span>
		<textarea
			bind:value={description}
			rows="3"
			placeholder="Add event details..."
			class="placeholder-theme-muted mt-1 block 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 focus:outline-none"
			disabled={submitting}
		></textarea>
	</label>

	<!-- 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'
					: 'hover:border-theme-secondary border-theme'}"
				aria-label="No color"
				title="No color"
				disabled={submitting}
			>
				<svg class="h-4 w-4 text-theme-muted" 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}
					disabled={submitting}
				></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'}"
						disabled={submitting}
					>
						<span
							class="flex h-6 w-6 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" 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 -->
		<label class="mb-3 flex items-center gap-3">
			<input
				type="checkbox"
				bind:checked={useDefaultReminders}
				class="h-4 w-4 rounded border-theme text-accent7-500 focus:ring-accent7-500"
				disabled={submitting}
			/>
			<span class="text-sm text-theme"> Use default reminders (30 minutes before via popup) </span>
		</label>

		<!-- 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 focus:outline-none"
								disabled={submitting}
							>
								<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 focus:outline-none"
								disabled={submitting}
							>
								{#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 shrink-0 items-center justify-center rounded-lg text-theme-muted transition-colors hover:bg-error-500/10 hover:text-error-500"
								disabled={submitting}
							>
								<svg class="h-5 w-5" 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"
					disabled={submitting}
				>
					<svg class="h-4 w-4" 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}

	<!-- Footer -->
	<div class="flex items-center justify-end gap-3 border-t border-theme pt-5">
		<button type="button" onclick={onCancel} class="btn-outline" disabled={submitting}>
			Cancel
		</button>
		<button type="submit" class="btn-accent7" disabled={submitting || !summary.trim()}>
			{submitting ? 'Creating...' : 'Create Event'}
		</button>
	</div>
</form>
