<script lang="ts">
	import type { AppointmentDateTimes } from '$lib/dbdata';
	import { isSameDate } from '$lib/funcs';
	import { t } from '$lib/translations';
	import moment, { type Moment } from 'moment';
	import { onMount } from 'svelte';

	let currentDate: Date = new Date();
	let days: Array<{ day: number; isActive: boolean; isAvailable: boolean }> = [];

	let currentMonth: string = '';
	export let selectedDate: Date;
	export let appointmentDateTimes: AppointmentDateTimes[];

	$: {
		if (appointmentDateTimes.length > 0) {
			renderCalendar();
		}
	}

	function isDayAvailable(year: number, month: number, day: number) {
		const dateStr = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`;
		const testDate: Date = moment(dateStr).toDate();

		return appointmentDateTimes.some((date) => isSameDate(testDate, date.date));
	}

	/**
	 * Updates the calendar display by calculating the days of the current month.
	 */
	const renderCalendar = (): void => {
		const mDate: Moment = moment(currentDate).locale("de");
		const year: number = currentDate.getFullYear();
		const month: number = mDate.month();

		let locale: string = "en-US";

		if (navigator.language.includes("de")) locale = "de";

		// make sure to properly translate this
		currentMonth = currentDate.toLocaleDateString(locale, { month: 'long', year: 'numeric' });

		const firstDayOfMonth: Date = new Date(year, month, 1);
		const lastDayOfMonth: Date = new Date(year, month + 1, 0);
		let firstDayIndex: number = firstDayOfMonth.getDay() - 1;
		if (firstDayIndex === -1) firstDayIndex = 6;
		const daysInMonth: number = lastDayOfMonth.getDate();

		// Reset days array
		days = [];

		// Add empty cells for days before the first of the month
		for (let i = 0; i < firstDayIndex; i++) {
			days.push({ day: 0, isActive: false, isAvailable: false });
		}

		// Add days of the month
		for (let day = 1; day <= daysInMonth; day++) {
			days.push({ day, isActive: false, isAvailable: isDayAvailable(year, month + 1, day) }); // Example: Make day 20 active
		}
	};

	/**
	 * Changes the current month by a given offset and re-renders the calendar.
	 * @param offset - The number of months to move forward or backward.
	 */
	const changeMonth = (offset: number): void => {
		//currentDate.setMonth(currentDate.getMonth() + offset);
		if (offset === -1) {
			currentDate = moment(currentDate).subtract(1, 'month').toDate();
		} else {
			currentDate = moment(currentDate).add(1, 'month').toDate();
		}

		renderCalendar();
	};

	onMount(() => {
		currentDate = new Date();
		renderCalendar();
	});

	/**
	 * Handles the selection of a day in the calendar.
	 * @param selectedDay - The day number that was clicked.
	 */
	const selectDay = (selectedDay: number): void => {
		days = days.map((d) => ({ ...d, isActive: d.day === selectedDay }));
		const selectedDateValue = new Date(
			currentDate.getFullYear(),
			currentDate.getMonth(),
			selectedDay
		);
		selectedDate = selectedDateValue;
	};
</script>

<div class="date-picker border center">
	<div class="date-picker-header">
		<button class="button square secondary medium" on:click={() => changeMonth(-1)}>&lt;</button>
		<h4 id="currentMonth" class="small wrap center-align">{currentMonth}</h4>
		<button class="button square secondary medium" on:click={() => changeMonth(1)}>&gt;</button>
	</div>
	<div class="date-picker-grid">
		<!-- Days of the week -->
		<div class="date-picker-day">{$t("common.monday-short")}</div>
		<div class="date-picker-day">{$t("common.tuesday-short")}</div>
		<div class="date-picker-day">{$t("common.wednesday-short")}</div>
		<div class="date-picker-day">{$t("common.thursday-short")}</div>
		<div class="date-picker-day">{$t("common.friday-short")}</div>
		<div class="date-picker-day">{$t("common.saturday-short")}</div>
		<div class="date-picker-day">{$t("common.sunday-short")}</div>

		<!-- Render days -->
		{#each days as { day, isActive, isAvailable }, index}
			{#if isAvailable}
				<!-- svelte-ignore a11y_click_events_have_key_events -->
				<!-- svelte-ignore a11y_no_static_element_interactions -->
				<div
					class="date-picker-cell {!isActive ? 'secondary' : ''} {isActive ? 'active' : ''} {day ===
					0
						? 'empty'
						: ''}"
					on:click={() => day && selectDay(day)}
				>
					{day || ''}
				</div>
			{:else}
				<!-- svelte-ignore a11y_click_events_have_key_events -->
				<!-- svelte-ignore a11y_no_static_element_interactions -->
				<div class="date-picker-cell">
					{day || ''}
				</div>
			{/if}
		{/each}
	</div>
</div>

<style>
	.date-picker {
		border: 1px solid var(--border-color);
		border-radius: var(--border-radius);
		padding: 1rem;
		max-width: 600px;
		background: var(--background);
		box-shadow: var(--shadow);
	}
	.date-picker-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-bottom: 1rem;
	}
	.date-picker-grid {
		display: grid;
		grid-template-columns: repeat(7, 1fr);
		gap: 0.5rem;
		text-align: center;
	}
	.date-picker-day {
		font-weight: bold;
		color: var(--secondary);
	}
	.date-picker-cell {
		padding: 0.5rem;
		border-radius: var(--border-radius);
		cursor: pointer;
		user-select: none;
	}
	.date-picker-cell:hover {
		background-color: var(--hover-background);
	}
	.date-picker-cell.active {
		background-color: var(--primary);
		color: var(--background);
	}
	.empty {
		pointer-events: none;
		visibility: hidden;
	}
</style>
