<!--
	SPDX-FileCopyrightText: © 2025 Hornwitser <code@hornwitser.no>
	SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
	<main>
		<h1>Schedule</h1>
		<p>
			Study carefully, we only hold these events once a year.
		</p>
		<p v-if="!accountStore.valid">
			<NuxtLink to="/login">Login</NuxtLink> or <NuxtLink to="/login#create-account">Create an account</NuxtLink>
			to get notified about updates to the schedule.
		</p>
		<p v-else>
			Check out your <NuxtLink to="/account/settings">Account Setting</NuxtLink> to set up notifications for changes to schedule.
		</p>
		<h2>Schedule</h2>
		<label v-if="accountStore.valid">
			Filter:
			<select
				v-model="filter"
			>
				<option
					:value="undefined"
					:selected="filter === undefined"
				>&lt;All events&gt;</option>
				<option
					value="my-schedule"
					:selected='filter === "my-schedule"'
				>My Schedule</option>
				<option
					v-if="accountStore.isCrew"
					value="assigned"
					:selected='filter === "assigned"'
				>Assigned to Me</option>
				<optgroup v-if="accountStore.isCrew" label="Crew">
					<option
						v-for="user in [...usersStore.users.values()].filter(a => a.type === 'crew' || a.type === 'admin')"
						:key="user.id"
						:value="`crew-${user.id}`"
						:selected="filter === `crew-${user.id}`"
					>{{ user.name }}</option>
				</optgroup>
			</select>
		</label>
		<Timetable :schedule :eventSlotFilter :shiftSlotFilter />
		<h2>Events</h2>
		<label>
			Hide past events
			<input type="checkbox" v-model="hidePastEvents">
		</label>
		<CardEventSlot
			v-for="eventSlot in eventSlots"
			:key="eventSlot.slot.id"
			:event="eventSlot.event"
			:slot="eventSlot.slot"
		/>
		<template v-if="accountStore.isCrew">
			<h2>Shifts</h2>
			<CardShift
				v-for="shift in [...schedule.shifts.values()].filter(s => !s.deleted && [...s.slots.values()].some(shiftSlotFilter))"
				:key="shift.id"
				:shift
			/>
		</template>
		<h2>Locations</h2>
		<ul>
			<li v-for="location in schedule.locations.values()" :key="location.id">
				<h3>{{ location.name }}</h3>
				{{ location.description ?? "No description provided" }}
			</li>
		</ul>
	</main>
</template>

<script setup lang="ts">
useHead({
	title: "Schedule",
});

const accountStore = useAccountStore();
const usersStore = useUsersStore();
await usersStore.fetch();
const schedule = await useSchedule();

const route = useRoute();
const filter = computed({
	get: () => queryToString(route.query.filter),
	set: (value: string | undefined) => navigateTo({
		path: route.path,
		query: {
			...route.query,
			filter: value,
		},
	}),
});

const hidePastEvents = computed({
	get: () => !queryToBoolean(route.query.showPast),
	set: (value: boolean) => navigateTo({
		path: route.path,
		query: {
			...route.query,
			showPast: value ? undefined : null,
		},
	}),
});

const eventSlotFilter = computed(() => {
	if (filter.value === undefined || !accountStore.valid || schedule.value.deleted) {
		return () => true;
	}
	const aid = accountStore.id;
	if (filter.value === "my-schedule") {
		const slotIds = new Set(accountStore.interestedEventSlotIds);
		for (const event of schedule.value.events.values()) {
			if (!event.deleted && accountStore.interestedEventIds.has(event.id)) {
				for (const slot of event.slots.values()) {
					slotIds.add(slot.id);
				}
			}
		}
		return (slot: ClientScheduleEventSlot) => slotIds.has(slot.id) || slot.assigned.has(aid!) || false;
	}
	if (filter.value === "assigned") {
		return (slot: ClientScheduleEventSlot) => slot.assigned.has(aid!) || false;
	}
	if (filter.value.startsWith("crew-")) {
		const cid = parseInt(filter.value.slice(5));
		return (slot: ClientScheduleEventSlot) => slot.assigned.has(cid) || false;
	}
	return () => false;
});
const shiftSlotFilter = computed(() => {
	if (filter.value === undefined || !accountStore.valid) {
		return () => true;
	}
	if (filter.value === "my-schedule" || filter.value === "assigned") {
		const aid = accountStore.id;
		return (slot: ClientScheduleShiftSlot) => slot.assigned.has(aid!) || false;
	}
	if (filter.value.startsWith("crew-")) {
		const cid = parseInt(filter.value.slice(5));
		return (slot: ClientScheduleShiftSlot) => slot.assigned.has(cid) || false;
	}
	return () => false;
});

const eventSlots = computed(() => {
	let slots = [...schedule.value.eventSlots.values()].filter(slot => !slot.deleted && eventSlotFilter.value(slot));
	if (hidePastEvents.value) {
		const nowMs = Date.now();
		slots = slots.filter(slot => slot.end.toMillis() >= nowMs);
	}
	slots.sort((a, b) => a.start.toMillis() - b.start.toMillis() || a.end.toMillis() - b.end.toMillis());
	return slots.map(slot => ({ slot, event: schedule.value.events.get(slot.eventId!) }));
});

</script>
