<script lang="ts">
	import Sidebar from '$lib/components/Sidebar.svelte';
	import { onMount } from 'svelte';
	import { goto } from '$app/navigation';
	import { auth } from '$lib/auth.svelte';
	import { toast } from '$lib/toast.svelte';
	import {
		getTeam,
		listTeams,
		updateTeam,
		addMember,
		removeMember,
		updateMemberRole,
		deleteTeam,
		leaveTeam,
		switchTeam,
		searchUsers,
		type TeamInfo,
		type TeamMember,
		type UserSearchResult
	} from '$lib/api/team';
	import { teams as teamsStore } from '$lib/teams.svelte';

	let collapsed = $state(
		typeof window !== 'undefined'
			? localStorage.getItem('wrenn_sidebar_collapsed') === 'true'
			: false
	);

	// Page data
	let team = $state<TeamInfo | null>(null);
	let members = $state<TeamMember[]>([]);
	let loading = $state(true);
	let error = $state<string | null>(null);

	// True when this is the user's only team — deleting/leaving would leave them teamless
	let isLastTeam = $derived(teamsStore.list.length <= 1);

	// Current user's role — derived from members list
	let myRole = $derived(members.find((m) => m.user_id === auth.userId)?.role ?? 'member');
	let canManage = $derived(myRole === 'owner' || myRole === 'admin');

	// Inline name edit
	let editingName = $state(false);
	let editName = $state('');
	let savingName = $state(false);
	let nameError = $state<string | null>(null);
	let nameInputEl = $state<HTMLInputElement | null>(null);

	// Copy state
	let copiedSlug = $state(false);
	let copiedId = $state(false);

	// Add member dialog
	let showAddMember = $state(false);
	let addEmail = $state('');
	let searchResults = $state<UserSearchResult[]>([]);
	let searchLoading = $state(false);
	let showResults = $state(false);
	let adding = $state(false);
	let addError = $state<string | null>(null);
	let searchTimeout: ReturnType<typeof setTimeout> | null = null;

	// Split button dropdown (members table)
	let openDropdownId = $state<string | null>(null);
	let dropdownPos = $state<{ top: number; left: number }>({ top: 0, left: 0 });

	// Role update (inline, no confirmation needed — reversible)
	let updatingRoleId = $state<string | null>(null);

	// Remove member confirmation
	let removeTarget = $state<TeamMember | null>(null);
	let removing = $state(false);
	let removeError = $state<string | null>(null);

	// Danger zone
	let showDangerConfirm = $state(false);
	let dangerLoading = $state(false);
	let dangerError = $state<string | null>(null);

	async function fetchTeam() {
		loading = true;
		error = null;
		if (!auth.teamId) {
			loading = false;
			return;
		}
		const [teamResult] = await Promise.all([
			getTeam(auth.teamId),
			teamsStore.fetch()
		]);
		if (teamResult.ok) {
			team = teamResult.data.team;
			members = teamResult.data.members;
		} else {
			error = teamResult.error;
		}
		loading = false;
	}

	function startEditName() {
		if (!team || !canManage) return;
		editName = team.name;
		editingName = true;
		nameError = null;
		setTimeout(() => nameInputEl?.focus(), 0);
	}

	function cancelEditName() {
		editingName = false;
		nameError = null;
	}

	async function saveEditName() {
		if (!team) return;
		const trimmed = editName.trim();
		if (!trimmed || trimmed === team.name) {
			cancelEditName();
			return;
		}
		savingName = true;
		nameError = null;
		const result = await updateTeam(team.id, trimmed);
		if (result.ok) {
			team = { ...team, name: trimmed };
			editingName = false;
			toast.success('Team name updated');
		} else {
			nameError = result.error;
		}
		savingName = false;
	}

	async function copyToClipboard(text: string, which: 'slug' | 'id') {
		try {
			await navigator.clipboard.writeText(text);
			if (which === 'slug') {
				copiedSlug = true;
				setTimeout(() => (copiedSlug = false), 2000);
			} else {
				copiedId = true;
				setTimeout(() => (copiedId = false), 2000);
			}
		} catch {
			toast.error('Copy failed — select the text and copy manually.');
		}
	}

	function handleSearchInput() {
		const val = addEmail.trim();
		showResults = false;
		if (searchTimeout) clearTimeout(searchTimeout);
		if (val.length < 3) {
			searchResults = [];
			return;
		}
		searchTimeout = setTimeout(async () => {
			searchLoading = true;
			const result = await searchUsers(val);
			if (result.ok) {
				searchResults = result.data;
				showResults = result.data.length > 0;
			}
			searchLoading = false;
		}, 300);
	}

	function selectSearchResult(user: UserSearchResult) {
		addEmail = user.email;
		showResults = false;
	}

	async function handleAddMember() {
		if (!team || !addEmail.trim()) return;
		adding = true;
		addError = null;
		const result = await addMember(team.id, addEmail.trim().toLowerCase());
		if (result.ok) {
			members = [...members, result.data];
			showAddMember = false;
			addEmail = '';
			searchResults = [];
			showResults = false;
			toast.success('Member added');
		} else {
			addError = result.error;
		}
		adding = false;
	}

	async function handleUpdateRole(member: TeamMember, newRole: 'admin' | 'member') {
		if (!team) return;
		updatingRoleId = member.user_id;
		openDropdownId = null;
		const result = await updateMemberRole(team.id, member.user_id, newRole);
		if (result.ok) {
			members = members.map((m) =>
				m.user_id === member.user_id ? { ...m, role: newRole } : m
			);
			toast.success(
				newRole === 'admin'
					? `${member.email} is now an admin`
					: `${member.email} is now a member`
			);
		} else {
			toast.error(result.error);
		}
		updatingRoleId = null;
	}

	async function handleRemoveMember() {
		if (!team || !removeTarget) return;
		removing = true;
		removeError = null;
		const uid = removeTarget.user_id;
		const result = await removeMember(team.id, uid);
		if (result.ok) {
			members = members.filter((m) => m.user_id !== uid);
			removeTarget = null;
			toast.success('Member removed');
		} else {
			removeError = result.error;
		}
		removing = false;
	}

	async function handleDangerAction() {
		if (!team) return;
		dangerLoading = true;
		dangerError = null;
		const result = myRole === 'owner' ? await deleteTeam(team.id) : await leaveTeam(team.id);
		if (result.ok) {
			// Fetch remaining teams and switch to the first available one
			const teamsResult = await listTeams();
			const remaining = teamsResult.ok ? teamsResult.data : [];
			if (remaining.length > 0) {
				const switchResult = await switchTeam(remaining[0].id);
				if (switchResult.ok) {
					auth.login(switchResult.data);
					window.location.reload();
					return;
				}
			}
			// No teams left — prompt user to create one
			dangerLoading = false;
			showDangerConfirm = false;
			toast.error('No teams remaining. Use the sidebar to create a new team.');
		} else {
			dangerError = result.error;
			dangerLoading = false;
		}
	}

	function formatDate(iso: string): string {
		return new Date(iso).toLocaleDateString('en-US', {
			month: 'short',
			day: 'numeric',
			year: 'numeric'
		});
	}

	function roleLabel(role: string): string {
		if (role === 'owner') return 'Owner';
		if (role === 'admin') return 'Admin';
		return 'Member';
	}

	// Whether to show actions for a given member row
	function canActOn(member: TeamMember): boolean {
		if (!canManage) return false;
		if (member.user_id === auth.userId) return false; // can't act on self
		if (member.role === 'owner') return false; // can't act on owner
		return true;
	}

	onMount(fetchTeam);
</script>

<svelte:head>
	<title>Wrenn - Team</title>
</svelte:head>

<!-- svelte-ignore a11y_no_static_element_interactions -->
<svelte:window
	onkeydown={(e) => {
		if (e.key === 'Escape') {
			if (openDropdownId) {
				openDropdownId = null;
				return;
			}
			if (editingName && !savingName) {
				cancelEditName();
				return;
			}
			if (removing || adding || dangerLoading) return;
			removeTarget = null;
			if (!adding) showAddMember = false;
			showDangerConfirm = false;
		}
	}}
	onclick={(e) => {
		if (openDropdownId && !(e.target as Element)?.closest('.split-btn-container')) {
			openDropdownId = null;
		}
		if (showResults && !(e.target as Element)?.closest('.search-container')) {
			showResults = false;
		}
	}}
/>

<div class="flex h-screen overflow-hidden">
	<Sidebar bind:collapsed />

	<div class="flex flex-1 flex-col overflow-hidden">
		<main class="flex-1 overflow-y-auto bg-[var(--color-bg-0)]">
			<!-- Header -->
			<div class="px-7 pt-8">
				<h1 class="font-serif text-page tracking-[-0.02em] text-[var(--color-text-bright)]">
					Team
				</h1>
				<p class="mt-2 text-ui text-[var(--color-text-tertiary)]">
					Manage your team, its members, and account settings.
				</p>
				<div class="mt-6 border-b border-[var(--color-border)]"></div>
			</div>

			<!-- Content -->
			<div class="p-8" style="animation: fadeUp 0.35s ease both">
				{#if error}
					<div
						class="mb-6 flex items-center justify-between gap-4 rounded-[var(--radius-card)] border border-[var(--color-red)]/30 bg-[var(--color-red)]/5 px-4 py-3 text-ui text-[var(--color-red)]"
					>
						<span>{error}</span>
						<button
							onclick={fetchTeam}
							class="shrink-0 font-semibold underline-offset-2 hover:underline"
						>
							Try again
						</button>
					</div>
				{/if}

				{#if loading}
					<div class="flex items-center justify-center py-24">
						<div class="flex items-center gap-3 text-ui text-[var(--color-text-secondary)]">
							<svg
								class="animate-spin"
								width="16"
								height="16"
								viewBox="0 0 24 24"
								fill="none"
								stroke="currentColor"
								stroke-width="2"
							>
								<path d="M21 12a9 9 0 1 1-6.219-8.56" />
							</svg>
							Loading team...
						</div>
					</div>
				{:else if !auth.teamId}
					<div class="flex flex-col items-center justify-center py-[72px]">
						<div class="mb-5 flex h-14 w-14 items-center justify-center rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-3)]">
							<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--color-text-secondary)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
								<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"/>
							</svg>
						</div>
						<p class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]">No team yet</p>
						<p class="mt-1.5 max-w-xs text-center text-ui text-[var(--color-text-tertiary)]">
							Use the team switcher in the sidebar to create your first team.
						</p>
					</div>
				{:else if team}
					<!-- ── Team Info ── -->
					<section class="mb-8">
						<div
							class="rounded-[var(--radius-card)] border border-[var(--color-border)] bg-[var(--color-bg-1)]"
						>
							<!-- Name row -->
							<div class="flex items-center gap-4 border-b border-[var(--color-border)] px-5 py-4">
								<div class="min-w-0 flex-1">
									<div
										class="mb-1.5 text-label font-semibold uppercase tracking-[0.05em] text-[var(--color-text-muted)]"
									>
										Team name
									</div>
									{#if editingName}
										<div class="flex items-center gap-2">
											<input
												bind:this={nameInputEl}
												bind:value={editName}
												onkeydown={(e) => {
													if (e.key === 'Enter' && !savingName) saveEditName();
													if (e.key === 'Escape' && !savingName) cancelEditName();
												}}
												disabled={savingName}
												class="min-w-0 flex-1 rounded-[var(--radius-input)] border border-[var(--color-accent)] bg-[var(--color-bg-4)] px-3 py-1.5 text-ui text-[var(--color-text-bright)] outline-none transition-colors duration-150 disabled:opacity-60"
											/>
											<!-- Save button -->
											<button
												onclick={saveEditName}
												disabled={savingName || !editName.trim()}
												title="Save"
												class="flex h-7 w-7 items-center justify-center rounded-[var(--radius-button)] border border-[var(--color-accent)]/40 bg-[var(--color-accent-glow-mid)] text-[var(--color-accent-bright)] transition-colors duration-150 hover:bg-[var(--color-accent-glow)] disabled:opacity-40"
											>
												{#if savingName}
													<svg
														class="animate-spin"
														width="12"
														height="12"
														viewBox="0 0 24 24"
														fill="none"
														stroke="currentColor"
														stroke-width="2"
													>
														<path d="M21 12a9 9 0 1 1-6.219-8.56" />
													</svg>
												{:else}
													<svg
														width="12"
														height="12"
														viewBox="0 0 24 24"
														fill="none"
														stroke="currentColor"
														stroke-width="2.5"
														stroke-linecap="round"
														stroke-linejoin="round"
													>
														<polyline points="20 6 9 17 4 12" />
													</svg>
												{/if}
											</button>
											<!-- Cancel button -->
											<button
												onclick={cancelEditName}
												disabled={savingName}
												title="Cancel"
												class="flex h-7 w-7 items-center justify-center rounded-[var(--radius-button)] border border-[var(--color-border-mid)] text-[var(--color-text-tertiary)] transition-colors duration-150 hover:border-[var(--color-border-mid)] hover:text-[var(--color-text-secondary)] disabled:opacity-40"
											>
												<svg
													width="12"
													height="12"
													viewBox="0 0 24 24"
													fill="none"
													stroke="currentColor"
													stroke-width="2.5"
													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>
										{#if nameError}
											<p class="mt-1.5 text-meta text-[var(--color-red)]">{nameError}</p>
										{/if}
									{:else}
										<!-- svelte-ignore a11y_click_events_have_key_events -->
										<div
											class="group flex items-center gap-2"
											onclick={canManage ? startEditName : undefined}
											role={canManage ? 'button' : undefined}
											tabindex={canManage ? 0 : undefined}
											onkeydown={canManage
												? (e) => {
														if (e.key === 'Enter' || e.key === ' ') startEditName();
													}
												: undefined}
											class:cursor-pointer={canManage}
											title={canManage ? 'Click to edit' : undefined}
										>
											<span
												class="text-ui font-medium text-[var(--color-text-bright)] {canManage ? 'group-hover:text-[var(--color-text-bright)]' : ''}"
											>
												{team.name}
											</span>
											{#if canManage}
												<svg
													width="12"
													height="12"
													viewBox="0 0 24 24"
													fill="none"
													stroke="currentColor"
													stroke-width="2"
													stroke-linecap="round"
													stroke-linejoin="round"
													class="shrink-0 text-[var(--color-text-tertiary)]"
												>
													<path
														d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
													/>
													<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
												</svg>
											{/if}
										</div>
									{/if}
								</div>
							</div>

							<!-- Slug row -->
							<div class="flex items-center gap-4 border-b border-[var(--color-border)] px-5 py-4">
								<div class="min-w-0 flex-1">
									<div
										class="mb-1.5 text-label font-semibold uppercase tracking-[0.05em] text-[var(--color-text-muted)]"
									>
										Slug
									</div>
									<span class="font-mono text-ui text-[var(--color-text-secondary)]"
										>{team.slug}</span
									>
								</div>
								<button
									onclick={() => copyToClipboard(team!.slug, 'slug')}
									class="flex shrink-0 items-center gap-1.5 rounded-[var(--radius-button)] border px-3 py-1.5 text-meta font-semibold transition-all duration-150
										{copiedSlug
										? 'border-[var(--color-accent)]/40 bg-[var(--color-accent-glow-mid)] text-[var(--color-accent-mid)]'
										: 'border-[var(--color-border-mid)] text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]'}"
								>
									{#if copiedSlug}
										<svg
											width="12"
											height="12"
											viewBox="0 0 24 24"
											fill="none"
											stroke="currentColor"
											stroke-width="2.5"
											stroke-linecap="round"
											stroke-linejoin="round"
										>
											<polyline points="20 6 9 17 4 12" />
										</svg>
										Copied
									{:else}
										<svg
											width="12"
											height="12"
											viewBox="0 0 24 24"
											fill="none"
											stroke="currentColor"
											stroke-width="2"
											stroke-linecap="round"
											stroke-linejoin="round"
										>
											<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
											<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
										</svg>
										Copy
									{/if}
								</button>
							</div>

							<!-- Team ID row -->
							<div class="flex items-center gap-4 px-5 py-4">
								<div class="min-w-0 flex-1">
									<div
										class="mb-1.5 text-label font-semibold uppercase tracking-[0.05em] text-[var(--color-text-muted)]"
									>
										Team ID
									</div>
									<span class="font-mono text-ui text-[var(--color-text-secondary)]"
										>{team.id}</span
									>
								</div>
								<button
									onclick={() => copyToClipboard(team!.id, 'id')}
									class="flex shrink-0 items-center gap-1.5 rounded-[var(--radius-button)] border px-3 py-1.5 text-meta font-semibold transition-all duration-150
										{copiedId
										? 'border-[var(--color-accent)]/40 bg-[var(--color-accent-glow-mid)] text-[var(--color-accent-mid)]'
										: 'border-[var(--color-border-mid)] text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]'}"
								>
									{#if copiedId}
										<svg
											width="12"
											height="12"
											viewBox="0 0 24 24"
											fill="none"
											stroke="currentColor"
											stroke-width="2.5"
											stroke-linecap="round"
											stroke-linejoin="round"
										>
											<polyline points="20 6 9 17 4 12" />
										</svg>
										Copied
									{:else}
										<svg
											width="12"
											height="12"
											viewBox="0 0 24 24"
											fill="none"
											stroke="currentColor"
											stroke-width="2"
											stroke-linecap="round"
											stroke-linejoin="round"
										>
											<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
											<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
										</svg>
										Copy
									{/if}
								</button>
							</div>
						</div>
					</section>

					<!-- ── Members ── -->
					<section class="mb-8">
						<div class="mb-4 flex items-center justify-between">
							<div>
								<h2
									class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]"
								>
									Members
								</h2>
								<p class="mt-0.5 text-meta text-[var(--color-text-tertiary)]">
									{members.length}
									{members.length === 1 ? 'member' : 'members'}
								</p>
							</div>
							{#if canManage}
								<button
									onclick={() => {
										showAddMember = true;
										addEmail = '';
										searchResults = [];
										showResults = false;
										addError = null;
									}}
									class="flex items-center gap-2 rounded-[var(--radius-button)] bg-[var(--color-accent)] px-4 py-2 text-ui font-semibold text-white transition-all duration-150 hover:brightness-115 hover:-translate-y-px active:translate-y-0"
								>
									<svg
										width="13"
										height="13"
										viewBox="0 0 24 24"
										fill="none"
										stroke="currentColor"
										stroke-width="2.5"
										stroke-linecap="round"
										stroke-linejoin="round"
									>
										<line x1="12" y1="5" x2="12" y2="19" />
										<line x1="5" y1="12" x2="19" y2="12" />
									</svg>
									Add Member
								</button>
							{/if}
						</div>

						<div
							class="overflow-hidden rounded-[var(--radius-card)] border border-[var(--color-border)]"
						>
							<!-- Table header -->
							<div
								class="grid grid-cols-[1fr_120px_140px_120px] border-b border-[var(--color-border)] bg-[var(--color-bg-3)]"
							>
								<div
									class="px-5 py-3 text-label font-semibold uppercase tracking-[0.05em] text-[var(--color-text-muted)]"
								>
									Member
								</div>
								<div
									class="px-4 py-3 text-label font-semibold uppercase tracking-[0.05em] text-[var(--color-text-muted)]"
								>
									Role
								</div>
								<div
									class="px-4 py-3 text-label font-semibold uppercase tracking-[0.05em] text-[var(--color-text-muted)]"
								>
									Joined
								</div>
								<div
									class="px-4 py-3 text-label font-semibold uppercase tracking-[0.05em] text-[var(--color-text-muted)]"
								></div>
							</div>

							{#each members as member, i (member.user_id)}
								<div
									class="grid grid-cols-[1fr_120px_140px_120px] items-center border-b border-[var(--color-border)] transition-colors duration-150 hover:bg-[var(--color-bg-3)] last:border-b-0"
									style="animation: fadeUp 0.35s ease both; animation-delay: {i * 40}ms"
								>
									<!-- Email -->
									<div class="min-w-0 px-5 py-4">
										<span class="block truncate text-ui text-[var(--color-text-bright)]"
											>{member.email}</span
										>
										{#if member.user_id === auth.userId}
											<span class="text-meta text-[var(--color-text-muted)]">you</span>
										{/if}
									</div>

									<!-- Role badge -->
									<div class="px-4 py-4">
										{#if updatingRoleId === member.user_id}
											<svg
												class="animate-spin text-[var(--color-text-tertiary)]"
												width="14"
												height="14"
												viewBox="0 0 24 24"
												fill="none"
												stroke="currentColor"
												stroke-width="2"
											>
												<path d="M21 12a9 9 0 1 1-6.219-8.56" />
											</svg>
										{:else}
											<span
												class="inline-flex items-center rounded-[3px] px-2 py-0.5 text-badge font-semibold uppercase tracking-[0.06em]
													{member.role === 'owner'
													? 'bg-[var(--color-accent-glow-mid)] text-[var(--color-accent-mid)]'
													: member.role === 'admin'
														? 'bg-[var(--color-bg-5)] text-[var(--color-text-secondary)]'
														: 'bg-[var(--color-bg-4)] text-[var(--color-text-muted)]'}"
											>
												{roleLabel(member.role)}
											</span>
										{/if}
									</div>

									<!-- Joined date -->
									<div class="px-4 py-4">
										<span class="text-ui text-[var(--color-text-secondary)]"
											>{formatDate(member.joined_at)}</span
										>
									</div>

									<!-- Actions: split button -->
									<div class="flex items-center justify-end px-3 py-3">
										{#if canActOn(member)}
											<div
												class="split-btn-container relative flex items-stretch overflow-hidden rounded-[var(--radius-button)] border border-[var(--color-border-mid)] bg-[var(--color-bg-3)]"
											>
												<!-- Primary: Remove -->
												<button
													onclick={() => {
														removeTarget = member;
														removeError = null;
													}}
													class="flex items-center px-3 py-1.5 text-meta font-medium text-[var(--color-text-primary)] transition-colors duration-150 hover:bg-[var(--color-bg-4)] hover:text-[var(--color-red)]"
												>
													Remove
												</button>
												<!-- Divider -->
												<div class="w-px shrink-0 bg-[var(--color-border-mid)]"></div>
												<!-- Chevron: Make Admin / Make Member -->
												<button
													onclick={(e) => {
														e.stopPropagation();
														if (openDropdownId === member.user_id) {
															openDropdownId = null;
														} else {
															const rect = (
																e.currentTarget as HTMLElement
															).getBoundingClientRect();
															dropdownPos = {
																top: rect.bottom + 4,
																left: rect.right - 140
															};
															openDropdownId = member.user_id;
														}
													}}
													class="flex items-center px-2 py-1.5 text-[var(--color-text-secondary)] transition-colors duration-150 hover:bg-[var(--color-bg-4)] hover:text-[var(--color-text-bright)]"
												>
													<svg
														class="transition-transform duration-150 {openDropdownId === member.user_id
															? 'rotate-180'
															: ''}"
														width="12"
														height="12"
														viewBox="0 0 24 24"
														fill="none"
														stroke="currentColor"
														stroke-width="2.5"
														stroke-linecap="round"
														stroke-linejoin="round"
													>
														<polyline points="6 9 12 15 18 9" />
													</svg>
												</button>
											</div>
										{/if}
									</div>
								</div>
							{/each}
						</div>
					</section>

					<!-- ── Danger Zone ── -->
					<section>
						<div
							class="rounded-[var(--radius-card)] border border-[var(--color-red)]/25 bg-[var(--color-red)]/[0.03]"
						>
							<div class="border-b border-[var(--color-red)]/15 px-5 py-4">
								<h2
									class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]"
								>
									Danger Zone
								</h2>
							</div>
							<div class="flex items-center justify-between gap-6 px-5 py-4">
								{#if myRole === 'owner'}
									<div>
										<p class="text-ui font-medium text-[var(--color-text-primary)]">
											Delete this team
										</p>
										<p class="mt-0.5 text-meta text-[var(--color-text-tertiary)]">
											{#if isLastTeam}Create another team before deleting this one.{:else}Permanently deletes the team and destroys all running capsules. This cannot be undone.{/if}
										</p>
									</div>
									<button
										onclick={() => { showDangerConfirm = true; dangerError = null; }}
										disabled={isLastTeam}
										class="shrink-0 rounded-[var(--radius-button)] border px-4 py-2 text-ui font-semibold transition-all duration-150 {isLastTeam ? 'cursor-not-allowed border-[var(--color-border)] text-[var(--color-text-muted)] opacity-50' : 'border-[var(--color-red)]/40 text-[var(--color-red)] hover:bg-[var(--color-red)]/10 hover:border-[var(--color-red)]/60'}"
									>
										Delete Team
									</button>
								{:else}
									<div>
										<p class="text-ui font-medium text-[var(--color-text-primary)]">
											Leave this team
										</p>
										<p class="mt-0.5 text-meta text-[var(--color-text-tertiary)]">
											{#if isLastTeam}Create another team before leaving this one.{:else}You will lose access to all capsules and resources belonging to this team.{/if}
										</p>
									</div>
									<button
										onclick={() => { showDangerConfirm = true; dangerError = null; }}
										disabled={isLastTeam}
										class="shrink-0 rounded-[var(--radius-button)] border px-4 py-2 text-ui font-semibold transition-all duration-150 {isLastTeam ? 'cursor-not-allowed border-[var(--color-border)] text-[var(--color-text-muted)] opacity-50' : 'border-[var(--color-red)]/40 text-[var(--color-red)] hover:bg-[var(--color-red)]/10 hover:border-[var(--color-red)]/60'}"
									>
										Leave Team
									</button>
								{/if}
							</div>
						</div>
					</section>
				{/if}
			</div>
		</main>

		<footer class="h-px shrink-0 bg-[var(--color-border)]"></footer>
	</div>
</div>

<!-- Split button dropdown -->
{#if openDropdownId}
	{@const dropdownMember = members.find((m) => m.user_id === openDropdownId)}
	{#if dropdownMember}
		<div
			class="fixed z-50 w-36 overflow-hidden rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] py-1"
			style="top: {dropdownPos.top}px; left: {dropdownPos.left}px; animation: fadeUp 0.15s ease both"
		>
			{#if dropdownMember.role === 'member'}
				<button
					onclick={(e) => {
						e.stopPropagation();
						handleUpdateRole(dropdownMember, 'admin');
					}}
					class="flex w-full items-center gap-2 px-3 py-2 text-meta text-[var(--color-text-primary)] transition-colors duration-150 hover:bg-[var(--color-bg-3)]"
				>
					<svg
						width="13"
						height="13"
						viewBox="0 0 24 24"
						fill="none"
						stroke="currentColor"
						stroke-width="2"
						stroke-linecap="round"
						stroke-linejoin="round"
						class="shrink-0 text-[var(--color-text-secondary)]"
					>
						<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
					</svg>
					Make Admin
				</button>
			{:else if dropdownMember.role === 'admin'}
				<button
					onclick={(e) => {
						e.stopPropagation();
						handleUpdateRole(dropdownMember, 'member');
					}}
					class="flex w-full items-center gap-2 px-3 py-2 text-meta text-[var(--color-text-primary)] transition-colors duration-150 hover:bg-[var(--color-bg-3)]"
				>
					<svg
						width="13"
						height="13"
						viewBox="0 0 24 24"
						fill="none"
						stroke="currentColor"
						stroke-width="2"
						stroke-linecap="round"
						stroke-linejoin="round"
						class="shrink-0 text-[var(--color-text-secondary)]"
					>
						<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
						<circle cx="12" cy="7" r="4" />
					</svg>
					Make Member
				</button>
			{/if}
		</div>
	{/if}
{/if}

<!-- Add Member Dialog -->
{#if showAddMember}
	<div class="fixed inset-0 z-50 flex items-center justify-center">
		<!-- svelte-ignore a11y_no_static_element_interactions -->
		<div
			class="absolute inset-0 bg-black/60"
			onclick={() => {
				if (!adding) {
					showAddMember = false;
				}
			}}
			onkeydown={(e) => {
				if (e.key === 'Escape' && !adding) showAddMember = false;
			}}
		></div>

		<div
			class="relative w-full max-w-[400px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6"
			style="animation: fadeUp 0.2s ease both"
		>
			<h2
				class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]"
			>
				Add Member
			</h2>
			<p class="mt-1 text-ui text-[var(--color-text-tertiary)]">
				Add an existing Wrenn user to your team by email.
			</p>

			{#if addError}
				<div
					class="mt-4 rounded-[var(--radius-input)] border border-[var(--color-red)]/30 bg-[var(--color-red)]/5 px-3 py-2 text-meta text-[var(--color-red)]"
				>
					{addError}
				</div>
			{/if}

			<div class="mt-5">
				<label
					class="mb-1.5 block text-label font-semibold uppercase tracking-[0.05em] text-[var(--color-text-tertiary)]"
					for="add-email"
				>
					Email address
				</label>
				<div class="search-container relative">
					<div class="relative">
						<input
							id="add-email"
							type="email"
							placeholder="colleague@example.com"
							bind:value={addEmail}
							oninput={handleSearchInput}
							onkeydown={(e) => {
								if (e.key === 'Enter' && !adding) handleAddMember();
							}}
							disabled={adding}
							class="w-full rounded-[var(--radius-input)] border border-[var(--color-border)] bg-[var(--color-bg-4)] px-3 py-2 text-ui text-[var(--color-text-bright)] outline-none placeholder:text-[var(--color-text-muted)] transition-colors duration-150 focus:border-[var(--color-accent)] disabled:opacity-60"
						/>
						{#if searchLoading}
							<div class="absolute right-2.5 top-1/2 -translate-y-1/2">
								<svg
									class="animate-spin text-[var(--color-text-tertiary)]"
									width="14"
									height="14"
									viewBox="0 0 24 24"
									fill="none"
									stroke="currentColor"
									stroke-width="2"
								>
									<path d="M21 12a9 9 0 1 1-6.219-8.56" />
								</svg>
							</div>
						{/if}
					</div>

					<!-- Typeahead results -->
					{#if showResults && searchResults.length > 0}
						<div
							class="absolute left-0 right-0 top-full z-10 mt-1 overflow-hidden rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] py-1"
							style="animation: fadeUp 0.15s ease both"
						>
							{#each searchResults as result (result.user_id)}
								<button
									onclick={() => selectSearchResult(result)}
									class="flex w-full items-center gap-2.5 px-3 py-2 text-ui transition-colors duration-150 hover:bg-[var(--color-bg-3)]"
								>
									<div
										class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-[var(--color-bg-5)] text-badge font-bold uppercase text-[var(--color-text-secondary)]"
									>
										{result.email[0]}
									</div>
									<span class="min-w-0 truncate text-[var(--color-text-primary)]"
										>{result.email}</span
									>
								</button>
							{/each}
						</div>
					{/if}
				</div>
			</div>

			<div class="mt-6 flex justify-end gap-3">
				<button
					onclick={() => {
						showAddMember = false;
					}}
					disabled={adding}
					class="rounded-[var(--radius-button)] border border-[var(--color-border)] px-4 py-2 text-ui text-[var(--color-text-secondary)] transition-colors duration-150 hover:border-[var(--color-border-mid)] hover:text-[var(--color-text-primary)] disabled:opacity-50"
				>
					Cancel
				</button>
				<button
					onclick={handleAddMember}
					disabled={adding || !addEmail.trim()}
					class="flex items-center gap-2 rounded-[var(--radius-button)] bg-[var(--color-accent)] px-5 py-2 text-ui font-semibold text-white transition-all duration-150 hover:brightness-115 hover:-translate-y-px active:translate-y-0 disabled:opacity-50 disabled:hover:translate-y-0"
				>
					{#if adding}
						<svg
							class="animate-spin"
							width="13"
							height="13"
							viewBox="0 0 24 24"
							fill="none"
							stroke="currentColor"
							stroke-width="2"
						>
							<path d="M21 12a9 9 0 1 1-6.219-8.56" />
						</svg>
						Adding...
					{:else}
						Add Member
					{/if}
				</button>
			</div>
		</div>
	</div>
{/if}

<!-- Remove Member Confirmation Dialog -->
{#if removeTarget}
	<div class="fixed inset-0 z-50 flex items-center justify-center">
		<!-- svelte-ignore a11y_no_static_element_interactions -->
		<div
			class="absolute inset-0 bg-black/60"
			onclick={() => {
				if (!removing) removeTarget = null;
			}}
			onkeydown={(e) => {
				if (e.key === 'Escape' && !removing) removeTarget = null;
			}}
		></div>

		<div
			class="relative w-full max-w-[380px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6"
			style="animation: fadeUp 0.2s ease both"
		>
			<h2
				class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]"
			>
				Remove Member
			</h2>
			<p class="mt-2 text-ui text-[var(--color-text-tertiary)]">
				Remove <span class="font-medium text-[var(--color-text-secondary)]"
					>{removeTarget.email}</span
				> from the team? They will lose access immediately.
			</p>

			{#if removeError}
				<div
					class="mt-4 rounded-[var(--radius-input)] border border-[var(--color-red)]/30 bg-[var(--color-red)]/5 px-3 py-2 text-meta text-[var(--color-red)]"
				>
					{removeError}
				</div>
			{/if}

			<div class="mt-6 flex justify-end gap-3">
				<button
					onclick={() => {
						removeTarget = null;
					}}
					disabled={removing}
					class="rounded-[var(--radius-button)] border border-[var(--color-border)] px-4 py-2 text-ui text-[var(--color-text-secondary)] transition-colors duration-150 hover:border-[var(--color-border-mid)] hover:text-[var(--color-text-primary)] disabled:opacity-50"
				>
					Cancel
				</button>
				<button
					onclick={handleRemoveMember}
					disabled={removing}
					class="flex items-center gap-2 rounded-[var(--radius-button)] bg-[var(--color-red)] px-5 py-2 text-ui font-semibold text-white transition-all duration-150 hover:brightness-115 hover:-translate-y-px active:translate-y-0 disabled:opacity-50 disabled:hover:translate-y-0"
				>
					{#if removing}
						<svg
							class="animate-spin"
							width="13"
							height="13"
							viewBox="0 0 24 24"
							fill="none"
							stroke="currentColor"
							stroke-width="2"
						>
							<path d="M21 12a9 9 0 1 1-6.219-8.56" />
						</svg>
						Removing...
					{:else}
						Remove
					{/if}
				</button>
			</div>
		</div>
	</div>
{/if}

<!-- Danger Zone Confirmation Dialog -->
{#if showDangerConfirm}
	<div class="fixed inset-0 z-50 flex items-center justify-center">
		<!-- svelte-ignore a11y_no_static_element_interactions -->
		<div
			class="absolute inset-0 bg-black/60"
			onclick={() => {
				if (!dangerLoading) showDangerConfirm = false;
			}}
			onkeydown={(e) => {
				if (e.key === 'Escape' && !dangerLoading) showDangerConfirm = false;
			}}
		></div>

		<div
			class="relative w-full max-w-[400px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6"
			style="animation: fadeUp 0.2s ease both"
		>
			{#if myRole === 'owner'}
				<h2
					class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]"
				>
					Delete Team
				</h2>
				<p class="mt-2 text-ui text-[var(--color-text-tertiary)]">
					This will permanently delete <span class="font-medium text-[var(--color-text-secondary)]"
						>{team?.name}</span
					> and destroy all running capsules. This action cannot be undone.
				</p>
			{:else}
				<h2
					class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]"
				>
					Leave Team
				</h2>
				<p class="mt-2 text-ui text-[var(--color-text-tertiary)]">
					You will lose access to all capsules and resources in <span
						class="font-medium text-[var(--color-text-secondary)]">{team?.name}</span
					>.
				</p>
			{/if}

			<!-- Amber warning -->
			<div
				class="mt-4 flex items-start gap-2 rounded-[var(--radius-input)] border border-[var(--color-amber)]/20 bg-[var(--color-amber)]/5 px-3 py-2.5"
			>
				<svg
					class="mt-0.5 shrink-0"
					width="13"
					height="13"
					viewBox="0 0 24 24"
					fill="none"
					stroke="var(--color-amber)"
					stroke-width="2"
					stroke-linecap="round"
					stroke-linejoin="round"
				>
					<path
						d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"
					/>
					<line x1="12" y1="9" x2="12" y2="13" />
					<line x1="12" y1="17" x2="12.01" y2="17" />
				</svg>
				<p class="text-meta leading-relaxed text-[var(--color-amber)]">
					{#if myRole === 'owner'}
						All team data, API keys, and running capsules will be permanently destroyed.
					{:else}
						You'll need a new invitation to rejoin this team.
					{/if}
				</p>
			</div>

			{#if dangerError}
				<div
					class="mt-4 rounded-[var(--radius-input)] border border-[var(--color-red)]/30 bg-[var(--color-red)]/5 px-3 py-2 text-meta text-[var(--color-red)]"
				>
					{dangerError}
				</div>
			{/if}

			<div class="mt-6 flex justify-end gap-3">
				<button
					onclick={() => {
						showDangerConfirm = false;
					}}
					disabled={dangerLoading}
					class="rounded-[var(--radius-button)] border border-[var(--color-border)] px-4 py-2 text-ui text-[var(--color-text-secondary)] transition-colors duration-150 hover:border-[var(--color-border-mid)] hover:text-[var(--color-text-primary)] disabled:opacity-50"
				>
					Cancel
				</button>
				<button
					onclick={handleDangerAction}
					disabled={dangerLoading}
					class="flex items-center gap-2 rounded-[var(--radius-button)] bg-[var(--color-red)] px-5 py-2 text-ui font-semibold text-white transition-all duration-150 hover:brightness-115 hover:-translate-y-px active:translate-y-0 disabled:opacity-50 disabled:hover:translate-y-0"
				>
					{#if dangerLoading}
						<svg
							class="animate-spin"
							width="13"
							height="13"
							viewBox="0 0 24 24"
							fill="none"
							stroke="currentColor"
							stroke-width="2"
						>
							<path d="M21 12a9 9 0 1 1-6.219-8.56" />
						</svg>
					{/if}
					{myRole === 'owner' ? 'Delete Team' : 'Leave Team'}
				</button>
			</div>
		</div>
	</div>
{/if}
