<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 weekDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

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

	function prevMonth() {
		currentDate = new Date(
			currentDate.getFullYear(),
			currentDate.getMonth() - 1,
			1,
		);
	}

	function nextMonth() {
		currentDate = new Date(
			currentDate.getFullYear(),
			currentDate.getMonth() + 1,
			1,
		);
	}

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

	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
	function getWeekDays(date: Date): Date[] {
		const startOfWeek = new Date(date);
		startOfWeek.setDate(date.getDate() - date.getDay());
		return Array.from({ length: 7 }, (_, i) => {
			const d = new Date(startOfWeek);
			d.setDate(startOfWeek.getDate() + i);
			return d;
		});
	}

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

	// Navigation functions for different views
	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);
		}
	}

	const headerTitle = $derived(() => {
		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="bg-surface rounded-xl p-4">
	<div class="flex items-center justify-between mb-4">
		<h2 class="text-xl font-semibold text-light">{headerTitle()}</h2>
		<div class="flex items-center gap-2">
			<!-- View Switcher -->
			<div class="flex bg-dark rounded-lg p-0.5">
				<button
					class="px-3 py-1 text-sm rounded-md transition-colors {currentView ===
					'day'
						? 'bg-primary text-white'
						: 'text-light/60 hover:text-light'}"
					onclick={() => (currentView = "day")}
				>
					Day
				</button>
				<button
					class="px-3 py-1 text-sm rounded-md transition-colors {currentView ===
					'week'
						? 'bg-primary text-white'
						: 'text-light/60 hover:text-light'}"
					onclick={() => (currentView = "week")}
				>
					Week
				</button>
				<button
					class="px-3 py-1 text-sm rounded-md transition-colors {currentView ===
					'month'
						? 'bg-primary text-white'
						: 'text-light/60 hover:text-light'}"
					onclick={() => (currentView = "month")}
				>
					Month
				</button>
			</div>
			<button
				class="px-3 py-1.5 text-sm text-light/60 hover:text-light hover:bg-light/10 rounded-lg transition-colors"
				onclick={goToToday}
			>
				Today
			</button>
			<button
				class="p-2 text-light/60 hover:text-light hover:bg-light/10 rounded-lg transition-colors"
				onclick={prev}
				aria-label="Previous"
			>
				<svg
					class="w-5 h-5"
					viewBox="0 0 24 24"
					fill="none"
					stroke="currentColor"
					stroke-width="2"
				>
					<path d="m15 18-6-6 6-6" />
				</svg>
			</button>
			<button
				class="p-2 text-light/60 hover:text-light hover:bg-light/10 rounded-lg transition-colors"
				onclick={next}
				aria-label="Next"
			>
				<svg
					class="w-5 h-5"
					viewBox="0 0 24 24"
					fill="none"
					stroke="currentColor"
					stroke-width="2"
				>
					<path d="m9 18 6-6-6-6" />
				</svg>
			</button>
		</div>
	</div>

	<!-- Month View -->
	{#if currentView === "month"}
		<div
			class="grid grid-cols-7 gap-px bg-light/10 rounded-lg overflow-hidden"
		>
			{#each weekDays as day}
				<div
					class="bg-dark px-2 py-2 text-center text-sm font-medium text-light/50"
				>
					{day}
				</div>
			{/each}

			{#each days as day}
				{@const dayEvents = getEventsForDay(day)}
				{@const isToday = isSameDay(day, today)}
				{@const inMonth = isCurrentMonth(day)}
				<button
					class="bg-dark min-h-[80px] p-1 text-left transition-colors hover:bg-light/5"
					class:opacity-40={!inMonth}
					onclick={() => onDateClick?.(day)}
				>
					<div class="flex items-center justify-center w-7 h-7 mb-1">
						<span
							class="text-sm {isToday
								? 'bg-primary text-white rounded-full w-7 h-7 flex items-center justify-center'
								: 'text-light/80'}"
						>
							{day.getDate()}
						</span>
					</div>
					<div class="space-y-0.5">
						{#each dayEvents.slice(0, 3) as event}
							<button
								class="w-full text-xs px-1 py-0.5 rounded truncate text-left"
								style="background-color: {event.color ??
									'#6366f1'}20; color: {event.color ??
									'#6366f1'}"
								onclick={(e) => {
									e.stopPropagation();
									onEventClick?.(event);
								}}
							>
								{event.title}
							</button>
						{/each}
						{#if dayEvents.length > 3}
							<p class="text-xs text-light/40 px-1">
								+{dayEvents.length - 3} more
							</p>
						{/if}
					</div>
				</button>
			{/each}
		</div>
	{/if}

	<!-- Week View -->
	{#if currentView === "week"}
		<div
			class="grid grid-cols-7 gap-px bg-light/10 rounded-lg overflow-hidden"
		>
			{#each weekDates as day}
				{@const dayEvents = getEventsForDay(day)}
				{@const isToday = isSameDay(day, today)}
				<div class="bg-dark">
					<div class="px-2 py-2 text-center border-b border-light/10">
						<div class="text-xs text-light/50">
							{weekDays[day.getDay()]}
						</div>
						<div
							class="text-lg font-medium {isToday
								? 'text-primary'
								: 'text-light'}"
						>
							{day.getDate()}
						</div>
					</div>
					<div class="min-h-[300px] p-1 space-y-1">
						{#each dayEvents as event}
							<button
								class="w-full text-xs px-2 py-1.5 rounded text-left"
								style="background-color: {event.color ??
									'#6366f1'}20; color: {event.color ??
									'#6366f1'}"
								onclick={() => onEventClick?.(event)}
							>
								<div class="font-medium truncate">
									{event.title}
								</div>
								<div class="text-[10px] opacity-70">
									{new Date(
										event.start_time,
									).toLocaleTimeString("en-US", {
										hour: "numeric",
										minute: "2-digit",
									})}
								</div>
							</button>
						{/each}
					</div>
				</div>
			{/each}
		</div>
	{/if}

	<!-- Day View -->
	{#if currentView === "day"}
		{@const dayEvents = getEventsForDay(currentDate)}
		<div class="bg-dark rounded-lg p-4 min-h-[400px]">
			{#if dayEvents.length === 0}
				<div class="text-center text-light/40 py-12">
					<p>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-lg transition-colors hover:opacity-80"
							style="background-color: {event.color ??
								'#6366f1'}20; border-left: 3px solid {event.color ??
								'#6366f1'}"
							onclick={() => onEventClick?.(event)}
						>
							<div class="font-medium text-light">
								{event.title}
							</div>
							<div class="text-sm 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="text-sm text-light/50 mt-2">
									{event.description}
								</div>
							{/if}
						</button>
					{/each}
				</div>
			{/if}
		</div>
	{/if}
</div>
