<script lang="ts">
	import type { PageData } from './$types';
	import Badges from '$lib/components/Input/Badges.svelte';
	import { Check, NoSymbol, PencilSquare, Trash, UserPlus } from 'svelte-heros-v2';
	import Input from '$lib/components/Input/Input.svelte';
	import { Permissions } from '$lib/permissions';
	import { env } from '$env/dynamic/public';
	import ErrorToast from '$lib/components/Toast/ErrorToast.svelte';
	import { buttonTriggeredRequest } from '$lib/components/utils';
	import { goto } from '$app/navigation';
	// eslint-disable-next-line @typescript-eslint/no-unused-vars
	import { adminCount } from '$lib/stores';

	let allPermissionBadges = {
		'Admin Read': Permissions.AdminRead,
		'Admin Write': Permissions.AdminWrite,
		'User Read': Permissions.UserRead,
		'User Write': Permissions.UserWrite,
		'Report Read': Permissions.ReportRead,
		'Report Write': Permissions.ReportWrite,
		'Settings Read': Permissions.SettingsRead,
		'Settings Write': Permissions.SettingsWrite
	};

	let newAdminUsername: string;
	let newAdminPassword: string;
	let newAdminPermissions: number[];

	async function addAdmin(username: string, password: string, permissions: Permissions) {
		const response = await fetch(`${env.PUBLIC_BASE_PATH}/admin/admin`, {
			method: 'POST',
			body: JSON.stringify({
				username: username,
				password: password,
				permissions: permissions.value
			})
		});
		if (response.ok) {
			let res = await response.json();
			$adminCount += 1;
			res.permissions = new Permissions(res.permissions).asArray();
			data.admins.push(res);
			data.admins = data.admins;
		} else {
			throw new Error();
		}
	}

	async function updateAdmin(
		id: number,
		username: string | null,
		password: string | null,
		updatePermissions: Permissions | null
	) {
		const response = await fetch(`${env.PUBLIC_BASE_PATH}/admin/admin`, {
			method: 'PATCH',
			body: JSON.stringify({
				id: id,
				username: username,
				password: password,
				permissions: updatePermissions?.value
			})
		});
		if (response.ok) {
			if (id === data.id && updatePermissions) {
				permissions = updatePermissions;
			}
		} else {
			throw new Error();
		}
	}

	async function deleteAdmin(id: number) {
		const response = await fetch(`${env.PUBLIC_BASE_PATH}/admin/admin`, {
			method: 'DELETE',
			body: JSON.stringify({
				id: id
			})
		});
		if (response.ok) {
			if (id === data.id) {
				await goto(`${env.PUBLIC_BASE_PATH}/`);
			} else {
				$adminCount -= 1;
				data.admins.splice(
					data.admins.findIndex((v) => v.id == id),
					1
				);
				data.admins = data.admins;
			}
		} else {
			throw new Error();
		}
	}

	let errorMessage = '';

	export let data: PageData;
	let permissions = new Permissions(data.permissions);
</script>

<table class="table table-zebra w-full">
	<thead>
		<tr>
			<th />
			<th>Benutzername</th>
			<th>Passwort</th>
			<th>Berechtigungen</th>
			<th />
		</tr>
	</thead>
	<tbody>
		{#each data.admins as admin, i}
			<tr>
				<td>{i + 1}</td>
				<td
					><Input
						type="text"
						bind:value={admin.username}
						disabled={!permissions.adminWrite() || !admin.edit}
						size="sm"
					/></td
				>
				<td
					><Input
						type="password"
						bind:value={admin.password}
						placeholder="Neues Passwort..."
						disabled={!permissions.adminWrite() || !admin.edit}
						size="sm"
					/></td
				>
				<td
					><Badges
						bind:value={admin.permissions}
						available={allPermissionBadges}
						disabled={!permissions.adminWrite() || !admin.edit}
					/></td
				>
				<td>
					<div>
						{#if admin.edit}
							<span class="w-min" class:cursor-not-allowed={!permissions.adminWrite()}>
								<button
									class="btn btn-sm btn-square"
									disabled={!permissions.adminWrite()}
									on:click={async (e) => {
										await buttonTriggeredRequest(
											e,
											updateAdmin(
												admin.id,
												admin.username,
												admin.password,
												new Permissions(admin.permissions)
											)
										);
										admin.password = '';
										admin.edit = false;
									}}
								>
									<Check size="18" />
								</button>
							</span>
							<span class="w-min" class:cursor-not-allowed={!permissions.adminWrite()}>
								<button
									class="btn btn-sm btn-square"
									disabled={!permissions.adminWrite()}
									on:click={() => {
										admin.edit = false;
										admin = admin.before;
									}}
								>
									<NoSymbol size="18" />
								</button>
							</span>
						{:else}
							<span class="w-min" class:cursor-not-allowed={!permissions.adminWrite()}>
								<button
									class="btn btn-sm btn-square"
									disabled={!permissions.adminWrite()}
									on:click={() => {
										admin.edit = true;
										admin.before = structuredClone(admin);
									}}
								>
									<PencilSquare size="18" />
								</button>
							</span>
							<span class="w-min" class:cursor-not-allowed={!permissions.adminWrite()}>
								<button
									class="btn btn-sm btn-square"
									disabled={!permissions.adminWrite()}
									on:click={(e) => buttonTriggeredRequest(e, deleteAdmin(admin.id))}
								>
									<Trash size="18" />
								</button>
							</span>
						{/if}
					</div>
				</td>
			</tr>
		{/each}
		<tr>
			<td>{data.admins.length + 1}</td>
			<td><Input type="text" bind:value={newAdminUsername} size="sm" /></td>
			<td><Input type="password" bind:value={newAdminPassword} size="sm" /></td>
			<td
				><Badges
					bind:value={newAdminPermissions}
					available={allPermissionBadges}
					disabled={!permissions.adminWrite()}
				/></td
			>
			<td>
				<span
					class="w-min"
					class:cursor-not-allowed={!permissions.adminWrite() ||
						!newAdminUsername ||
						!newAdminPassword}
				>
					<button
						class="btn btn-sm btn-square"
						disabled={!permissions.adminWrite() || !newAdminUsername || !newAdminPassword}
						on:click={async (e) => {
							await buttonTriggeredRequest(
								e,
								addAdmin(newAdminUsername, newAdminPassword, new Permissions(newAdminPermissions))
							);
							newAdminUsername = '';
							newAdminPassword = '';
							newAdminPermissions = [];
						}}
					>
						<UserPlus size="18" />
					</button>
				</span>
			</td>
		</tr>
	</tbody>
</table>

<ErrorToast show={errorMessage !== ''}>
	<span />
</ErrorToast>
