<script lang="ts">
	import { onMount } from 'svelte';
	import { getSupabase } from '$lib/supabase';
	import { currentUser } from '$lib/stores/auth';
	import { currentCollective, collectiveMembers } from '$lib/stores/collective';
	import Avatar from '$lib/components/Avatar.svelte';
	import * as m from '$lib/paraglide/messages';

	type Member = {
		user_id: string;
		role: 'admin' | 'member' | 'guest';
		display_name: string;
		avatar_type: 'initials' | 'emoji' | 'upload';
		avatar_emoji: string | null;
		avatar_url: string | null;
	};

	let members = $state<Member[]>([]);
	let loading = $state(true);
	let error = $state<string | null>(null);

	let inviteRole = $state<'member' | 'guest'>('member');
	let generatedLink = $state<string | null>(null);
	let generating = $state(false);
	let copied = $state(false);

	const myRole = $derived(members.find((m) => m.user_id === $currentUser?.id)?.role);
	const isAdmin = $derived(myRole === 'admin');

	onMount(async () => {
		await loadMembers();
	});

	async function loadMembers() {
		if (!$currentCollective) return;
		loading = true;

		const { data, error: fetchError } = await getSupabase()
			.from('collective_members')
			.select(`
				user_id, role,
				users(display_name, avatar_type, avatar_emoji, avatar_url)
			`)
			.eq('collective_id', $currentCollective.id)
			.order('joined_at');

		if (fetchError) {
			error = fetchError.message;
			loading = false;
			return;
		}

		members = (data ?? []).map((row) => {
			const u = row.users as { display_name: string; avatar_type: string; avatar_emoji: string | null; avatar_url: string | null } | null;
			return {
				user_id: row.user_id,
				role: row.role as Member['role'],
				display_name: u?.display_name ?? '',
				avatar_type: (u?.avatar_type ?? 'initials') as Member['avatar_type'],
				avatar_emoji: u?.avatar_emoji ?? null,
				avatar_url: u?.avatar_url ?? null
			};
		});
		collectiveMembers.set(members.map((m) => ({ ...m, collective_id: $currentCollective!.id })));
		loading = false;
	}

	async function changeRole(userId: string, newRole: 'admin' | 'member' | 'guest') {
		if (!$currentCollective) return;
		const { error: updateError } = await getSupabase()
			.from('collective_members')
			.update({ role: newRole })
			.eq('collective_id', $currentCollective.id)
			.eq('user_id', userId);

		if (updateError) {
			error = updateError.message;
			return;
		}
		members = members.map((m) => m.user_id === userId ? { ...m, role: newRole } : m);
	}

	async function removeMember(userId: string) {
		if (!$currentCollective) return;
		const { error: deleteError } = await getSupabase()
			.from('collective_members')
			.delete()
			.eq('collective_id', $currentCollective.id)
			.eq('user_id', userId);

		if (deleteError) {
			error = deleteError.message;
			return;
		}
		members = members.filter((m) => m.user_id !== userId);
	}

	async function generateInviteLink() {
		if (!$currentCollective) return;
		generating = true;
		generatedLink = null;

		const { data, error: insertError } = await getSupabase()
			.from('collective_invitations')
			.insert({
				collective_id: $currentCollective.id,
				role: inviteRole,
				created_by: $currentUser!.id
			})
			.select('token')
			.single();

		if (insertError || !data) {
			error = insertError?.message ?? 'Failed to generate link.';
			generating = false;
			return;
		}

		generatedLink = `${window.location.origin}/invitation/${data.token}`;
		generating = false;
	}

	async function copyLink() {
		if (!generatedLink) return;
		await navigator.clipboard.writeText(generatedLink);
		copied = true;
		setTimeout(() => (copied = false), 2000);
	}

	const ROLES: Array<'admin' | 'member' | 'guest'> = ['admin', 'member', 'guest'];

	function roleLabel(role: 'admin' | 'member' | 'guest'): string {
		if (role === 'admin') return m.role_admin();
		if (role === 'member') return m.role_member();
		return m.role_guest();
	}
</script>

<div class="flex flex-1 flex-col overflow-hidden">
<div class="flex-1 overflow-y-auto">
<div class="px-8 pb-4 pt-8">
	<p class="mb-1 text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">
		{m.nav_collective()}
	</p>
	<h1 class="text-[20px] font-semibold tracking-[-0.01em] text-slate-900 dark:text-slate-50">
		{m.manage_title()}
	</h1>
</div>
<div class="px-8 py-6">

	{#if error}
		<p class="mb-4 text-sm text-red-600">{error}</p>
	{/if}

	<!-- Members list — no dividers, vertical padding creates separation -->
	<section class="mb-8">
		<h2 class="mb-4 text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">
			{m.manage_members()}
		</h2>

		{#if loading}
			<p class="text-sm text-text-secondary">{m.loading()}</p>
		{:else}
			<ul>
				{#each members as member}
					<li class="flex items-center gap-3 py-3">
						<Avatar
							name={member.display_name}
							type={member.avatar_type}
							emoji={member.avatar_emoji}
							src={member.avatar_url}
							size={36}
						/>
						<div class="min-w-0 flex-1">
							<p class="truncate text-sm font-medium text-slate-900 dark:text-slate-50">
								{member.display_name}
								{#if member.user_id === $currentUser?.id}
									<span class="ml-1 text-text-secondary">({m.manage_you()})</span>
								{/if}
							</p>
						</div>

						{#if isAdmin && member.user_id !== $currentUser?.id}
							<select
								value={member.role}
								onchange={(e) => changeRole(member.user_id, e.currentTarget.value as Member['role'])}
								class="rounded-md border border-slate-300 bg-surface px-2 py-1 text-xs
									dark:border-slate-600 dark:bg-slate-800"
							>
								{#each ROLES as r}
									<option value={r}>{roleLabel(r)}</option>
								{/each}
							</select>
							<button
								onclick={() => removeMember(member.user_id)}
								class="rounded-md p-1.5 text-slate-400 hover:bg-red-50 hover:text-red-600
									dark:hover:bg-red-900/20"
								aria-label={m.manage_remove()}
							>✕</button>
						{:else}
							<span class="rounded-md bg-slate-100 px-2 py-1 text-xs text-slate-600
								dark:bg-slate-700 dark:text-slate-400">
								{roleLabel(member.role)}
							</span>
						{/if}
					</li>
				{/each}
			</ul>
		{/if}
	</section>

	<!-- Invite link generator — background shift instead of border -->
	{#if isAdmin}
		<section class="rounded-lg bg-surface-container-low p-4 dark:bg-surface-raised">
			<h2 class="mb-3 text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">
				{m.manage_invite_title()}
			</h2>

			<div class="mb-3 flex items-center gap-2">
				<label for="invite-role" class="text-sm text-slate-700 dark:text-slate-300">{m.manage_invite_role()}</label>
				<select
					id="invite-role"
					bind:value={inviteRole}
					class="rounded-md border border-slate-300 bg-surface px-2 py-1 text-sm
						dark:border-slate-600 dark:bg-slate-800"
				>
					<option value="member">{m.role_member()}</option>
					<option value="guest">{m.role_guest()}</option>
				</select>
			</div>

			<button
				onclick={generateInviteLink}
				disabled={generating}
				class="mb-3 w-full rounded-lg bg-slate-900 px-4 py-2 text-sm font-semibold text-white
					hover:opacity-90 disabled:opacity-50 dark:bg-slate-50 dark:text-slate-900"
			>
				{generating ? m.loading() : m.manage_generate_link()}
			</button>

			{#if generatedLink}
				<div class="flex items-center gap-2 rounded-lg bg-surface p-2 dark:bg-surface-raised">
					<code class="min-w-0 flex-1 truncate text-xs text-slate-600 dark:text-slate-400">
						{generatedLink}
					</code>
					<button
						onclick={copyLink}
						class="flex-shrink-0 rounded-md px-2 py-1 text-xs font-medium text-slate-700
							hover:bg-slate-200 dark:text-slate-300 dark:hover:bg-slate-700"
					>
						{copied ? m.manage_copied() : m.manage_copy()}
					</button>
				</div>
				<p class="mt-1 text-xs text-text-secondary">{m.manage_link_expires()}</p>
			{/if}
		</section>
	{/if}
</div>
</div>
</div>
