<script lang="ts">
	import type { CalendarEvent } from "$lib/supabase/types";
	import { getMonthDays, isSameDay } from "$lib/api/calendar";

	type ViewType = "month" | "week" | "day";

	interface Props {
		events: CalendarEvent[];
		onDateClick?: (date: Date) => void;
		onEventClick?: (event: CalendarEvent) => void;
		initialView?: ViewType;
	}

	let {
		events,
		onDateClick,
		onEventClick,
		initialView = "month",
	}: Props = $props();

	let currentDate = $state(new Date());
	let currentView = $state<ViewType>(initialView);
	const today = new Date();

	const weekDayHeaders = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

	const days = $derived(
		getMonthDays(currentDate.getFullYear(), currentDate.getMonth()),
	);

	// Group days into weeks (rows of 7)
	const weeks = $derived.by(() => {
		const result: Date[][] = [];
		for (let i = 0; i < days.length; i += 7) {
			result.push(days.slice(i, i + 7));
		}
		return result;
	});

	function getEventsForDay(date: Date): CalendarEvent[] {
		return events.filter((event) => {
			const eventStart = new Date(event.start_time);
			return isSameDay(eventStart, date);
		});
	}

	function isCurrentMonth(date: Date): boolean {
		return date.getMonth() === currentDate.getMonth();
	}

	const monthYear = $derived(
		currentDate.toLocaleDateString("en-US", {
			month: "long",
			year: "numeric",
		}),
	);

	// Get week days for week view (Mon-Sun)
	function getWeekDays(date: Date): Date[] {
		const startOfWeek = new Date(date);
		const dayOfWeek = startOfWeek.getDay();
		const mondayOffset = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
		startOfWeek.setDate(date.getDate() + mondayOffset);
		return Array.from({ length: 7 }, (_, i) => {
			const d = new Date(startOfWeek);
			d.setDate(startOfWeek.getDate() + i);
			return d;
		});
	}

	const weekDates = $derived(getWeekDays(currentDate));

	function prev() {
		if (currentView === "month") {
			currentDate = new Date(
				currentDate.getFullYear(),
				currentDate.getMonth() - 1,
				1,
			);
		} else if (currentView === "week") {
			currentDate = new Date(
				currentDate.getTime() - 7 * 24 * 60 * 60 * 1000,
			);
		} else {
			currentDate = new Date(currentDate.getTime() - 24 * 60 * 60 * 1000);
		}
	}

	function next() {
		if (currentView === "month") {
			currentDate = new Date(
				currentDate.getFullYear(),
				currentDate.getMonth() + 1,
				1,
			);
		} else if (currentView === "week") {
			currentDate = new Date(
				currentDate.getTime() + 7 * 24 * 60 * 60 * 1000,
			);
		} else {
			currentDate = new Date(currentDate.getTime() + 24 * 60 * 60 * 1000);
		}
	}

	function goToToday() {
		currentDate = new Date();
	}

	const headerTitle = $derived.by(() => {
		if (currentView === "day") {
			return currentDate.toLocaleDateString("en-US", {
				weekday: "long",
				month: "long",
				day: "numeric",
				year: "numeric",
			});
		} else if (currentView === "week") {
			const start = weekDates[0];
			const end = weekDates[6];
			return `${start.toLocaleDateString("en-US", { month: "short", day: "numeric" })} - ${end.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })}`;
		}
		return monthYear;
	});
</script>

<div class="flex flex-col h-full gap-2">
	<!-- Navigation bar -->
	<div class="flex items-center justify-between px-2">
		<div class="flex items-center gap-2">
			<button
				class="p-1 text-light/60 hover:text-light hover:bg-dark rounded-full transition-colors"
				onclick={prev}
				aria-label="Previous"
			>
				<span
					class="material-symbols-rounded"
					style="font-size: 24px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;"
					>chevron_left</span
				>
			</button>
			<span
				class="font-heading text-h4 text-white min-w-[200px] text-center"
				>{headerTitle}</span
			>
			<button
				class="p-1 text-light/60 hover:text-light hover:bg-dark rounded-full transition-colors"
				onclick={next}
				aria-label="Next"
			>
				<span
					class="material-symbols-rounded"
					style="font-size: 24px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;"
					>chevron_right</span
				>
			</button>
			<button
				class="px-3 py-1 text-body-md font-body text-light/60 hover:text-white hover:bg-dark rounded-[32px] transition-colors ml-2"
				onclick={goToToday}
			>
				Today
			</button>
		</div>
		<div class="flex bg-dark rounded-[32px] p-0.5">
			<button
				class="px-3 py-1 text-body-md font-body rounded-[32px] transition-colors {currentView ===
				'day'
					? 'bg-primary text-night'
					: 'text-light/60 hover:text-light'}"
				onclick={() => (currentView = "day")}>Day</button
			>
			<button
				class="px-3 py-1 text-body-md font-body rounded-[32px] transition-colors {currentView ===
				'week'
					? 'bg-primary text-night'
					: 'text-light/60 hover:text-light'}"
				onclick={() => (currentView = "week")}>Week</button
			>
			<button
				class="px-3 py-1 text-body-md font-body rounded-[32px] transition-colors {currentView ===
				'month'
					? 'bg-primary text-night'
					: 'text-light/60 hover:text-light'}"
				onclick={() => (currentView = "month")}>Month</button
			>
		</div>
	</div>

	<!-- Month View -->
	{#if currentView === "month"}
		<div
			class="flex flex-col flex-1 gap-2 min-h-0 bg-background rounded-xl p-2"
		>
			<!-- Day Headers -->
			<div class="grid grid-cols-7 gap-2">
				{#each weekDayHeaders as day}
					<div class="flex items-center justify-center py-2 px-2">
						<span
							class="font-heading text-h4 text-white text-center"
							>{day}</span
						>
					</div>
				{/each}
			</div>

			<!-- Calendar Grid -->
			<div
				class="flex-1 flex flex-col gap-2 min-h-0 rounded-lg overflow-hidden"
			>
				{#each weeks as week}
					<div class="grid grid-cols-7 gap-2 flex-1">
						{#each week as day}
							{@const dayEvents = getEventsForDay(day)}
							{@const isToday = isSameDay(day, today)}
							{@const inMonth = isCurrentMonth(day)}
							<div
								class="bg-night rounded-none flex flex-col items-start px-2 py-2.5 overflow-hidden transition-colors hover:bg-dark/50 min-h-0 cursor-pointer
									{!inMonth ? 'opacity-50' : ''}"
								onclick={() => onDateClick?.(day)}
							>
								<span
									class="font-body text-body text-white {isToday
										? 'text-primary font-bold'
										: ''}"
								>
									{day.getDate()}
								</span>
								{#each dayEvents.slice(0, 2) as event}
									<button
										class="w-full mt-1 px-2 py-0.5 rounded-[4px] text-body-sm font-bold font-body text-night truncate text-left"
										style="background-color: {event.color ??
											'#00A3E0'}"
										onclick={(e) => {
											e.stopPropagation();
											onEventClick?.(event);
										}}
									>
										{event.title}
									</button>
								{/each}
								{#if dayEvents.length > 2}
									<span
										class="text-body-sm text-light/40 mt-0.5"
										>+{dayEvents.length - 2} more</span
									>
								{/if}
							</div>
						{/each}
					</div>
				{/each}
			</div>
		</div>
	{/if}

	<!-- Week View -->
	{#if currentView === "week"}
		<div
			class="flex flex-col flex-1 gap-2 min-h-0 bg-background rounded-xl p-2"
		>
			<div
				class="grid grid-cols-7 gap-2 flex-1 rounded-lg overflow-hidden"
			>
				{#each weekDates as day}
					{@const dayEvents = getEventsForDay(day)}
					{@const isToday = isSameDay(day, today)}
					<div class="flex flex-col overflow-hidden">
						<div class="px-2 py-2 text-center">
							<div
								class="font-heading text-h4 {isToday
									? 'text-primary'
									: 'text-white'}"
							>
								{weekDayHeaders[(day.getDay() + 6) % 7]}
							</div>
							<div
								class="font-body text-body-md {isToday
									? 'text-primary'
									: 'text-light/60'}"
							>
								{day.getDate()}
							</div>
						</div>
						<div
							class="bg-night flex-1 px-2 pb-2 space-y-1 overflow-y-auto"
						>
							{#each dayEvents as event}
								<button
									class="w-full px-2 py-1.5 rounded-[4px] text-body-sm font-bold font-body text-night truncate text-left"
									style="background-color: {event.color ??
										'#00A3E0'}"
									onclick={() => onEventClick?.(event)}
								>
									{event.title}
								</button>
							{/each}
						</div>
					</div>
				{/each}
			</div>
		</div>
	{/if}

	<!-- Day View -->
	{#if currentView === "day"}
		{@const dayEvents = getEventsForDay(currentDate)}
		<div class="flex-1 bg-night px-4 py-5 min-h-0 overflow-auto">
			{#if dayEvents.length === 0}
				<div class="text-center text-light/40 py-12">
					<p class="font-body text-body">No events for this day</p>
				</div>
			{:else}
				<div class="space-y-2">
					{#each dayEvents as event}
						<button
							class="w-full text-left p-3 rounded-[8px] transition-colors hover:opacity-80"
							style="background-color: {event.color ??
								'#00A3E0'}20; border-left: 3px solid {event.color ??
								'#00A3E0'}"
							onclick={() => onEventClick?.(event)}
						>
							<div class="font-heading text-h5 text-white">
								{event.title}
							</div>
							<div
								class="font-body text-body-md text-light/60 mt-1"
							>
								{new Date(event.start_time).toLocaleTimeString(
									"en-US",
									{ hour: "numeric", minute: "2-digit" },
								)}
								- {new Date(event.end_time).toLocaleTimeString(
									"en-US",
									{ hour: "numeric", minute: "2-digit" },
								)}
							</div>
							{#if event.description}
								<div
									class="font-body text-body-md text-light/50 mt-2"
								>
									{event.description}
								</div>
							{/if}
						</button>
					{/each}
				</div>
			{/if}
		</div>
	{/if}
</div>
