<script lang="ts">
	import { page } from "$app/stores";
	import { goto } from "$app/navigation";
	import type { Snippet } from "svelte";
	import { getContext } from "svelte";
	import { on } from "svelte/events";
	import { Avatar, Logo } from "$lib/components/ui";
	import type { SupabaseClient } from "@supabase/supabase-js";
	import type { Database } from "$lib/supabase/types";
	import { hasPermission, type Permission } from "$lib/utils/permissions";
	import { setContext } from "svelte";
	import * as m from "$lib/paraglide/messages";
	import { totalUnreadCount } from "$lib/stores/matrix";

	interface Member {
		id: string;
		user_id: string;
		role: string;
		profiles: {
			id: string;
			email: string;
			full_name: string | null;
			avatar_url: string | null;
		};
	}

	interface UserProfile {
		id: string;
		email: string;
		full_name: string | null;
		avatar_url: string | null;
	}

	interface Props {
		data: {
			org: {
				id: string;
				name: string;
				slug: string;
				avatar_url?: string | null;
			};
			userRole: string;
			userPermissions: string[] | null;
			members: Member[];
			profile: UserProfile;
		};
		children: Snippet;
	}

	let { data, children }: Props = $props();

	const supabase = getContext<SupabaseClient<Database>>("supabase");

	const isAdmin = $derived(
		data.userRole === "owner" || data.userRole === "admin",
	);

	// Provide a permission checker via context so any child component can use it
	const canAccess = (permission: Permission | string): boolean =>
		hasPermission(data.userRole, data.userPermissions, permission);
	setContext("canAccess", canAccess);

	// Sidebar collapses on all pages except org overview
	const isOrgOverview = $derived($page.url.pathname === `/${data.org.slug}`);
	let sidebarHovered = $state(false);
	const sidebarCollapsed = $derived(!isOrgOverview && !sidebarHovered);

	// User dropdown
	let showUserMenu = $state(false);
	let menuContainerEl = $state<HTMLElement | null>(null);

	// Attach click-outside and Escape listeners only while menu is open.
	// Uses svelte/events 'on' to respect Svelte 5 event delegation order.
	$effect(() => {
		if (!showUserMenu) return;

		// Defer so the opening click doesn't immediately close the menu
		const timer = setTimeout(() => {
			cleanupClick = on(document, "click", (e: MouseEvent) => {
				if (
					menuContainerEl &&
					!menuContainerEl.contains(e.target as Node)
				) {
					showUserMenu = false;
				}
			});
		}, 0);

		const cleanupKey = on(document, "keydown", (e: Event) => {
			if ((e as KeyboardEvent).key === "Escape") showUserMenu = false;
		});

		let cleanupClick: (() => void) | undefined;

		return () => {
			clearTimeout(timer);
			cleanupClick?.();
			cleanupKey();
		};
	});

	async function handleLogout() {
		await supabase.auth.signOut();
		goto("/");
	}

	const navItems = $derived([
		...(canAccess("documents.view")
			? [
					{
						href: `/${data.org.slug}/documents`,
						label: m.nav_files(),
						icon: "cloud",
					},
				]
			: []),
		...(canAccess("calendar.view")
			? [
					{
						href: `/${data.org.slug}/calendar`,
						label: m.nav_calendar(),
						icon: "calendar_today",
					},
				]
			: []),
		{
			href: `/${data.org.slug}/events`,
			label: m.nav_events(),
			icon: "celebration",
		},
		{
			href: `/${data.org.slug}/chat`,
			label: "Chat",
			icon: "chat",
			badge: $totalUnreadCount > 0 ? ($totalUnreadCount > 99 ? "99+" : String($totalUnreadCount)) : null,
		},
		// Settings requires settings.view or admin role
		...(canAccess("settings.view")
			? [
					{
						href: `/${data.org.slug}/settings`,
						label: m.nav_settings(),
						icon: "settings",
					},
				]
			: []),
	]);

	function isActive(href: string): boolean {
		return $page.url.pathname.startsWith(href);
	}
</script>

<!-- Figma-matched layout: bg-background with gap-4 padding -->
<div class="flex h-screen bg-background p-4 gap-4">
	<!-- Organization Module -->
	<aside
		class="
			{sidebarCollapsed ? 'w-[72px]' : 'w-64'}
			transition-all duration-300
			bg-night rounded-[32px] flex flex-col px-4 py-5 gap-4 overflow-hidden shrink-0
		"
		onmouseenter={() => (sidebarHovered = true)}
		onmouseleave={() => (sidebarHovered = false)}
	>
		<!-- Org Header -->
		<a
			href="/{data.org.slug}"
			class="flex items-center gap-2 p-1 rounded-[32px] hover:bg-dark transition-colors"
		>
			<div
				class="shrink-0 transition-all duration-300 {sidebarCollapsed
					? 'w-8 h-8'
					: 'w-12 h-12'}"
			>
				<Avatar
					name={data.org.name}
					src={data.org.avatar_url}
					size="md"
				/>
			</div>
			<div
				class="min-w-0 flex-1 overflow-hidden transition-all duration-300 {sidebarCollapsed
					? 'opacity-0 max-w-0'
					: 'opacity-100 max-w-[200px]'}"
			>
				<h1
					class="font-heading text-h3 text-white truncate whitespace-nowrap"
				>
					{data.org.name}
				</h1>
				<p
					class="text-body-sm text-white font-body capitalize whitespace-nowrap"
				>
					{data.userRole}
				</p>
			</div>
		</a>

		<!-- Nav Items -->
		<nav class="flex-1 flex flex-col gap-1">
			{#each navItems as item}
				<a
					href={item.href}
					class="flex items-center gap-2 h-10 pl-1 pr-2 py-1 rounded-[32px] transition-colors {isActive(
						item.href,
					)
						? 'bg-primary'
						: 'hover:bg-dark'}"
					title={sidebarCollapsed ? item.label : undefined}
				>
					<div
						class="w-8 h-8 flex items-center justify-center p-1 shrink-0"
					>
						<span
							class="material-symbols-rounded {isActive(item.href)
								? 'text-background'
								: 'text-light'}"
							style="font-size: 24px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;"
						>
							{item.icon}
						</span>
					</div>
					<span
						class="font-body text-body truncate whitespace-nowrap transition-all duration-300 {isActive(
							item.href,
						)
							? 'text-background'
							: 'text-white'} {sidebarCollapsed
							? 'opacity-0 max-w-0 overflow-hidden'
							: 'opacity-100 max-w-[200px]'}">{item.label}</span
					>
					{#if item.badge}
						<span class="ml-auto bg-primary text-background text-xs font-bold px-1.5 py-0.5 rounded-full min-w-[18px] text-center shrink-0">
							{item.badge}
						</span>
					{/if}
				</a>
			{/each}
		</nav>

		<!-- User Section + Logo at bottom -->
		<div class="mt-auto flex flex-col gap-3">
			<!-- User Avatar + Quick Menu -->
			<div
				class="relative user-menu-container"
				bind:this={menuContainerEl}
			>
				<button
					type="button"
					class="flex items-center gap-2 p-1 rounded-[32px] hover:bg-dark transition-colors w-full"
					onclick={() => (showUserMenu = !showUserMenu)}
					aria-expanded={showUserMenu}
					aria-haspopup="true"
				>
					<div
						class="shrink-0 transition-all duration-300 {sidebarCollapsed
							? 'w-8 h-8'
							: 'w-10 h-10'}"
					>
						<Avatar
							name={data.profile.full_name || data.profile.email}
							src={data.profile.avatar_url}
							size="sm"
						/>
					</div>
					<div
						class="min-w-0 flex-1 overflow-hidden text-left transition-all duration-300 {sidebarCollapsed
							? 'opacity-0 max-w-0'
							: 'opacity-100 max-w-[200px]'}"
					>
						<p
							class="font-body text-body-sm text-white truncate whitespace-nowrap leading-tight"
						>
							{data.profile.full_name || "User"}
						</p>
						<p
							class="font-body text-[11px] text-light/50 truncate whitespace-nowrap leading-tight"
						>
							{data.profile.email}
						</p>
					</div>
				</button>

				{#if showUserMenu}
					<div
						class="absolute bottom-full left-0 mb-2 py-1 bg-dark border border-light/10 rounded-xl shadow-xl min-w-[200px] z-50"
					>
						<a
							href="/{data.org.slug}/account"
							class="flex items-center gap-3 px-3 py-2 text-sm text-light hover:bg-light/5 transition-colors"
							onclick={() => (showUserMenu = false)}
						>
							<span
								class="material-symbols-rounded text-light/50"
								style="font-size: 18px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 18;"
							>
								person
							</span>
							<span>{m.user_menu_account_settings()}</span>
						</a>
						<a
							href="/"
							class="flex items-center gap-3 px-3 py-2 text-sm text-light hover:bg-light/5 transition-colors"
							onclick={() => (showUserMenu = false)}
						>
							<span
								class="material-symbols-rounded text-light/50"
								style="font-size: 18px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 18;"
							>
								swap_horiz
							</span>
							<span>{m.user_menu_switch_org()}</span>
						</a>
						<div class="border-t border-light/10 my-1"></div>
						<button
							type="button"
							class="w-full flex items-center gap-3 px-3 py-2 text-sm text-error hover:bg-error/10 transition-colors"
							onclick={handleLogout}
						>
							<span
								class="material-symbols-rounded text-error/60"
								style="font-size: 18px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 18;"
							>
								logout
							</span>
							<span>{m.user_menu_logout()}</span>
						</button>
					</div>
				{/if}
			</div>

			<!-- Logo -->
			<a
				href="/"
				title="Back to organizations"
				class="flex items-center justify-center"
			>
				<Logo
					size={sidebarCollapsed ? "sm" : "md"}
					showText={!sidebarCollapsed}
				/>
			</a>
		</div>
	</aside>

	<!-- Main Content Area -->
	<main class="flex-1 bg-night rounded-[32px] overflow-hidden relative">
		{@render children()}
	</main>
</div>
