<!--
	SPDX-FileCopyrightText: © 2025 Hornwitser <code@hornwitser.no>
	SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
	<main>
		<h1>Edit</h1>
		<label>
			Crew Filter:
			<select
				v-model="crewFilter"
			>
				<option
					:value="undefined"
					:selected="crewFilter === undefined"
				>&lt;All Crew&gt;</option>
				<option
					v-for="user in [...usersStore.users.values()].filter(a => a.type === 'crew' || a.type === 'admin')"
					:key="user.id"
					:value="String(user.id)"
					:selected="crewFilter === String(user.id)"
				>{{ user.name }}</option>
			</select>
		</label>
		<Timetable :schedule :eventSlotFilter :shiftSlotFilter />
		<Tabs
			:tabs
			default="locations"
		>
			<template #locations>
				<TableScheduleLocations :edit="accountStore.canEditPublic" />
			</template>
			<template #events>
				<TableScheduleEvents :edit="true" />
			</template>
			<template #eventSlots>
				<label>
					Location Filter:
					<select
						v-model="locationFilter"
					>
						<option
							:value="undefined"
							:selected="locationFilter === undefined"
						>&lt;All locations&gt;</option>
						<option
							v-for="location in schedule.locations.values()"
							:key="location.id"
							:value="location.id"
							:disabled="location.deleted"
							:selected="locationFilter === location.id"
						>{{ location.name }}</option>
					</select>
				</label>
				<TableScheduleEventSlots :edit="true" :locationId="locationFilter" :eventSlotFilter />
			</template>
			<template #roles>
				<TableScheduleRoles :edit="true" />
			</template>
			<template #shifts>
				<TableScheduleShifts :edit="true" :roleId="roleFilter" />
			</template>
			<template #shiftSlots>
				<label>
					Role Filter:
					<select
						v-model="roleFilter"
					>
						<option
							:value="undefined"
							:selected="roleFilter === undefined"
						>&lt;All roles&gt;</option>
						<option
							v-for="role in schedule.roles.values()"
							:key="role.id"
							:value="role.id"
							:disabled="role.deleted"
							:selected="roleFilter === role.id"
						>{{ role.name }}</option>
					</select>
				</label>
				<TableScheduleShiftSlots :edit="true" :roleId="roleFilter" :shiftSlotFilter />
			</template>
		</Tabs>
		<section
			class="saveDialog"
			:class="{ visible: schedule.isModified() }"
		>
			<DiffSchedule
				v-if="reviewOpen"
				:schedule
			/>
			<hr v-if="reviewOpen">
			<section class="saveLine">
				<span>Changes are not saved yet.</span>
				<button
					type="button"
					v-if="reviewOpen"
					@click="saveChanges"
				>Save changes</button>
				<button
					type="button"
					class="review"
					@click="reviewOpen = !reviewOpen"
				>
					{{ reviewOpen ? "Close" : "Review" }}
				</button>
			</section>
		</section>
	</main>
</template>

<script lang="ts" setup>
definePageMeta({
	middleware: ["authenticated"],
	allowedAccountTypes: ["crew", "admin"],
});

const tabs = [
	{ id: "locations", title: "Locations" },
	{ id: "events", title: "Events" },
	{ id: "eventSlots", title: "Event Slots" },
	{ id: "roles", title: "Roles" },
	{ id: "shifts", title: "Shifts" },
	{ id: "shiftSlots", title: "Shifts Slots" },
];

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

const route = useRoute();
const crewFilter = computed({
	get: () => queryToString(route.query.crew),
	set: (value: string | undefined) => navigateTo({
		path: route.path,
		query: {
			...route.query,
			crew: value,
		},
	}),
});
const eventSlotFilter = computed(() => {
	if (crewFilter.value === undefined || !accountStore.valid) {
		return () => true;
	}
	const cid = parseInt(crewFilter.value);
	return (slot: ClientScheduleEventSlot) => slot.assigned.has(cid);
});
const shiftSlotFilter = computed(() => {
	if (crewFilter.value === undefined || !accountStore.valid) {
		return () => true;
	}
	const cid = parseInt(crewFilter.value);
	return (slot: ClientScheduleShiftSlot) => slot.assigned.has(cid);
});

const locationFilter = computed({
	get: () => queryToNumber(route.query.location),
	set: (value: number | undefined) => navigateTo({
		path: route.path,
		query: {
			...route.query,
			location: value !== undefined ? String(value) : undefined,
		},
	}),
});

const roleFilter = computed({
	get: () => queryToNumber(route.query.role),
	set: (value: string | undefined) => navigateTo({
		path: route.path,
		query: {
			...route.query,
			role: value,
		},
	}),
});

const reviewOpen = ref(false);

async function saveChanges() {
	try {
		await $fetch("/api/schedule", {
			method: "PATCH",
			body: schedule.value.toApi(true),
		});
	} catch (err: any) {
		console.error(err);
		alert(err?.data?.message ?? err.message);
	}
}
</script>

<style scoped>
.saveDialog {
	visibility: hidden;
	max-height: calc(100dvh - 2rem);
	overflow-y: auto;
	max-width: 30rem;
	padding: 0.2rem 0.4rem;
	border: 1px solid CanvasText;
	background-color: color-mix(in srgb, Canvas, CanvasText 10%);
	margin-block-start: 1rem;
	margin-block-end: 0.5rem;
	margin-inline: auto;
}
.saveDialog.visible {
	visibility: visible;
	position: sticky;
	bottom: 0.5rem;
}
.saveDialog hr {
	margin-block-start: 0.4rem;
	margin-block-end: 0.2rem;
}
.saveLine {
	display: flex;
	gap: 0.5rem;
}
.saveLine span {
	margin-inline-end: auto;
}
button.review {
	width: 4.5rem;
}
</style>
