<script>
	import InputField from '$lib/components/InputField.svelte';
	import SmallLoader from '$lib/components/SmallLoader.svelte';
	import { createEventDispatcher } from 'svelte';
	import { applyAction, enhance } from '$app/forms';
	import { hasPrivilige, receive, send } from '$lib/utils/helpers';
	import { t } from 'svelte-i18n';
	import { PERMISSIONS } from '$lib/utils/constants';
	import { defaultLicence } from '$lib/utils/defaults';

	/** @type {import('../../routes/auth/about/[id]/$types').ActionData} */
	export let form;

	/** @type {App.Locals['subscriptions']}*/
	export let subscriptions;

	/** @type {App.Locals['user']} */
	export let user;

	// Ensure licence is initialized before passing to child
	$: if (user && !user.licence) {
		user.licence = defaultLicence();
	}

	/** @type {App.Locals['user']} */
	export let editor;

	let readonlyUser = !hasPrivilige(editor, PERMISSIONS.Update);

	// $: isNewUser = user === null;
	$: isLoading = user === undefined;

	/** @type {App.Locals['licence_categories']} */
	export let licence_categories;

	const userStatusOptions = [
		{ value: 1, label: $t('userStatus.1'), color: '--subtext1' }, // Grey for "Nicht verifiziert"
		{ value: 2, label: $t('userStatus.2'), color: '--light-green' }, // Light green for "Verifiziert"
		{ value: 3, label: $t('userStatus.3'), color: '--green' }, // Green for "Aktiv"
		{ value: 4, label: $t('userStatus.4'), color: '--pink' }, // Pink for "Passiv"
		{ value: 5, label: $t('userStatus.5'), color: '--red' } // Red for "Deaktiviert"
	];
	const userRoleOptions = [
		{ value: 0, label: $t('userRole.0'), color: '--subtext1' }, // Grey for "Nicht verifiziert"
		{ value: 1, label: $t('userRole.1'), color: '--light-green' }, // Light green for "Verifiziert"
		{ value: 2, label: $t('userRole.2'), color: '--green' }, // Light green for "Verifiziert"
		{ value: 4, label: $t('userRole.4'), color: '--pink' }, // Green for "Aktiv"
		{ value: 8, label: $t('userRole.8'), color: '--red' } // Pink for "Passiv"
	];
	const membershipStatusOptions = [
		{ value: 3, label: $t('userStatus.3'), color: '--green' }, // Green for "Aktiv"
		{ value: 4, label: $t('userStatus.4'), color: '--pink' }, // Pink for "Passiv"
		{ value: 5, label: $t('userStatus.5'), color: '--red' } // Red for "Deaktiviert"
	];
	const licenceStatusOptions = [
		{ value: 1, label: $t('userStatus.1'), color: '--subtext1' }, // Grey for "Nicht verifiziert"
		{ value: 3, label: $t('userStatus.3'), color: '--green' }, // Green for "Aktiv"
		{ value: 4, label: $t('userStatus.4'), color: '--pink' }, // Pink for "Passiv"
		{ value: 5, label: $t('userStatus.5'), color: '--red' } // Red for "Deaktiviert"
	];

	const dispatch = createEventDispatcher();
	const TABS = hasPrivilige(user, PERMISSIONS.Member)
		? ['profile', 'licence', 'membership', 'bankaccount']
		: ['profile', 'bankaccount', 'membership'];
	let activeTab = TABS[0];

	let isUpdating = false,
		password = '',
		confirm_password = '';

	/** @type {Object.<string, App.Locals['licence_categories']>} */
	$: groupedCategories = groupCategories(licence_categories);
	$: subscriptionModelOptions = subscriptions.map((sub) => ({
		value: sub?.name ?? '',
		label: sub?.name ?? ''
	}));
	$: selectedSubscriptionModel =
		subscriptions.find((sub) => sub?.name === user.membership?.subscription_model.name) || null;

	/**
	 * creates groups of categories depending on the first letter
	 * @param {App.Locals['licence_categories']} categories - the categories to sort and group
	 * @returns {Object.<string, App.Locals['licence_categories']>} Grouped categories
	 */
	function groupCategories(categories) {
		return Object.entries(categories)
			.sort((a, b) => a[1].category.localeCompare(b[1].category))
			.reduce(
				(/** @type {Object.<string, App.Locals['licence_categories']>} */ acc, [, category]) => {
					const firstLetter = category.category[0];
					if (!acc[firstLetter]) {
						acc[firstLetter] = [];
					}
					acc[firstLetter].push(category);
					return acc;
				},
				{}
			);
	}

	/** @type {import('../../routes/auth/about/[id]/$types').SubmitFunction} */
	const handleUpdate = async () => {
		isUpdating = true;
		return async ({ result }) => {
			isUpdating = false;
			if (result.type === 'success' || result.type === 'redirect') {
				dispatch('close');
			} else {
				document.querySelector('.modal .container')?.scrollTo({ top: 0, behavior: 'smooth' });
			}
			await applyAction(result);
		};
	};
</script>

{#if isLoading}
	<SmallLoader width={30} message={$t('loading.user_data')} />
{:else if user}
	<form class="content" action="?/updateUser" method="POST" use:enhance={handleUpdate}>
		<input name="user[id]" type="hidden" bind:value={user.id} />
		<h1 class="step-title" style="text-align: center;">
			{user.id ? $t('user.edit') : $t('user.create')}
		</h1>
		{#if form?.success}
			<h4
				class="step-subtitle warning"
				in:receive|global={{ key: Math.floor(Math.random() * 100) }}
				out:send|global={{ key: Math.floor(Math.random() * 100) }}
			>
				Um einen fehlerhaften upload Ihres Bildes zu vermeiden, clicke bitte auf den "Update" Button
				unten.
			</h4>
		{/if}
		{#if form?.errors}
			{#each form?.errors as error (error.id)}
				<h4
					class="step-subtitle warning"
					in:receive|global={{ key: error.id }}
					out:send|global={{ key: error.id }}
				>
					{$t(error.field) + ': ' + $t(error.key)}
				</h4>
			{/each}
		{/if}

		<div class="button-container">
			{#each TABS as tab}
				<button
					type="button"
					class="button-dark"
					class:active={activeTab === tab}
					on:click={() => (activeTab = tab)}
				>
					{$t(tab)}
				</button>
			{/each}
		</div>
		<div class="tab-content" style="display: {activeTab === 'profile' ? 'block' : 'none'}">
			<InputField
				name="user[status]"
				type="select"
				label={$t('status')}
				bind:value={user.status}
				options={userStatusOptions}
				readonly={readonlyUser}
			/>
			{#if hasPrivilige(editor, PERMISSIONS.Super)}
				<InputField
					name="user[role_id]"
					type="select"
					label={$t('user.role')}
					bind:value={user.role_id}
					options={userRoleOptions}
				/>
			{/if}
			{#if hasPrivilige(user, PERMISSIONS.Member)}
				<InputField
					name="user[password]"
					type="password"
					label={$t('password')}
					placeholder={$t('placeholder.password')}
					bind:value={password}
					otherPasswordValue={confirm_password}
				/>
				<InputField
					name="confirm_password"
					type="password"
					label={$t('confirm_password')}
					placeholder={$t('placeholder.password')}
					bind:value={confirm_password}
					otherPasswordValue={password}
				/>
			{/if}
			<InputField
				name="user[first_name]"
				label={$t('user.first_name')}
				bind:value={user.first_name}
				placeholder={$t('placeholder.first_name')}
				required={true}
				readonly={readonlyUser}
			/>
			<InputField
				name="user[last_name]"
				label={$t('user.last_name')}
				bind:value={user.last_name}
				placeholder={$t('placeholder.last_name')}
				required={true}
				readonly={readonlyUser}
			/>
			<InputField
				name="user[company]"
				label={$t('company')}
				bind:value={user.company}
				placeholder={$t('placeholder.company')}
			/>
			<InputField
				name="user[email]"
				type="email"
				label={$t('user.email')}
				bind:value={user.email}
				placeholder={$t('placeholder.email')}
				required={true}
			/>
			<InputField
				name="user[phone]"
				type="tel"
				label={$t('user.phone')}
				bind:value={user.phone}
				placeholder={$t('placeholder.phone')}
			/>
			{#if hasPrivilige(user, PERMISSIONS.Member)}
				<InputField
					name="user[dateofbirth]"
					type="date"
					label={$t('user.dateofbirth')}
					bind:value={user.dateofbirth}
					placeholder={$t('placeholder.dateofbirth')}
					readonly={readonlyUser}
				/>
			{/if}
			<InputField
				name="user[address]"
				label={$t('address')}
				bind:value={user.address}
				placeholder={$t('placeholder.address')}
			/>
			<InputField
				name="user[zip_code]"
				label={$t('zip_code')}
				bind:value={user.zip_code}
				placeholder={$t('placeholder.zip_code')}
			/>
			<InputField
				name="user[city]"
				label={$t('city')}
				bind:value={user.city}
				placeholder={$t('placeholder.city')}
			/>
			{#if !readonlyUser}
				<InputField
					name="user[notes]"
					type="textarea"
					label={$t('notes')}
					bind:value={user.notes}
					placeholder={$t('placeholder.notes', {
						values: { name: user.first_name || '' }
					})}
					rows={10}
				/>
			{/if}
		</div>

		{#if hasPrivilige(user, PERMISSIONS.Member)}
			<div class="tab-content" style="display: {activeTab === 'licence' ? 'block' : 'none'}">
				<InputField
					name="user[licence][status]"
					type="select"
					label={$t('status')}
					bind:value={user.licence.status}
					options={licenceStatusOptions}
					readonly={readonlyUser}
				/>
				<InputField
					name="user[licence][number]"
					type="text"
					label={$t('licence_number')}
					bind:value={user.licence.number}
					placeholder={$t('placeholder.licence_number')}
					toUpperCase={true}
					readonly={readonlyUser}
				/>
				<InputField
					name="user[licence][issued_date]"
					type="date"
					label={$t('issued_date')}
					bind:value={user.licence.issued_date}
					placeholder={$t('placeholder.issued_date')}
					readonly={readonlyUser}
				/>
				<InputField
					name="user[licence][expiration_date]"
					type="date"
					label={$t('expiration_date')}
					bind:value={user.licence.expiration_date}
					placeholder={$t('placeholder.expiration_date')}
					readonly={readonlyUser}
				/>
				<InputField
					name="user[licence][country]"
					label={$t('country')}
					bind:value={user.licence.country}
					placeholder={$t('placeholder.issuing_country')}
					readonly={readonlyUser}
				/>
				<div class="licence-categories">
					<h3>{$t('licence_categories')}</h3>
					<div class="checkbox-grid">
						{#each Object.entries(groupedCategories) as [, categories], groupIndex}
							{#if groupIndex > 0}
								<div class="category-break"></div>
							{/if}
							{#each categories as category}
								<div class="checkbox-item">
									<div class="checkbox-label-container">
										<InputField
											type="checkbox"
											name="user[licence][categories][]"
											value={JSON.stringify(category)}
											label={category.category}
											checked={user.licence.categories != null &&
												user.licence.categories.some((cat) => cat.category === category.category)}
										/>
									</div>
									<span class="checkbox-description">
										{$t(`licenceCategory.${category.category}`)}
									</span>
								</div>
							{/each}
						{/each}
					</div>
				</div>
			</div>
		{/if}
		<div class="tab-content" style="display: {activeTab === 'membership' ? 'block' : 'none'}">
			<InputField
				name="user[membership][status]"
				type="select"
				label={$t('status')}
				bind:value={user.membership.status}
				options={membershipStatusOptions}
				readonly={readonlyUser}
			/>
			<InputField
				name="user[membership][subscription_model][name]"
				type="select"
				label={$t('subscription.subscription')}
				bind:value={user.membership.subscription_model.name}
				options={subscriptionModelOptions}
				readonly={readonlyUser || !hasPrivilige(user, PERMISSIONS.Member)}
			/>
			<div class="subscription-info">
				{#if hasPrivilige(user, PERMISSIONS.Member)}
					<div class="subscription-column">
						<p>
							<strong>{$t('subscription.monthly_fee')}:</strong>
							{selectedSubscriptionModel?.monthly_fee || '-'} €
						</p>
						<p>
							<strong>{$t('subscription.hourly_rate')}:</strong>
							{selectedSubscriptionModel?.hourly_rate || '-'} €
						</p>
						{#if selectedSubscriptionModel?.included_hours_per_year}
							<p>
								<strong>{$t('subscription.included_hours_per_year')}:</strong>
								{selectedSubscriptionModel?.included_hours_per_year}
							</p>
						{/if}
						{#if selectedSubscriptionModel?.included_hours_per_month}
							<p>
								<strong>{$t('subscription.included_hours_per_month')}:</strong>
								{selectedSubscriptionModel?.included_hours_per_month}
							</p>
						{/if}
					</div>
				{/if}
				<div class="subscription-column">
					<p>
						<strong>{$t('details')}:</strong>
						{selectedSubscriptionModel?.details || '-'}
					</p>
					{#if selectedSubscriptionModel?.conditions}
						<p>
							<strong>{$t('subscription.conditions')}:</strong>
							{selectedSubscriptionModel?.conditions}
						</p>
					{/if}
				</div>
			</div>
			<InputField
				name="user[membership][start_date]"
				type="date"
				label={$t('start')}
				bind:value={user.membership.start_date}
				placeholder={$t('placeholder.start_date')}
				readonly={readonlyUser}
			/>
			<InputField
				name="user[membership][end_date]"
				type="date"
				label={$t('end')}
				bind:value={user.membership.end_date}
				placeholder={$t('placeholder.end_date')}
				readonly={readonlyUser}
			/>
			{#if hasPrivilige(user, PERMISSIONS.Member)}
				<InputField
					name="user[membership][parent_member_id]"
					type="number"
					label={$t('parent_member_id')}
					bind:value={user.membership.parent_member_id}
					placeholder={$t('placeholder.parent_member_id')}
					readonly={readonlyUser}
				/>
			{/if}
		</div>
		<div class="tab-content" style="display: {activeTab === 'bankaccount' ? 'block' : 'none'}">
			<InputField
				name="user[bank_account][account_holder_name]"
				label={$t('bank_account_holder')}
				bind:value={user.bank_account.account_holder_name}
				placeholder={$t('placeholder.bank_account_holder')}
			/>
			<InputField
				name="user[bank_account][bank_name]"
				label={$t('bank_name')}
				bind:value={user.bank_account.bank}
				placeholder={$t('placeholder.bank_name')}
			/>
			<InputField
				name="user[bank_account][iban]"
				label={$t('iban')}
				bind:value={user.bank_account.iban}
				placeholder={$t('placeholder.iban')}
				toUpperCase={true}
			/>
			<InputField
				name="user[bank_account][bic]"
				label={$t('bic')}
				bind:value={user.bank_account.bic}
				placeholder={$t('placeholder.bic')}
				toUpperCase={true}
			/>
			<InputField
				name="user[bank_account][mandate_reference]"
				label={$t('mandate_reference')}
				bind:value={user.bank_account.mandate_reference}
				placeholder={$t('placeholder.mandate_reference')}
				readonly={readonlyUser}
			/>
			<InputField
				name="user[bank_account][mandate_date_signed]"
				label={$t('mandate_date_signed')}
				type="date"
				bind:value={user.bank_account.mandate_date_signed}
				readonly={true}
			/>
		</div>
		<div class="button-container">
			{#if isUpdating}
				<SmallLoader width={30} message={$t('loading.updating')} />
			{:else}
				<button type="button" class="button-dark" on:click={() => dispatch('cancel')}>
					{$t('cancel')}</button
				>
				<button type="submit" class="button-dark">{$t('confirm')}</button>
			{/if}
		</div>
	</form>
{/if}

<style>
	.category-break {
		grid-column: 1 / -1;
		height: 1px;
		background-color: var(--overlay0);
		margin-top: 10px;
		margin-left: 20%;
		width: 60%;
		opacity: 0.4;
	}

	.licence-categories {
		margin-bottom: 20px;
	}

	.checkbox-grid {
		display: grid;
		grid-template-columns: 1fr;
		gap: 0px;
	}

	.checkbox-item {
		display: flex;
		justify-content: space-between;
		align-items: center;
	}

	.checkbox-label-container {
		flex: 0 0 auto;
		width: 4em;
		margin-right: 5px;
	}

	.checkbox-description {
		flex: 1;
		font-size: 15px;
		color: var(--subtext0);
		margin-left: 10px;
	}

	@media (min-width: 768px) {
		.checkbox-grid {
			grid-template-columns: 1fr 1fr;
			gap: 0px;
		}
	}

	@media (max-width: 480px) {
		.checkbox-item {
			flex-direction: column;
			align-items: flex-start;
		}

		.checkbox-description {
			margin-left: 24px;
			margin-top: 5px;
			text-align: left;
		}
	}
	.subscription-info {
		display: flex;
		flex-wrap: wrap;
		gap: 1rem;
		margin-top: 1rem;
		font-size: 0.9rem;
		background-color: var(--surface0);
		padding: 1rem;
		border-radius: 8px;
		border: 1px solid var(--surface1);
	}

	.subscription-column {
		flex: 1;
		min-width: 200px;
		color: var(--text);
	}

	.subscription-column p {
		margin: 0.5rem 0;
	}

	.subscription-column strong {
		display: inline-block;
		min-width: 100px;
		color: var(--lavender);
	}
	.tab-content {
		padding: 1rem;
		border-radius: 0 0 3px 3px;
		background-color: var(--surface0);
		border: 1px solid var(--surface1);
		margin-top: 1rem;
	}
	.button-container {
		display: flex;
		justify-content: space-between;
		flex-wrap: wrap;
		gap: 10px;
		margin-top: 1rem;
		width: 100%;
	}

	.button-container button {
		flex: 1 1 0;
		min-width: 120px;
		max-width: calc(50% - 5px);
		background-color: var(--surface1);
		color: var(--text);
		border: 1px solid var(--overlay0);
		transition: all 0.2s ease-in-out;
	}

	.button-container button:hover {
		background-color: var(--surface2);
		border-color: var(--lavender);
	}

	.button-container button.active {
		background-color: var(--mauve);
		border-color: var(--mauve);
		color: var(--base);
	}

	@media (max-width: 480px) {
		.button-container button {
			flex-basis: 100%;
			max-width: none;
		}
	}
</style>
