<script lang="ts">
	import { page } from '$app/state';
	import { api, type AgentRoleRow, type AgentModelRow, type AgentSkillRow } from '$lib/api';
	import { session } from '$lib/session';
	import { resolveOrg } from '$lib/org';
	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 RoleCard from '$lib/components/RoleCard.svelte';
	import { toastError, toastSuccess } from '$lib/toast';

	const org = $derived(resolveOrg($session.me, page.url.search));
	const slug = $derived(org?.slug ?? '');

	let roles = $state<AgentRoleRow[]>([]);
	let models = $state<AgentModelRow[]>([]);
	let skills = $state<AgentSkillRow[]>([]);
	let loading = $state(true);
	let error = $state<string | null>(null);

	let newRoleId = $state('');
	let newLabel = $state('');
	let adding = $state(false);

	async function load() {
		loading = true;
		error = null;
		try {
			const [r, s] = await Promise.all([api.agentRoles(slug), api.agentSkills(slug)]);
			roles = r.roles;
			skills = s.skills;
			// Model fetch hits the provider API and may fail or be slow; load it
			// independently so roles remain editable even without a model list.
			models = [];
			api.agentModels(slug)
				.then((m) => { models = m.models; })
				.catch((err) => { toastError(`模型列表加载失败：${err instanceof Error ? err.message : String(err)}`); });
		} catch (err) {
			error = err instanceof Error ? err.message : String(err);
		} finally {
			loading = false;
		}
	}

	async function add() {
		const roleId = newRoleId.trim();
		const label = newLabel.trim();
		if (roleId === '' || label === '') {
			toastError('角色 ID 与显示名均为必填');
			return;
		}
		if (roles.some((r) => r.roleId === roleId)) {
			toastError(`角色 ID 已存在：${roleId}`);
			return;
		}
		adding = true;
		try {
			const created = await api.upsertAgentRole(slug, roleId, { label });
			roles = [...roles, created];
			newRoleId = '';
			newLabel = '';
			toastSuccess('角色已创建');
		} catch (err) {
			toastError(err instanceof Error ? err.message : String(err));
		} finally {
			adding = false;
		}
	}

	function onRoleUpdated(updated: AgentRoleRow) {
		roles = roles.map((x) => (x.roleId === updated.roleId ? { ...updated, skillNames: x.skillNames } : x));
		if (updated.isDefault) {
			roles = roles.map((x) => (x.roleId === updated.roleId ? x : { ...x, isDefault: false }));
		}
	}

	function onRoleSkillsChanged(roleId: string, skillNames: string[]) {
		roles = roles.map((x) => (x.roleId === roleId ? { ...x, skillNames } : x));
	}

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

<PageHeader
	title="角色"
	description="角色是组织级数据：组合默认模型、系统提示词、工具白名单与已绑定技能。角色 ID 即飞书斜杠命令（如 /draft）。"
/>

{#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 sm:grid-cols-[10rem_1fr_auto]">
			<input
				class="saas-input font-mono text-sm"
				placeholder="角色 ID（如 draft）"
				bind:value={newRoleId}
				onkeydown={(e) => {
					if (e.key === 'Enter') add();
				}}
			/>
			<input
				class="saas-input"
				placeholder="显示名（如 草稿）"
				bind:value={newLabel}
				onkeydown={(e) => {
					if (e.key === 'Enter') add();
				}}
			/>
			<button class="saas-btn-primary" onclick={add} disabled={adding}>新建</button>
		</div>
		<p class="mt-2 text-xs text-surface-600">角色 ID 仅允许小写字母、数字、下划线与连字符，且以字母或数字开头。</p>
	</div>

	{#if roles.length === 0}
		<div class="saas-card">
			<EmptyState title="暂无角色" description="组织必须且只能有一个启用中的默认角色；新建第一个角色将自动成为默认。" />
		</div>
	{:else}
		<div class="space-y-4">
			{#each roles as r (r.roleId)}
				<RoleCard {r} {models} {skills} {slug} onupdated={onRoleUpdated} onskillschanged={onRoleSkillsChanged} />
			{/each}
		</div>
	{/if}
{/if}
