<script lang="ts">
	import { t } from 'svelte-i18n';
	import { TargetType, PermissionLevel } from '$lib/utils/constants.js';
	import {
		loadBoardPermissions,
		grantBoardPermission,
		revokeBoardPermission,
		getTargetName as resolveTargetName,
		type PermissionRecord,
		type SelectOption
	} from '$lib/utils/boardPermissions.js';

	interface Props {
		boardId: string;
		boardName: string;
		isGuestAccessible: boolean;
		users: SelectOption[];
		groups: SelectOption[];
		onClose: () => void;
		onGuestToggle: (value: boolean) => void;
	}

	let {
		boardId,
		boardName,
		isGuestAccessible,
		users,
		groups,
		onClose,
		onGuestToggle
	}: Props = $props();

	let permissions = $state<PermissionRecord[]>([]);
	let loading = $state(true);
	let errorMessage = $state('');
	let copySuccess = $state(false);
	let copyTimerId = $state<ReturnType<typeof setTimeout> | null>(null);

	let selectedTargetType = $state<string>(TargetType.USER);
	let selectedTargetId = $state('');
	let selectedLevel = $state<string>(PermissionLevel.VIEW);
	let searchQuery = $state('');

	let targetOptions = $derived(
		selectedTargetType === TargetType.USER ? users : groups
	);

	let filteredTargetOptions = $derived(
		searchQuery.length > 0
			? targetOptions.filter((opt) =>
					opt.name.toLowerCase().includes(searchQuery.toLowerCase())
				)
			: targetOptions
	);

	async function loadPermissions() {
		loading = true;
		errorMessage = '';
		try {
			permissions = await loadBoardPermissions(boardId);
		} catch (err) {
			errorMessage = err instanceof Error ? err.message : 'Network error';
		} finally {
			loading = false;
		}
	}

	async function handleGrant() {
		if (!selectedTargetId) return;
		errorMessage = '';
		try {
			await grantBoardPermission(boardId, selectedTargetType, selectedTargetId, selectedLevel);
			selectedTargetId = '';
			searchQuery = '';
			await loadPermissions();
		} catch (err) {
			errorMessage = err instanceof Error ? err.message : 'Network error';
		}
	}

	async function handleRevoke(perm: PermissionRecord) {
		errorMessage = '';
		try {
			await revokeBoardPermission(boardId, perm.targetType, perm.targetId);
			await loadPermissions();
		} catch (err) {
			errorMessage = err instanceof Error ? err.message : 'Network error';
		}
	}

	function getTargetName(targetType: string, targetId: string): string {
		return resolveTargetName(targetType, targetId, users, groups);
	}

	function getLevelLabel(level: string): string {
		switch (level) {
			case PermissionLevel.VIEW:
				return $t('admin.perm_view');
			case PermissionLevel.EDIT:
				return $t('admin.perm_edit');
			case PermissionLevel.ADMIN:
				return $t('admin.perm_admin');
			default:
				return level;
		}
	}

	async function handleCopyLink() {
		try {
			const url = `${window.location.origin}/boards/${boardId}`;
			await navigator.clipboard.writeText(url);
			copySuccess = true;
			if (copyTimerId !== null) {
				clearTimeout(copyTimerId);
			}
			copyTimerId = setTimeout(() => {
				copySuccess = false;
				copyTimerId = null;
			}, 2000);
		} catch {
			// Fallback: ignore if clipboard API not available
		}
	}

	function handleBackdropClick(event: MouseEvent) {
		if (event.target === event.currentTarget) {
			onClose();
		}
	}

	function handleKeydown(event: KeyboardEvent) {
		if (event.key === 'Escape') {
			onClose();
		}
	}

	// Load permissions on mount; clean up copy timer on destroy
	$effect(() => {
		loadPermissions();
		return () => {
			if (copyTimerId !== null) {
				clearTimeout(copyTimerId);
			}
		};
	});
</script>

<svelte:window onkeydown={handleKeydown} />

<!-- Backdrop -->
<div
	class="fixed inset-0 z-50 flex items-center justify-center bg-black/50"
	onclick={handleBackdropClick}
	role="presentation"
>
	<div class="mx-4 w-full max-w-lg rounded-[1.4rem] border border-border bg-card p-6 shadow-[var(--shadow-lift)]" role="dialog" aria-modal="true">
		<!-- Header -->
		<div class="mb-4 flex items-center justify-between">
			<h2 class="text-lg font-semibold text-card-foreground">
				{$t('board.share_title', { values: { name: boardName } })}
			</h2>
			<button
				type="button"
				onclick={onClose}
				class="rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
				aria-label={$t('common.cancel')}
			>
				<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
					<line x1="18" y1="6" x2="6" y2="18" />
					<line x1="6" y1="6" x2="18" y2="18" />
				</svg>
			</button>
		</div>

		<!-- Copy link -->
		<div class="mb-4 flex items-center gap-2">
			<button
				type="button"
				onclick={handleCopyLink}
				class="flex items-center gap-2 rounded-xl border border-border px-3 py-2 text-sm text-foreground transition-colors hover:bg-accent"
			>
				<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
					<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
					<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
				</svg>
				{copySuccess ? $t('board.share_copied') : $t('board.share_copy_link')}
			</button>
		</div>

		<!-- Guest access toggle -->
		<div class="mb-4 rounded-lg border border-border bg-muted/30 p-3">
			<label class="flex items-center gap-3 text-sm text-foreground">
				<input
					type="checkbox"
					checked={isGuestAccessible}
					onchange={(e) => onGuestToggle(e.currentTarget.checked)}
					class="h-4 w-4 rounded border-input accent-primary"
				/>
				<div>
					<span class="font-medium">{$t('board.guest_accessible')}</span>
					<p class="text-xs text-muted-foreground">{$t('board.share_guest_description')}</p>
				</div>
			</label>
		</div>

		<!-- Quick add permission -->
		<div class="mb-4 rounded-lg border border-border p-3">
			<h3 class="mb-2 text-sm font-medium text-card-foreground">{$t('board.share_add_access')}</h3>
			<div class="flex gap-2">
				<select
					bind:value={selectedTargetType}
					onchange={() => { selectedTargetId = ''; searchQuery = ''; }}
					class="rounded-xl border border-input bg-background px-2 py-1.5 text-sm text-foreground"
				>
					<option value={TargetType.USER}>{$t('admin.perm_user')}</option>
					<option value={TargetType.GROUP}>{$t('admin.perm_group')}</option>
				</select>
				<div class="relative flex-1">
					<input
						type="text"
						bind:value={searchQuery}
						placeholder={$t('board.access_search_placeholder')}
						class="w-full rounded-xl border border-input bg-background px-2 py-1.5 text-sm text-foreground placeholder:text-muted-foreground"
					/>
					{#if searchQuery.length > 0 && filteredTargetOptions.length > 0 && !selectedTargetId}
						<div class="absolute z-10 mt-1 max-h-32 w-full overflow-y-auto rounded-xl border border-border bg-card shadow-[var(--shadow-soft)]">
							{#each filteredTargetOptions as option (option.id)}
								<button
									type="button"
									class="w-full px-3 py-1.5 text-left text-sm text-foreground hover:bg-accent"
									onclick={() => { selectedTargetId = option.id; searchQuery = option.name; }}
								>
									{option.name}
								</button>
							{/each}
						</div>
					{/if}
				</div>
				<select
					bind:value={selectedLevel}
					class="rounded-xl border border-input bg-background px-2 py-1.5 text-sm text-foreground"
				>
					<option value={PermissionLevel.VIEW}>{$t('admin.perm_view')}</option>
					<option value={PermissionLevel.EDIT}>{$t('admin.perm_edit')}</option>
					<option value={PermissionLevel.ADMIN}>{$t('admin.perm_admin')}</option>
				</select>
				<button
					type="button"
					onclick={handleGrant}
					disabled={!selectedTargetId}
					class="shrink-0 rounded-xl bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50"
				>
					{$t('common.add')}
				</button>
			</div>
		</div>

		{#if errorMessage}
			<p class="mb-3 text-sm text-destructive">{errorMessage}</p>
		{/if}

		<!-- Current access list -->
		<div class="max-h-48 overflow-y-auto">
			{#if loading}
				<p class="text-sm text-muted-foreground">{$t('board.access_loading')}</p>
			{:else if permissions.length > 0}
				<h3 class="mb-2 text-sm font-medium text-card-foreground">{$t('board.share_current_access')}</h3>
				<div class="space-y-1">
					{#each permissions as perm (perm.id)}
						<div class="flex items-center justify-between rounded px-2 py-1.5 hover:bg-muted/50">
							<div class="flex items-center gap-2 text-sm">
								<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-muted-foreground">
									{#if perm.targetType === TargetType.USER}
										<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
										<circle cx="12" cy="7" r="4" />
									{:else}
										<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
										<circle cx="9" cy="7" r="4" />
										<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
										<path d="M16 3.13a4 4 0 0 1 0 7.75" />
									{/if}
								</svg>
								<span class="text-foreground">{getTargetName(perm.targetType, perm.targetId)}</span>
								<span class="rounded-full bg-accent px-2 py-0.5 text-xs text-accent-foreground">
									{getLevelLabel(perm.level)}
								</span>
							</div>
							<button
								type="button"
								onclick={() => handleRevoke(perm)}
								class="text-xs text-destructive hover:underline"
							>
								{$t('admin.perm_revoke')}
							</button>
						</div>
					{/each}
				</div>
			{:else}
				<p class="text-sm text-muted-foreground">{$t('board.access_none')}</p>
			{/if}
		</div>
	</div>
</div>
