<script lang="ts">
	import { page } from '$app/state';
	import { api, type OrgMember } from '$lib/api';
	import { session } from '$lib/session';
	import { resolveOrg } from '$lib/org';
	import { fmtDate } from '$lib/format';
	import { ORG_ROLES, ORG_ROLE_LABELS, PERMISSION_ROLE_LABELS } from '$lib/constants';
	import PageHeader from '$lib/components/PageHeader.svelte';
	import LoadingState from '$lib/components/LoadingState.svelte';
	import ErrorBanner from '$lib/components/ErrorBanner.svelte';
	import EmptyState from '$lib/components/EmptyState.svelte';
	import SelectField from '$lib/components/SelectField.svelte';
	import { toastError, toastSuccess } from '$lib/toast';

	const org = $derived(resolveOrg($session.me, page.url.search));
	const slug = $derived(org?.slug ?? '');
	const roleItems = ORG_ROLES.map((r) => ({ value: r, label: ORG_ROLE_LABELS[r] }));
	const permHint = Object.values(PERMISSION_ROLE_LABELS).join(' / ');

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

	let newOpenId = $state('');
	let newName = $state('');
	let newRole = $state<string>('MEMBER');
	let adding = $state(false);

	async function load() {
		loading = true;
		error = null;
		try {
			const res = await api.members(slug);
			members = res.members;
		} catch (err) {
			error = err instanceof Error ? err.message : String(err);
		} finally {
			loading = false;
		}
	}

	async function addMember() {
		if (!newOpenId.trim()) return;
		adding = true;
		try {
			const m = await api.addMember(slug, {
				feishuOpenId: newOpenId.trim(),
				role: newRole,
				...(newName.trim() ? { displayName: newName.trim() } : {}),
			});
			members = [...members, m].sort((a, b) => a.role.localeCompare(b.role) || a.createdAt.localeCompare(b.createdAt));
			newOpenId = '';
			newName = '';
			toastSuccess('成员已添加');
		} catch (err) {
			toastError(err instanceof Error ? err.message : String(err));
		} finally {
			adding = false;
		}
	}

	async function changeRole(m: OrgMember, role: string) {
		try {
			await api.setMemberRole(slug, m.userId, role);
			await load();
			toastSuccess('角色已更新');
		} catch (err) {
			toastError(err instanceof Error ? err.message : String(err));
		}
	}

	async function revoke(m: OrgMember) {
		if (!confirm(`移除成员 ${m.displayName} 出本组织?`)) return;
		try {
			await api.revokeMember(slug, m.userId);
			await load();
			toastSuccess('成员已移除');
		} catch (err) {
			toastError(err instanceof Error ? err.message : String(err));
		}
	}

	$effect(() => {
		if (slug) load();
	});
</script>

<PageHeader title="成员与权限" description="管理组织角色：所有者与管理员可访问本后台，成员不可。" />

{#if loading}
	<LoadingState />
{:else if error}
	<ErrorBanner message={error} onretry={load} />
{:else}
	<div class="saas-card-pad mb-6">
		<h2 class="saas-section-title mb-4">添加成员</h2>
		<div class="grid gap-3 md:grid-cols-[1.2fr_1fr_12rem_auto]">
			<input class="saas-input" placeholder="飞书 open_id" bind:value={newOpenId} />
			<input class="saas-input" placeholder="显示名（可选）" bind:value={newName} />
			<SelectField items={roleItems} bind:value={newRole} />
			<button class="saas-btn-primary" onclick={addMember} disabled={adding}>
				{adding ? '添加中…' : '添加成员'}
			</button>
		</div>
	</div>

	<div class="saas-card overflow-hidden">
		<div class="flex items-center justify-between border-b border-surface-200 px-5 py-3">
			<h2 class="text-sm font-semibold">成员列表</h2>
			<span class="saas-badge-neutral">{members.length}</span>
		</div>
		{#if members.length === 0}
			<EmptyState title="暂无成员" description="使用上方表单按飞书 open_id 添加成员。" />
		{:else}
			<div class="overflow-x-auto">
				<table class="data-table">
					<thead>
						<tr>
							<th>用户</th>
							<th>open_id</th>
							<th>组织角色</th>
							<th>加入时间</th>
							<th></th>
						</tr>
					</thead>
					<tbody>
						{#each members as m}
							<tr>
								<td>
									<div class="flex items-center gap-2.5">
										{#if m.avatarUrl}
											<img src={m.avatarUrl} alt="" class="h-7 w-7 border border-surface-300 object-cover" />
										{:else}
											<div
												class="flex h-7 w-7 items-center justify-center border border-primary-300 bg-primary-100 text-xs font-semibold text-primary-800"
											>
												{m.displayName.slice(0, 1)}
											</div>
										{/if}
										<span class="font-medium">{m.displayName}</span>
									</div>
								</td>
								<td class="font-mono text-xs text-surface-700">{m.feishuOpenId}</td>
								<td class="min-w-36">
									<SelectField
										items={roleItems}
										value={m.role}
										onchange={(role) => {
											if (role !== m.role) changeRole(m, role);
										}}
									/>
								</td>
								<td class="text-surface-700">{fmtDate(m.createdAt)}</td>
								<td class="text-right">
									<button class="saas-btn-danger py-1! text-sm" onclick={() => revoke(m)}>移除</button>
								</td>
							</tr>
						{/each}
					</tbody>
				</table>
			</div>
		{/if}
		<p class="border-t border-surface-300 px-5 py-3 text-xs text-surface-600">
			组织角色控制后台访问；项目级权限由「项目」页团队授权（{permHint}）决定。
		</p>
	</div>
{/if}
