<script lang="ts">
	import { Users, X, UserPlus, Copy, Check } from '@lucide/svelte';
	import { Button } from '$lib/components/ui/button';
	import * as Card from '$lib/components/ui/card';
	import { toast } from 'svelte-sonner';
	import { companyStore } from '$lib/stores/company.svelte';
	import { usersAPI, type User } from '$lib/api/dashboard/users';
	import { rolesAPI, type CompanyRole } from '$lib/api/dashboard/admin/roles';
	import { userRolesAPI, type UserRole } from '$lib/api/dashboard/admin/user-roles';

	const inputCls =
		'rounded-md border bg-transparent px-2 py-1 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring';

	const companyId = $derived(companyStore.activeCompany?.id ?? null);

	let users = $state<User[]>([]);
	let roles = $state<CompanyRole[]>([]);
	let assignments = $state<UserRole[]>([]);
	let loading = $state(true);
	let busy = $state<string | null>(null);

	// Alta de usuario por invitación
	let inviteEmail = $state('');
	let inviteRoleId = $state<number | null>(null);
	let inviting = $state(false);
	let inviteUrl = $state<string | null>(null);
	let copied = $state(false);

	// user_id → asignaciones de rol
	const rolesByUser = $derived.by(() => {
		const m: Record<string, UserRole[]> = {};
		for (const a of assignments) (m[String(a.user_id)] ??= []).push(a);
		return m;
	});

	function fullName(u: User): string {
		const n = `${u.first_name ?? ''} ${u.last_name ?? ''}`.trim();
		return n || u.username || u.email || u.id;
	}

	async function load() {
		if (!companyId) {
			loading = false;
			return;
		}
		loading = true;
		try {
			const [uRes, rRes, arRes] = await Promise.all([
				usersAPI.list(companyId, { page_size: 100 }).catch(() => ({ users: [] as User[] })),
				rolesAPI.list(companyId, { page_size: 100 }),
				userRolesAPI.list(companyId, { page_size: 500 }).catch(() => ({ items: [] as UserRole[] } as any))
			]);
			users = uRes.users ?? [];
			roles = rRes.data?.items ?? [];
			assignments = arRes.items ?? [];
		} catch {
			toast.error('No se pudieron cargar los usuarios');
		} finally {
			loading = false;
		}
	}

	// Recarga al cambiar la compañía activa —incluida la hidratación inicial tras
	// refrescar (antes no cargaba hasta re-seleccionar la compañía).
	$effect(() => {
		const id = companyId;
		if (id) {
			void load();
		} else {
			users = [];
			loading = false;
		}
	});

	async function assignRole(user: User, roleIdRaw: string) {
		if (!companyId) return;
		const roleId = Number(roleIdRaw);
		if (!roleId) return;
		if (rolesByUser[String(user.id)]?.some((a) => a.company_role_id === roleId)) {
			toast.info('El usuario ya tiene ese rol');
			return;
		}
		busy = `assign:${user.id}`;
		try {
			await userRolesAPI.assign(companyId, { user_id: String(user.id), company_role_id: roleId });
			toast.success('Rol asignado');
			await load();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo asignar el rol');
		} finally {
			busy = null;
		}
	}

	async function removeRole(a: UserRole) {
		if (!companyId) return;
		busy = `remove:${a.id}`;
		try {
			await userRolesAPI.remove(a.id, companyId);
			toast.success('Rol removido');
			await load();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo remover el rol');
		} finally {
			busy = null;
		}
	}

	async function inviteUser() {
		if (!companyId) return;
		const email = inviteEmail.trim();
		if (!email || !email.includes('@')) {
			toast.error('Ingresa un email válido');
			return;
		}
		if (!inviteRoleId) {
			toast.error('Selecciona el rol del usuario');
			return;
		}
		inviting = true;
		inviteUrl = null;
		try {
			const res = await usersAPI.invite({ email, company_id: companyId, role_id: inviteRoleId });
			toast.success('Invitación creada');
			inviteUrl = res.invite_url ?? null;
			inviteEmail = '';
			await load();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo dar de alta el usuario');
		} finally {
			inviting = false;
		}
	}

	async function copyInvite() {
		if (!inviteUrl) return;
		try {
			await navigator.clipboard.writeText(inviteUrl);
			copied = true;
			toast.success('Enlace copiado');
			setTimeout(() => (copied = false), 2000);
		} catch {
			toast.error('No se pudo copiar');
		}
	}
</script>

<div class="space-y-6">
	<div>
		<h1 class="flex items-center gap-2 text-2xl font-bold tracking-tight">
			<Users class="h-6 w-6" /> Usuarios
		</h1>
		<p class="mt-1 text-sm text-muted-foreground">
			Usuarios de la compañía activa y sus roles. Para dar de alta usuarios nuevos usa Workspace → Usuarios (invitaciones).
		</p>
	</div>

	{#if !companyId}
		<Card.Root><Card.Content class="pt-6 text-sm text-muted-foreground">Selecciona una compañía activa.</Card.Content></Card.Root>
	{:else}
		<Card.Root>
			<Card.Header>
				<Card.Title class="flex items-center gap-2"><UserPlus class="h-4 w-4" /> Dar de alta usuario</Card.Title>
				<Card.Description>Se envía una invitación por email; el usuario crea su contraseña y queda en la compañía con el rol elegido.</Card.Description>
			</Card.Header>
			<Card.Content>
				<div class="grid gap-4 sm:grid-cols-3">
					<label class="flex flex-col gap-1 text-sm sm:col-span-2">
						<span class="font-medium">Email *</span>
						<input type="email" class={inputCls} bind:value={inviteEmail} placeholder="persona@empresa.com" />
					</label>
					<label class="flex flex-col gap-1 text-sm">
						<span class="font-medium">Rol *</span>
						<select class={inputCls} bind:value={inviteRoleId}>
							<option value={null} disabled>Selecciona…</option>
							{#each roles as r (r.id)}<option value={r.id}>{r.name}</option>{/each}
						</select>
					</label>
				</div>
				<div class="mt-4 flex items-center justify-between gap-2">
					{#if roles.length === 0}
						<span class="text-xs text-muted-foreground">Primero crea roles en "Roles y permisos".</span>
					{:else}<span></span>{/if}
					<Button onclick={inviteUser} disabled={inviting || roles.length === 0}>{inviting ? 'Enviando…' : 'Invitar / dar de alta'}</Button>
				</div>
				{#if inviteUrl}
					<div class="mt-3 flex items-center gap-2 rounded-md border bg-muted/40 p-2">
						<span class="whitespace-nowrap text-xs text-muted-foreground">Si el correo no llega, comparte:</span>
						<input class="flex-1 font-mono text-xs {inputCls}" readonly value={inviteUrl} />
						<Button variant="outline" size="sm" onclick={copyInvite}>{#if copied}<Check class="h-4 w-4" />{:else}<Copy class="h-4 w-4" />{/if}</Button>
					</div>
				{/if}
			</Card.Content>
		</Card.Root>

		<Card.Root>
			<Card.Header>
				<Card.Title>Usuarios ({users.length})</Card.Title>
				<Card.Description>Asigna o quita roles (los roles se definen en Roles y permisos).</Card.Description>
			</Card.Header>
			<Card.Content>
				{#if loading}
					<p class="text-sm text-muted-foreground">Cargando…</p>
				{:else if users.length === 0}
					<p class="text-sm text-muted-foreground">No hay usuarios en esta compañía todavía.</p>
				{:else}
					<div class="overflow-x-auto">
						<table class="w-full text-sm">
							<thead class="text-left text-muted-foreground">
								<tr class="border-b">
									<th class="py-2 pr-4 font-medium">Usuario</th>
									<th class="py-2 pr-4 font-medium">Email</th>
									<th class="py-2 pr-4 font-medium">Roles</th>
									<th class="py-2 pr-4 font-medium">Asignar rol</th>
								</tr>
							</thead>
							<tbody>
								{#each users as u (u.id)}
									<tr class="border-b last:border-0 align-top">
										<td class="py-2 pr-4">{fullName(u)}</td>
										<td class="py-2 pr-4 text-muted-foreground">{u.email ?? '—'}</td>
										<td class="py-2 pr-4">
											<div class="flex flex-wrap gap-1">
												{#each rolesByUser[String(u.id)] ?? [] as a (a.id)}
													<span class="inline-flex items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-xs text-primary">
														{a.company_role?.name ?? a.company_role?.code ?? `rol ${a.company_role_id}`}
														<button type="button" class="hover:text-destructive" disabled={busy === `remove:${a.id}`} onclick={() => removeRole(a)} title="Quitar rol"><X class="h-3 w-3" /></button>
													</span>
												{:else}
													<span class="text-xs text-muted-foreground">sin rol</span>
												{/each}
											</div>
										</td>
										<td class="py-2 pr-4">
											<select
												class={inputCls}
												disabled={busy === `assign:${u.id}` || roles.length === 0}
												onchange={(e) => { const el = e.currentTarget as HTMLSelectElement; assignRole(u, el.value); el.value = ''; }}
											>
												<option value="">+ rol…</option>
												{#each roles as r (r.id)}<option value={r.id}>{r.name}</option>{/each}
											</select>
										</td>
									</tr>
								{/each}
							</tbody>
						</table>
					</div>
				{/if}
			</Card.Content>
		</Card.Root>
	{/if}
</div>
