<script lang="ts">
	import { usersAPI, type User, type UserStats, type InviteUserResponse } from '$lib/api/dashboard/users';
	import { userRolesAPI, type UserRole } from '$lib/api/dashboard/admin/user-roles';
	import { rolesAPI, type CompanyRole } from '$lib/api/dashboard/admin/roles';
	import {
		rolePermissionsAPI,
		type RolePermission
	} from '$lib/api/dashboard/admin/role-permissions';
	import { permissionsAPI, type Permission } from '$lib/api/dashboard/admin/permissions';
	import {
		userPermissionsAPI,
		type UserPermission,
		type EffectiveUserPermissions
	} from '$lib/api/dashboard/admin/user-permissions';
	import ErrorState from '$lib/components/dashboard/common/error-state.svelte';
	import { companyStore } from '$lib/stores/company.svelte';
	import * as Card from '$lib/components/ui/card';
	import * as Dialog from '$lib/components/ui/dialog';
	import * as AlertDialog from '$lib/components/ui/alert-dialog';
	import * as Table from '$lib/components/ui/table';
	import * as Tabs from '$lib/components/ui/tabs';
	import { Button } from '$lib/components/ui/button';
	import { Input } from '$lib/components/ui/input';
	import { Label } from '$lib/components/ui/label';
	import { Textarea } from '$lib/components/ui/textarea';
	import { Switch } from '$lib/components/ui/switch';
	import * as Select from '$lib/components/ui/select';
	import * as Tooltip from '$lib/components/ui/tooltip';
	import { Badge } from '$lib/components/ui/badge';
	import { Checkbox } from '$lib/components/ui/checkbox';
	import {
		Plus,
		Pencil,
		Trash2,
		Key,
		UserCheck,
		UserX,
		Search,
		RefreshCw,
		Users,
		AlertCircle,
		Shield,
		ArrowLeft,
		Check
	} from 'lucide-svelte';
	import { toast } from 'svelte-sonner';
	import { refreshPermissions, currentUser, userHasPermission } from '$lib/auth';
	import { friendlyApiErrorParts } from '$lib/api';

	// --- PERMISOS ---
	const canView = $derived(userHasPermission($currentUser, 'user.view'));
	const canCreate = $derived(userHasPermission($currentUser, 'user.create'));
	const canDelete = $derived(userHasPermission($currentUser, 'user.delete'));
	const canManage = $derived(userHasPermission($currentUser, 'user.manage'));

	// Permissions for Roles module
	const canViewRoles = $derived(userHasPermission($currentUser, 'roles.view'));
	const canCreateRoles = $derived(userHasPermission($currentUser, 'roles.create'));
	const canEditRoles = $derived(userHasPermission($currentUser, 'roles.edit'));
	const canDeleteRoles = $derived(userHasPermission($currentUser, 'roles.delete'));

	/** Pestaña "Roles y Permisos": plantillas de rol; alineado con backend (no solo roles.view). */
	const canAccessRolesTab = $derived(
		userHasPermission($currentUser, 'roles.view') ||
			userHasPermission($currentUser, 'user.manage') ||
			userHasPermission($currentUser, 'user.update')
	);

	/** Ver/editar datos del usuario (contraseña, perfil). Requiere update o manage, no basta user.view. */
	const canEditUserProfile = $derived(
		userHasPermission($currentUser, 'user.update') ||
			userHasPermission($currentUser, 'user.manage')
	);

	/**
	 * Gestionar roles/permisos de un usuario (escudo). Alineado con API: update, manage o roles.view.
	 * Nota: la lista de usuarios solo exige user.view; sin update/manage/roles.view estos botones quedan deshabilitados.
	 */
	const canManageUserRoles = $derived(
		userHasPermission($currentUser, 'user.update') ||
			userHasPermission($currentUser, 'user.manage') ||
			userHasPermission($currentUser, 'roles.view')
	);

	/** Prefijos de código ocultos en UI (pickers, heredados del rol, etc.; siguen en BD). */
	const HIDDEN_ASSIGNMENT_PERMISSION_PREFIXES = ['frac_american.'] as const;

	function isHiddenAssignmentPermission(p: { code: string }): boolean {
		return HIDDEN_ASSIGNMENT_PERMISSION_PREFIXES.some((prefix) => p.code.startsWith(prefix));
	}

	// ============================================================================
	// HELPERS PARA FORMATEO DE PERMISOS
	// ============================================================================

	/**
	 * Traduce nombres de módulos a español
	 */
	function getModuleLabel(module: string): string {
		const moduleLabels: Record<string, string> = {
			audit_logs: 'Bitacora',
			reference_data: 'Catalogos fijos',
			general_catalogs: 'Catalogos generales',
			fractions: 'Fracciones',
			transports: 'Transportes',
			goods: 'Mercancias',
			pedimentos: 'Pedimentos',
			invoice_imp: 'Facturas de importacion',
			invoice_exp: 'Factura de exportacion',
			export: 'Exportacion',
			partners: 'Clientes y proveedores',
			brokers: 'Agentes aduanales',
			reports: 'Reportes',
			settings: 'Configuracion',
			users: 'Usuarios',
			help: 'Ayuda',
			csv_upload: 'Carga CSV'
		};
		return moduleLabels[module.toLowerCase()] || module.charAt(0).toUpperCase() + module.slice(1);
	}

	/**
	 * Traduce acciones a español
	 */
	function getActionLabel(action: string): string {
		const actionLabels: Record<string, string> = {
			view: 'Ver',
			create: 'Crear',
			edit: 'Editar',
			update: 'Actualizar',
			delete: 'Eliminar',
			list: 'Listar',
			read: 'Leer',
			write: 'Escribir',
			manage: 'Gestionar',
			process: 'Procesar',
			approve: 'Aprobar',
			reject: 'Rechazar',
			export: 'Exportar',
			import: 'Importar',
			download: 'Descargar',
			upload: 'Subir',
			generate: 'Generar',
			send: 'Enviar',
			receive: 'Recibir'
		};
		return actionLabels[action.toLowerCase()] || action.charAt(0).toUpperCase() + action.slice(1);
	}

	/**
	 * Traduce recursos específicos de catálogos generales
	 */
	function getSubModuleLabel(resource: string): string {
		const labels: Record<string, string> = {
			cat_company: 'Informacion de la empresa',
			cat_packages: 'Bultos',
			cat_concepts: 'Conceptos',
			cat_broker_concepts: 'Conceptos de agente aduanal',
			cat_classification: 'Clasifcacion',
			cat_identifiers: 'Identificadores',
			cat_incoterms: 'Incoterms',
			cat_inpc: 'I.N.P.C',
			cat_legends: 'Leyendas fijas',
			cat_seals: 'Precitno',
			cat_valuation: 'Metodos de valoracion',
			cat_countries: 'Paises',
			cat_ports: 'Puertos',
			cat_um_general: 'Unidades de medida',
			cat_um_customs: 'UM Aduanas MX',
			cat_um_american: 'UM Aduanas USA',
			cat_um_oma: 'UM OMA',
			cat_unit_conversions: 'Conversiones',
			cat_equivalencies: 'Equivalencias',
			cat_exchange_rates: 'Tipos de cambio',
			cat_currency: 'Tipos de moneda',
			cat_multi_currency_types: 'Tipos de Moneda (Múltiples)',
			cat_inv_types: 'Tipos de factura',
			cat_signatures: 'Firmas electronicas',
			cat_errors: 'Errores de facturacion',
			cat_warehouses: 'Recintos',
			cat_doda: 'DODA',
			cat_prevalidators: 'Prevalidadores',
			cat_notices: 'Avisos electronicos',
			cat_crossing: 'Aviso de cruce',
			frac_sitar: 'Fracciones SITAR',
			frac_sitar_7: 'FRacciones Sitar - 7ma',
			frac_sitar_us: 'Fracciones sitar US',
			frac_canadian: 'Fracciones Canadienses',
			frac_historical: 'Fracciones historicas',
			frac_sectors: 'Sectores',
			transporters: 'Transportistas',
			drivers: 'Conductores',
			trailers: 'Trailers',
			vehicles: 'Vehiculos',
			goods_classes: 'Clases',
			goods_part: 'Partes',
			goods_fda: 'Codigos F.D.A',
			pedimentos_mgmt: 'Gestion de pedimentos',
			pedimentos_codes: 'CLaves de pedimento',
			pedimentos_regimes: 'Regimenes aduaneros',
			pedimentos_payments: 'Formas de pago',
			pedimentos_sections: 'Secciones aduaneras',
			pedimentos_anexo22: 'Anexo 22 app 3',
			'invoice.imp.tem': 'Temporal',
			'invoice.imp.def': 'Definiitva',
			'invoice.imp.cm': 'Compras mexicanas',
			'invoice.imp.cr': 'Cambio de regimen',
			'invoice.imp.rep': 'Reparacion',
			'invoice.exp': 'Exportacion',
			'invoice.exp.rep': 'Reparacion',
			'user': 'Usuarios',
			'report': 'Reportes',
			'roles': 'Roles',
			export_catalog: 'Ctalogo de eportacion',
			export_repair: 'Reparacion',
			export_manifest: 'Manifiesto',
			export_proforma: 'Proforma',
			export_reports: 'Reportes',
			export_used: 'Modulod de materiales utilizados',
			export_destruction: 'Destruccion',
			export_special: 'procesos especiales'
		};
		return labels[resource] || resource;
	}

	/**
	 * Formatea un código de permiso en una etiqueta legible
	 * Ej: "invoice.exp.rep.process" -> "Facturas > Exportación > Reportes > Procesar"
	 */
	function formatPermissionLabel(permission: Permission): string {
		if (permission.description) {
			return permission.description;
		}

		// Dividir el código en partes
		const parts = permission.code.split('.');

		// Si solo tiene module.action, formatear simple
		if (parts.length === 2) {
			const [module, action] = parts;
			return `${getModuleLabel(module)} - ${getActionLabel(action)}`;
		}

		// Si tiene más partes, formatear jerárquicamente
		// La última parte es la acción, el resto son módulos/submódulos
		const action = parts[parts.length - 1];
		const modules = parts.slice(0, -1);

		const modulePath = modules.map((m) => getModuleLabel(m)).join(' › ');
		return `${modulePath} - ${getActionLabel(action)}`;
	}

	/**
	 * Obtiene una descripción corta del permiso para mostrar en tooltips
	 */
	function getPermissionHint(permission: Permission): string {
		return `Código: ${permission.code} | Módulo: ${permission.module} | Acción: ${permission.action}`;
	}
	function getActionColor(action: string): string {
		const act = action.toLowerCase();
		if (['view', 'read', 'list'].includes(act))
			return 'bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-900/30 dark:text-blue-400 dark:border-blue-800';
		if (['create', 'edit', 'update', 'write'].includes(act))
			return 'bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400 dark:border-emerald-800';
		if (['delete', 'revert'].includes(act))
			return 'bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-400 dark:border-red-800';
		if (['manage', 'process', 'approve', 'reject'].includes(act))
			return 'bg-amber-100 text-amber-700 border-amber-200 dark:bg-amber-900/30 dark:text-amber-400 dark:border-amber-800';
		return 'bg-secondary text-secondary-foreground border-border';
	}

	// Estados principales - Usuarios
	let users = $state<User[]>([]);
	let stats = $state<UserStats | null>(null);
	let loading = $state(false);
	let searchTerm = $state('');
	let currentPage = $state(1);
	let pageSize = $state(20);
	let totalPages = $state(1);

	// Diálogos
	let showCreateDialog = $state(false);
	let showEditDialog = $state(false);
	let showDeleteDialog = $state(false);
	let showPasswordDialog = $state(false);
	let showRolesDialog = $state(false);

	// Estado de invitación
	let showInviteDialog = $state(false);
	let inviteEmail = $state('');
	let inviteRoleId = $state<number>(0);
	let inviteLoading = $state(false);
	let inviteResult = $state<InviteUserResponse | null>(null);
	let inviteCopied = $state(false);

	async function sendInvite() {
		if (!inviteEmail || !companyStore.activeCompany?.id) return;
		inviteLoading = true;
		try {
			const res = await usersAPI.invite({
				email: inviteEmail,
				company_id: companyStore.activeCompany.id,
				role_id: inviteRoleId,
			});
			inviteResult = res;
			toast.success('Invitación generada correctamente');
		} catch (e: any) {
			toast.error(e.message || 'Error al generar invitación');
		} finally {
			inviteLoading = false;
		}
	}

	function copyInviteUrl() {
		if (!inviteResult) return;
		navigator.clipboard.writeText(inviteResult.invite_url);
		inviteCopied = true;
		setTimeout(() => (inviteCopied = false), 2000);
	}

	function closeInviteDialog() {
		showInviteDialog = false;
		inviteEmail = '';
		inviteRoleId = 0;
		inviteResult = null;
		inviteCopied = false;
	}

	// Estado de borrado multi-tenant
	let deleteUserTenantCount = $state(0);
	let deleteLoadingCount = $state(false);

	// Estados para gestión de roles
	let availableRoles = $state<CompanyRole[]>([]);
	let userRoles = $state<UserRole[]>([]);
	let loadingRoles = $state(false);
	let selectedRoleId = $state<number | string>(0);

	// Estados para permisos individuales de usuario
	let effectivePermissions = $state<EffectiveUserPermissions | null>(null);
	let loadingUserPermissions = $state(false);
	let showUserPermissionsDialog = $state(false);
	let showGrantUserPermDialog = $state(false);
	let availablePermissionsForUser = $state<Permission[]>([]);
	let selectedUserPermissionIds = $state<number[]>([]);

	// Roles disponibles que NO están asignados
	const unassignedRoles = $derived(
		availableRoles.filter((role) => !userRoles.some((ur) => ur.company_role_id === role.id))
	);

	// Usuario seleccionado para editar/eliminar
	let selectedUser = $state<User | null>(null);

	// Formulario de creación
	let createForm = $state({
		email: '',
		username: '',
		first_name: '',
		last_name: '',
		password: '',
		role: '',
		enabled: true,
		email_verified: false
	});

	// Formulario de edición
	let editForm = $state({
		first_name: '',
		last_name: '',
		email: '',
		enabled: true,
		email_verified: false,
		role: ''
	});

	// Formulario de cambio de contraseña
	let passwordForm = $state({
		password: '',
		confirmPassword: '',
		temporary: true
	});

	// Estados para Roles y Permisos
	let rolesState = $state<CompanyRole[]>([]);
	let selectedRoleForPermissions = $state<CompanyRole | null>(null);
	let rolePermissionsState = $state<RolePermission[]>([]);
	let allPermissionsState = $state<Permission[]>([]);
	let availablePermissionsState = $state<Permission[]>([]);
	let permissionsByModuleState = $state<Map<string, Permission[]>>(new Map());
	let loadingPermissionsState = $state(false);
	let showPermissionsDialog = $state(false);
	let showRoleDialog = $state(false);
	let showDeleteRoleDialog = $state(false);
	let roleToDelete = $state<CompanyRole | null>(null);
	let selectedPermissionIds = $state<number[]>([]);
	let permissionSearchQuery = $state('');
	let rolePermissionsSearchQuery = $state('');
	let userEffectiveSearchQuery = $state('');
	let userEffectiveModuleFilter = $state('');
	let userEffectiveActionFilter = $state('');

	// Estado de rediseño de UI de modales
	let selectedModuleForUserDialog = $state<string>('all');
	let selectedModuleForRoleDialog = $state<string>('all');
	let selectedSubModuleForUserDialog = $state<string>('all');
	let selectedSubModuleForRoleDialog = $state<string>('all');

	const generalCatalogsResources = [
		'cat_company',
		'cat_packages',
		'cat_concepts',
		'cat_broker_concepts',
		'cat_classification',
		'cat_identifiers',
		'cat_incoterms',
		'cat_inpc',
		'cat_legends',
		'cat_seals',
		'cat_valuation',
		'cat_countries',
		'cat_ports',
		'cat_um_general',
		'cat_um_customs',
		'cat_um_american',
		'cat_um_oma',
		'cat_unit_conversions',
		'cat_equivalencies',
		'cat_exchange_rates',
		'cat_currency',
		'cat_multi_currency_types',
		'cat_inv_types',
		'cat_signatures',
		'cat_errors',
		'cat_warehouses',
		'cat_doda',
		'cat_prevalidators',
		'cat_notices',
		'cat_crossing'
	];

	const fractionsResources = [
		'frac_sitar',
		'frac_sitar_7',
		'frac_sitar_us',
		'frac_canadian',
		'frac_historical',
		'frac_sectors'
	];

	const transportsResources = [
		'transporters', 'drivers', 'trailers', 'vehicles'
	];

	const goodsResources = [
		'goods_classes', 'goods_parts', 'goods_fda'
	];

	const pedimentosResources = [
		'pedimentos_mgmt', 'pedimentos_codes', 'pedimentos_regimes', 
		'pedimentos_payments', 'pedimentos_sections', 'pedimentos_anexo22'
	];

	const invoiceImpResources = [
		'invoice.imp.tem', 'invoice.imp.def', 'invoice.imp.cm', 'invoice.imp.cr', 'invoice.imp.rep'
	];

	const invoiceExpResources = [
		'invoice.exp', 'invoice.exp.rep'
	];

	const exportResources = [
		'export_catalog', 'export_repair', 'export_manifest', 'export_proforma',
		'export_reports', 'export_used', 'export_destruction', 'export_special'
	];

	// No tienen sub-recursos mapeados externamente pero usaremos los prefijos de seed.py
	const userResources = ['user'];
	const reportResources = ['report'];
	const rolesResources = ['roles'];

	// Agrupaciones para el Sidebar del Modal
	const sidebarGroups = [
		{
			title: 'Navegación',
			keys: [
				'audit_logs',
				'reference_data',
				'general_catalogs',
				'fractions',
				'transports',
				'goods',
				'pedimentos',
				'invoice_imp',
				'invoice_exp',
				'export',
				'partners',
				'brokers',
				'reports',
				'settings',
				'users',
				'help',
				'csv_upload'
			]
		}
	];

	// Nueva Vista Embebida
	let managementView = $state<'list' | 'permissions'>('list');
	let manageTargetType = $state<'user' | 'role' | null>(null);

	function normalizeText(value: string | null | undefined): string {
		return (value || '').toLowerCase().trim();
	}

	function matchesPermissionQuery(
		permission: Permission | null | undefined,
		query: string | null | undefined
	): boolean {
		const q = normalizeText(query);
		if (!q) return true;
		if (!permission) return false;
		return (
			normalizeText(permission.code).includes(q) ||
			normalizeText(permission.description).includes(q) ||
			normalizeText(permission.module).includes(q) ||
			normalizeText(permission.action).includes(q)
		);
	}

	function matchesUserEffectiveModuleActionFilters(
		permission: Permission,
		moduleFilter: string,
		actionFilter: string
	): boolean {
		if (moduleFilter && permission.module !== moduleFilter) return false;
		if (actionFilter && permission.action !== actionFilter) return false;
		return true;
	}

	const userEffectivePermissionsUniverse = $derived.by(() => {
		const ep = effectivePermissions;
		if (!ep) return [] as Permission[];
		const seen = new Set<number>();
		const out: Permission[] = [];
		for (const p of [...ep.role_permissions, ...ep.granted_permissions, ...ep.revoked_permissions]) {
			if (isHiddenAssignmentPermission(p)) continue;
			if (seen.has(p.id)) continue;
			seen.add(p.id);
			out.push(p);
		}
		return out;
	});

	const userEffectiveModuleFilterItems = $derived.by(() => {
		const mods = new Set(userEffectivePermissionsUniverse.map((p) => p.module));
		const sorted = [...mods].sort();
		const items = sorted.map((m) => ({ value: m, label: getModuleLabel(m) }));
		return [{ value: '', label: 'Todos los módulos' }, ...items];
	});

	const userEffectiveActionFilterItems = $derived.by(() => {
		const actions = new Set(userEffectivePermissionsUniverse.map((p) => p.action));
		const sorted = [...actions].sort();
		const items = sorted.map((a) => ({ value: a, label: getActionLabel(a) }));
		return [{ value: '', label: 'Todas las acciones' }, ...items];
	});

	const userEffectiveActionsValidForModuleFilter = $derived.by(() => {
		const mod = userEffectiveModuleFilter;
		if (!mod) return null as Set<string> | null;
		return new Set(
			userEffectivePermissionsUniverse.filter((p) => p.module === mod).map((p) => p.action)
		);
	});

	const filteredRolePermissions = $derived(
		rolePermissionsState
			.filter((rp) => rp.permission && !isHiddenAssignmentPermission(rp.permission))
			.filter((rp) => matchesPermissionQuery(rp.permission, rolePermissionsSearchQuery))
	);

	const rolePermissionsVisibleCount = $derived(
		rolePermissionsState.filter(
			(rp) => rp.permission && !isHiddenAssignmentPermission(rp.permission)
		).length
	);

	const filteredGrantedPermissions = $derived(
		effectivePermissions?.granted_permissions
			.filter((perm) => !isHiddenAssignmentPermission(perm))
			.filter((perm) => matchesPermissionQuery(perm, userEffectiveSearchQuery))
			.filter((perm) =>
				matchesUserEffectiveModuleActionFilters(perm, userEffectiveModuleFilter, userEffectiveActionFilter)
			) || []
	);

	const filteredRevokedPermissions = $derived(
		effectivePermissions?.revoked_permissions
			.filter((perm) => !isHiddenAssignmentPermission(perm))
			.filter((perm) => matchesPermissionQuery(perm, userEffectiveSearchQuery))
			.filter((perm) =>
				matchesUserEffectiveModuleActionFilters(perm, userEffectiveModuleFilter, userEffectiveActionFilter)
			) || []
	);

	const filteredInheritedPermissions = $derived(
		effectivePermissions?.role_permissions
			.filter((perm) => !isHiddenAssignmentPermission(perm))
			.filter((perm) => matchesPermissionQuery(perm, userEffectiveSearchQuery))
			.filter((perm) =>
				matchesUserEffectiveModuleActionFilters(perm, userEffectiveModuleFilter, userEffectiveActionFilter)
			) || []
	);

	const effectiveGrantedVisibleCount = $derived(
		effectivePermissions?.granted_permissions.filter((p) => !isHiddenAssignmentPermission(p)).length ?? 0
	);
	const effectiveRevokedVisibleCount = $derived(
		effectivePermissions?.revoked_permissions.filter((p) => !isHiddenAssignmentPermission(p)).length ?? 0
	);
	const effectiveInheritedVisibleCount = $derived(
		effectivePermissions?.role_permissions.filter((p) => !isHiddenAssignmentPermission(p)).length ?? 0
	);

	const hasUserEffectiveSearchMatches = $derived(
		filteredGrantedPermissions.length > 0 ||
			filteredRevokedPermissions.length > 0 ||
			filteredInheritedPermissions.length > 0
	);

	const userEffectiveHasActiveListFilters = $derived(
		userEffectiveSearchQuery.trim() !== '' ||
			userEffectiveModuleFilter !== '' ||
			userEffectiveActionFilter !== ''
	);

	let modulesForUserDialog = $derived(
		(() => {
			const allKeys = sidebarGroups.flatMap((g) => g.keys);
			const map = new Map<string, Permission[]>();
			allKeys.forEach((k) => map.set(k, []));

			availablePermissionsForUser.forEach((p) => {
				if (!map.has(p.module)) map.set(p.module, []);
				map.get(p.module)!.push(p);
			});

			return [...map.entries()].map(([module, permissions]) => {
				const moduleSelectedCount = permissions.filter((p: Permission) =>
					selectedUserPermissionIds.includes(p.id)
				).length;
				return { module, permissions, moduleSelectedCount };
			});
		})()
	);

	let modulesForRoleDialog = $derived(
		(() => {
			const allKeys = sidebarGroups.flatMap((g) => g.keys);
			const map = new Map<string, Permission[]>();
			allKeys.forEach((k) => map.set(k, []));

			availablePermissionsState.forEach((p) => {
				if (!map.has(p.module)) map.set(p.module, []);
				map.get(p.module)!.push(p);
			});

			return [...map.entries()].map(([module, permissions]) => {
				const moduleSelectedCount = permissions.filter((p: Permission) =>
					selectedPermissionIds.includes(p.id)
				).length;
				return { module, permissions, moduleSelectedCount };
			});
		})()
	);

	let editingRole = $state<CompanyRole | null>(null);
	let roleFormData = $state({
		name: '',
		code: '',
		description: '',
		is_active: true
	});

	// Cargar estadísticas
	async function loadStats() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		try {
			stats = await usersAPI.getStats(companyId);
		} catch (error: any) {
			console.error('Error loading stats:', error);
			toast.error('Error al cargar estadísticas', {
				description: error.response?.data?.detail || error.message
			});
		}
	}

	// Cargar usuarios
	async function loadUsers() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		loading = true;
		try {
			const response = await usersAPI.list(companyId, {
				page: currentPage,
				page_size: pageSize,
				search: searchTerm || undefined
			});

			users = response.users;
			totalPages = response.total_pages;
		} catch (error: any) {
			console.error('Error loading users:', error);
			toast.error('Error al cargar usuarios', {
				description: error.response?.data?.detail || error.message
			});
		} finally {
			loading = false;
		}
	}

	// Buscar usuarios
	let searchTimeout: ReturnType<typeof setTimeout>;
	function handleSearch() {
		clearTimeout(searchTimeout);
		searchTimeout = setTimeout(() => {
			currentPage = 1;
			loadUsers();
		}, 500);
	}

	// Crear usuario
	async function handleCreate() {
		if (
			!createForm.email ||
			!createForm.username ||
			!createForm.first_name ||
			!createForm.last_name ||
			!createForm.password
		) {
			toast.error('Por favor complete todos los campos requeridos');
			return;
		}

		if (createForm.password.length < 8) {
			toast.error('La contraseña debe tener al menos 8 caracteres');
			return;
		}

		const companyId = companyStore.activeCompany?.id;
		if (!companyId) {
			toast.error('No hay compañía seleccionada');
			return;
		}

		try {
			await usersAPI.create(createForm, companyId);

			toast.success('Usuario creado exitosamente');
			showCreateDialog = false;
			resetCreateForm();
			await Promise.all([loadUsers(), loadStats()]);
		} catch (error: any) {
			console.error('Error creating user:', error);
			toast.error('Error al crear usuario', {
				description: error.response?.data?.detail || error.message
			});
		}
	}

	// Abrir diálogo de edición
	function openEditDialog(user: User) {
		selectedUser = user;
		editForm = {
			first_name: user.first_name,
			last_name: user.last_name,
			email: user.email,
			enabled: user.enabled,
			email_verified: user.email_verified,
			role: user.role || ''
		};
		showEditDialog = true;
	}

	// Actualizar usuario
	async function handleUpdate() {
		if (!selectedUser) return;

		const companyId = companyStore.activeCompany?.id;
		if (!companyId) {
			toast.error('No hay compañía seleccionada');
			return;
		}

		try {
			// Filtrar campos vacíos antes de enviar
			const updateData: any = {};
			if (editForm.first_name && editForm.first_name.trim()) {
				updateData.first_name = editForm.first_name.trim();
			}
			if (editForm.last_name && editForm.last_name.trim()) {
				updateData.last_name = editForm.last_name.trim();
			}
			if (editForm.email && editForm.email.trim()) {
				updateData.email = editForm.email.trim();
			}
			if (editForm.role !== undefined && editForm.role !== null) {
				updateData.role = editForm.role;
			}
			// Solo incluir enabled y email_verified si son diferentes del original
			if (editForm.enabled !== selectedUser.enabled) {
				updateData.enabled = editForm.enabled;
			}
			if (editForm.email_verified !== selectedUser.email_verified) {
				updateData.email_verified = editForm.email_verified;
			}

			await usersAPI.update(selectedUser.id, updateData, companyId);
			toast.success('Usuario actualizado exitosamente');
			showEditDialog = false;
			selectedUser = null;
			await loadUsers();
		} catch (error: any) {
			console.error('Error updating user:', error);
			toast.error('Error al actualizar usuario', {
				description: error.response?.data?.detail || error.message
			});
		}
	}

	// Abrir diálogo de eliminación
	async function openDeleteDialog(user: User) {
		selectedUser = user;
		deleteUserTenantCount = 0;
		deleteLoadingCount = true;
		showDeleteDialog = true;
		try {
			const companyId = companyStore.activeCompany?.id;
			if (companyId) {
				deleteUserTenantCount = await usersAPI.getTenantCount(user.id, companyId);
			}
		} catch {
			deleteUserTenantCount = 1;
		} finally {
			deleteLoadingCount = false;
		}
	}

	// Eliminar usuario
	async function handleDelete(
		softDelete: boolean = true,
		scope: 'current' | 'all' = 'current'
	) {
		if (!selectedUser) return;

		const companyId = companyStore.activeCompany?.id;
		if (!companyId) {
			toast.error('No hay compañía seleccionada');
			return;
		}

		try {
			await usersAPI.delete(selectedUser.id, companyId, softDelete, scope);
			const scopeMsg = scope === 'all' ? ' de todos los tenants' : '';
			toast.success(
				softDelete
					? `Usuario desactivado exitosamente${scopeMsg}`
					: `Usuario eliminado permanentemente${scopeMsg}`
			);
			showDeleteDialog = false;
			selectedUser = null;
			await Promise.all([loadUsers(), loadStats()]);
		} catch (error: any) {
			console.error('Error deleting user:', error);
			toast.error('Error al eliminar usuario', {
				description: error.response?.data?.detail || error.message
			});
		}
	}

	// Abrir diálogo de cambio de contraseña
	function openPasswordDialog(user: User) {
		selectedUser = user;
		passwordForm = {
			password: '',
			confirmPassword: '',
			temporary: true
		};
		showPasswordDialog = true;
	}

	// Cambiar contraseña
	async function handleChangePassword() {
		if (!selectedUser) return;

		if (passwordForm.password !== passwordForm.confirmPassword) {
			toast.error('Las contraseñas no coinciden');
			return;
		}

		if (passwordForm.password.length < 8) {
			toast.error('La contraseña debe tener al menos 8 caracteres');
			return;
		}

		const companyId = companyStore.activeCompany?.id;
		if (!companyId) {
			toast.error('No hay compañía seleccionada');
			return;
		}

		try {
			await usersAPI.changePassword(
				selectedUser.id,
				{
					password: passwordForm.password,
					temporary: passwordForm.temporary
				},
				companyId
			);
			toast.success('Contraseña actualizada exitosamente');
			showPasswordDialog = false;
			selectedUser = null;
			passwordForm = { password: '', confirmPassword: '', temporary: true };
		} catch (error: any) {
			console.error('Error changing password:', error);
			toast.error('Error al cambiar contraseña', {
				description: error.response?.data?.detail || error.message
			});
		}
	}
	// Gestión de roles
	async function openRolesDialog(user: User) {
		selectedUser = user;
		showRolesDialog = true;
		await Promise.all([loadUserRoles(), loadAvailableRoles(), loadUserEffectivePermissions()]);
	}

	async function loadAvailableRoles() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		try {
			const res = await rolesAPI.list(companyId, { is_active: true });
			if (res.error) {
				console.error('Error al cargar roles disponibles:', res.error);
				return;
			}
			availableRoles = res.data?.items || [];
		} catch (error) {
			console.error('Error al cargar roles disponibles:', error);
		}
	}

	async function loadUserRoles() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId || !selectedUser) return;

		try {
			loadingRoles = true;
			const response = await userRolesAPI.list(companyId, { user_id: selectedUser.id });
			userRoles = response.items;
		} catch (error: any) {
			console.error('Error loading user roles:', error);
		} finally {
			loadingRoles = false;
		}
	}

	async function assignRole() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId || !selectedUser || !selectedRoleId || selectedRoleId === 0) {
			toast.error('Selecciona un rol');
			return;
		}

		try {
			const roleId = typeof selectedRoleId === 'string' ? parseInt(selectedRoleId) : selectedRoleId;
			await userRolesAPI.assign(companyId, {
				user_id: selectedUser.id,
				company_role_id: roleId
			});
			toast.success('Rol asignado correctamente');
			selectedRoleId = 0;
			await refreshPermissions();
			await loadUserRoles();
			await loadUsers(); // Actualizar la tabla de usuarios
		} catch (error: any) {
			console.error('Error assigning role:', error);
			if (error.response?.status === 409) {
				toast.error('El usuario ya tiene este rol asignado');
			} else {
				toast.error('Error al asignar rol', {
					description: error.response?.data?.detail || error.message
				});
			}
		}
	}

	async function removeRole(userRoleId: number) {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		try {
			await userRolesAPI.remove(userRoleId, companyId);
			toast.success('Rol removido correctamente');
			await refreshPermissions();
			await loadUserRoles();
			await loadUsers(); // Actualizar la tabla de usuarios
		} catch (error: any) {
			console.error('Error removing role:', error);
			toast.error('Error al remover rol');
		}
	}

	// ============================================================================
	// FUNCIONES PARA PERMISOS INDIVIDUALES
	// ============================================================================

	async function loadUserEffectivePermissions() {
		if (!selectedUser) return;
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		try {
			loadingUserPermissions = true;
			effectivePermissions = await userPermissionsAPI.getEffective(selectedUser.id, companyId);
		} catch (error) {
			toast.error('Error al cargar permisos del usuario');
			console.error(error);
		} finally {
			loadingUserPermissions = false;
		}
	}

	function openUserPermissionsDialog() {
		if (!effectivePermissions) return;

		// Permisos disponibles son todos los permisos que no están:
		// - Ya concedidos individualmente
		// - Ya revocados individualmente
		const grantedIds = new Set(effectivePermissions.granted_permissions.map((p) => p.id));
		const revokedIds = new Set(effectivePermissions.revoked_permissions.map((p) => p.id));

		availablePermissionsForUser = allPermissionsState.filter(
			(p) => !grantedIds.has(p.id) && !revokedIds.has(p.id)
		);

		selectedUserPermissionIds = [];
		userEffectiveSearchQuery = '';
		userEffectiveModuleFilter = '';
		userEffectiveActionFilter = '';
		showUserPermissionsDialog = true;
	}

	function openGrantUserPermDialog() {
		if (!effectivePermissions) return;

		// Mostrar todos los permisos del sistema
		availablePermissionsForUser = [...allPermissionsState];

		// Pre-seleccionar los que ya tiene concedidos individualmente
		selectedUserPermissionIds = effectivePermissions.granted_permissions.map((p) => p.id);
		
		permissionSearchQuery = '';

		// Cambiar a vista embebida
		manageTargetType = 'user';
		managementView = 'permissions';
		selectedModuleForUserDialog = 'all';
	}

	async function handleGrantUserPermissions() {
		if (!selectedUser || !effectivePermissions) return;
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		const userId = selectedUser.id;
		const currentIds = new Set(effectivePermissions.granted_permissions.map(p => p.id));
		const newIds = new Set(selectedUserPermissionIds);

		const toGrant = selectedUserPermissionIds.filter(id => !currentIds.has(id));
		const toRemove = Array.from(currentIds).filter(id => !newIds.has(id));

		if (toGrant.length === 0 && toRemove.length === 0) {
			managementView = 'list';
			return;
		}

		try {
			// Conceder nuevos
			if (toGrant.length > 0) {
				await Promise.all(toGrant.map(id => userPermissionsAPI.grant(userId, companyId, id)));
			}
			
			// Remover quitados
			if (toRemove.length > 0) {
				await Promise.all(toRemove.map(id => userPermissionsAPI.remove(userId, companyId, id)));
			}

			toast.success('Permisos actualizados correctamente');
			managementView = 'list';
			selectedUserPermissionIds = [];
			await refreshPermissions();
			await loadUserEffectivePermissions();
		} catch (error) {
			toast.error('Error al actualizar permisos');
			console.error(error);
		}
	}

	async function handleRevokeUserPermission(permissionId: number) {
		if (!selectedUser) return;
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		try {
			await userPermissionsAPI.revoke(selectedUser.id, companyId, permissionId);
			toast.success('Permiso revocado');
			await refreshPermissions();
			await loadUserEffectivePermissions();
		} catch (error) {
			toast.error('Error al revocar permiso');
			console.error(error);
		}
	}

	async function handleRemoveUserPermission(permissionId: number) {
		if (!selectedUser) return;
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		try {
			await userPermissionsAPI.remove(selectedUser.id, companyId, permissionId);
			toast.success('Permiso individual eliminado');
			await refreshPermissions();
			await loadUserEffectivePermissions();
		} catch (error) {
			toast.error('Error al eliminar permiso');
			console.error(error);
		}
	}

	function toggleUserPermission(permId: number) {
		if (selectedUserPermissionIds.includes(permId)) {
			selectedUserPermissionIds = selectedUserPermissionIds.filter((id) => id !== permId);
		} else {
			selectedUserPermissionIds = [...selectedUserPermissionIds, permId];
		}
	}

	// Resetear formularios
	function resetCreateForm() {
		createForm = {
			email: '',
			username: '',
			first_name: '',
			last_name: '',
			password: '',
			role: '',
			enabled: true,
			email_verified: false
		};
	}

	// Cambiar página
	function goToPage(page: number) {
		if (page >= 1 && page <= totalPages) {
			currentPage = page;
			loadUsers();
		}
	}

	// ========================================
	// Funciones para Roles y Permisos
	// ========================================

	async function loadRolesTab() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		try {
			loadingRoles = true;
			const res = await rolesAPI.list(companyId);
			if (res.error) {
				toast.error(res.error);
				return;
			}
			rolesState = res.data?.items || [];
			if (rolesState.length > 0 && !selectedRoleForPermissions) {
				await selectRoleForPermissions(rolesState[0]);
			}
		} catch (error) {
			toast.error('Error al cargar roles');
			console.error(error);
		} finally {
			loadingRoles = false;
		}
	}

	async function loadAllPermissionsForRoles() {
		try {
			const response = await permissionsAPI.list({ page_size: 1000 });
			allPermissionsState = (response?.items || []).filter((p) => !isHiddenAssignmentPermission(p));
			if (selectedRoleForPermissions) {
				updateAvailablePermissionsForRole();
			}
		} catch (error) {
			toast.error('Error al cargar permisos');
			console.error(error);
		}
	}

	async function selectRoleForPermissions(role: CompanyRole) {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		selectedRoleForPermissions = role;
		rolePermissionsSearchQuery = '';
		loadingPermissionsState = true;

		try {
			const response = await rolePermissionsAPI.listByRole(role.id, companyId);
			rolePermissionsState = response.permissions;
			updateAvailablePermissionsForRole();
		} catch (error) {
			toast.error('Error al cargar permisos del rol');
			console.error(error);
		} finally {
			loadingPermissionsState = false;
		}
	}

	function updateAvailablePermissionsForRole() {
		const assignedIds = rolePermissionsState.map((rp) => rp.permission_id);
		availablePermissionsState = allPermissionsState.filter((p) => !assignedIds.includes(p.id));
		updatePermissionsByModuleForRole();
	}

	function updatePermissionsByModuleForRole() {
		const grouped = new Map<string, Permission[]>();

		const filtered = availablePermissionsState.filter((p) => {
			if (!permissionSearchQuery.trim()) return true;
			const search = permissionSearchQuery.toLowerCase();
			return (
				p.code.toLowerCase().includes(search) ||
				p.description?.toLowerCase().includes(search) ||
				p.action.toLowerCase().includes(search)
			);
		});

		filtered.forEach((p) => {
			if (!grouped.has(p.module)) {
				grouped.set(p.module, []);
			}
			grouped.get(p.module)!.push(p);
		});

		permissionsByModuleState = grouped;
	}

	function openAddPermissionsDialog() {
		// Mostrar todos los permisos en lugar de filtrar
		availablePermissionsState = [...allPermissionsState];
		
		// Pre-seleccionar los permisos que el rol ya tiene
		selectedPermissionIds = rolePermissionsState.map((rp) => rp.permission_id);
		
		permissionSearchQuery = '';

		// Cambiar a vista embebida
		manageTargetType = 'role';
		managementView = 'permissions';
		selectedModuleForRoleDialog = 'all';
	}

	function openCreateRoleDialog() {
		editingRole = null;
		roleFormData = { name: '', code: '', description: '', is_active: true };
		showRoleDialog = true;
	}

	function openEditRoleDialog(role: CompanyRole) {
		editingRole = role;
		roleFormData = {
			name: role.name,
			code: role.code,
			description: role.description || '',
			is_active: role.is_active
		};
		showRoleDialog = true;
	}

	async function handleRoleSubmit() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		try {
			if (editingRole) {
				const res = await rolesAPI.update(editingRole.id, companyId, roleFormData);
				if (res.error) {
					const { title, description } = friendlyApiErrorParts(res);
					toast.error(title, { description });
					return;
				}
				toast.success('Rol actualizado correctamente');
				if (selectedRoleForPermissions?.id === editingRole.id) {
					selectedRoleForPermissions = { ...selectedRoleForPermissions, ...roleFormData };
				}
			} else {
				const res = await rolesAPI.create(companyId, roleFormData);
				if (res.error) {
					const { title, description } = friendlyApiErrorParts(res);
					toast.error(title, { description });
					return;
				}
				toast.success('Rol creado correctamente');
				selectedRoleForPermissions = res.data || null;
			}
			showRoleDialog = false;
			await loadRolesTab();
			await loadAvailableRoles(); // También recargar roles para el diálogo de asignación
		} catch (error: any) {
			toast.error('Error procesando la solicitud');
			console.error(error);
		}
	}

	async function handleDeleteRole(role: CompanyRole) {
		roleToDelete = role;
		showDeleteRoleDialog = true;
	}

	async function confirmDeleteRole() {
		if (!roleToDelete) return;
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		try {
			const res = await rolesAPI.delete(roleToDelete.id, companyId);
			if (res.error) {
				toast.error(res.error);
				return;
			}

			// Limpiar estado si el rol eliminado estaba seleccionado
			if (selectedRoleForPermissions?.id === roleToDelete.id) {
				selectedRoleForPermissions = null;
				rolePermissionsState = [];
			}

			showDeleteRoleDialog = false;
			const deletedRoleId = roleToDelete.id;
			roleToDelete = null;

			// Recargar listas
			await Promise.all([loadRolesTab(), loadAvailableRoles()]);

			// Verificar que el rol ya no esté en la lista
			rolesState = rolesState.filter((r) => r.id !== deletedRoleId);

			toast.success('Rol eliminado permanentemente');
		} catch (error: any) {
			// Manejar error específico cuando el rol tiene usuarios asignados
			if (error?.response?.data?.detail) {
				toast.error(error.response.data.detail);
			} else {
				toast.error('Error al eliminar el rol');
			}
			console.error(error);
		}
	}

	async function handleAssignPermissions() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId || !selectedRoleForPermissions || selectedPermissionIds.length === 0) return;

		try {
			await rolePermissionsAPI.assignMultiple(
				selectedRoleForPermissions.id,
				companyId,
				selectedPermissionIds
			);
			toast.success('Permisos asignados correctamente');
			showPermissionsDialog = false;
			managementView = 'list';
			await refreshPermissions();
			await selectRoleForPermissions(selectedRoleForPermissions);
		} catch (error) {
			toast.error('Error al asignar permisos');
			console.error(error);
		}
	}

	async function handleRemovePermission(permissionId: number) {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId || !selectedRoleForPermissions) return;
		if (!confirm('¿Estás seguro de remover este permiso?')) return;

		try {
			await rolePermissionsAPI.remove(selectedRoleForPermissions.id, permissionId, companyId);
			toast.success('Permiso removido correctamente');
			await refreshPermissions();
			await selectRoleForPermissions(selectedRoleForPermissions);
		} catch (error) {
			toast.error('Error al remover permiso');
			console.error(error);
		}
	}

	function togglePermission(permissionId: number) {
		if (selectedPermissionIds.includes(permissionId)) {
			selectedPermissionIds = selectedPermissionIds.filter((id) => id !== permissionId);
		} else {
			selectedPermissionIds = [...selectedPermissionIds, permissionId];
		}
	}

	function handlePermissionToggle(permission: Permission) {
		if (manageTargetType === 'user') {
			if (selectedUserPermissionIds.includes(permission.id)) {
				selectedUserPermissionIds = selectedUserPermissionIds.filter((id) => id !== permission.id);
			} else {
				selectedUserPermissionIds = [...selectedUserPermissionIds, permission.id];
			}
		} else {
			if (selectedPermissionIds.includes(permission.id)) {
				selectedPermissionIds = selectedPermissionIds.filter((id) => id !== permission.id);
			} else {
				selectedPermissionIds = [...selectedPermissionIds, permission.id];
			}
		}
	}

	function handleBulkSelection(action: 'select' | 'deselect') {
		const targetModule = manageTargetType === 'user' ? selectedModuleForUserDialog : selectedModuleForRoleDialog;
		const targetSub = manageTargetType === 'user' ? selectedSubModuleForUserDialog : selectedSubModuleForRoleDialog;
		const search = permissionSearchQuery.toLowerCase();

		const subModuleParents = [
			'general_catalogs', 'fractions', 'transports', 'goods',
			'pedimentos', 'invoice_imp', 'invoice_exp', 'export', 'users', 'reports', 'roles'
		];

		const visiblePermissions = allPermissionsState.filter((p) => {
			// Filtro de módulo
			if (targetModule !== 'all' && p.module !== targetModule) return false;

			// Filtro de sub-módulo jerárquico
			if (targetSub !== 'all' && subModuleParents.includes(p.module)) {
				const selectedParts = targetSub.split('.');
				const codeParts = p.code.split('.');
				const isImmediateChild = codeParts.length === selectedParts.length + 1;
				const startsWithExact = codeParts.slice(0, selectedParts.length).join('.') === targetSub;
				if (!(isImmediateChild && startsWithExact)) return false;
			}

			// Filtro de búsqueda
			if (search) {
				const matches = p.code.toLowerCase().includes(search) || (p.description || '').toLowerCase().includes(search);
				if (!matches) return false;
			}

			return true;
		});

		const visibleIds = visiblePermissions.map((p) => p.id);

		if (manageTargetType === 'user') {
			if (action === 'select') {
				selectedUserPermissionIds = Array.from(new Set([...selectedUserPermissionIds, ...visibleIds]));
			} else {
				selectedUserPermissionIds = selectedUserPermissionIds.filter((id) => !visibleIds.includes(id));
			}
		} else {
			if (action === 'select') {
				selectedPermissionIds = Array.from(new Set([...selectedPermissionIds, ...visibleIds]));
			} else {
				selectedPermissionIds = selectedPermissionIds.filter((id) => !visibleIds.includes(id));
			}
		}
	}

	// Cargar datos reactivamente cuando cambia la compañía
	$effect(() => {
		const companyId = companyStore.activeCompany?.id;
		if (companyId) {
			Promise.all([loadUsers(), loadStats(), loadRolesTab(), loadAllPermissionsForRoles(), loadAvailableRoles()]);
		}
	});

	$effect(() => {
		if (!showUserPermissionsDialog) {
			userEffectiveSearchQuery = '';
			userEffectiveModuleFilter = '';
			userEffectiveActionFilter = '';
		}
	});

	$effect(() => {
		const mod = userEffectiveModuleFilter;
		const act = userEffectiveActionFilter;
		if (!mod || !act) return;
		const valid = userEffectiveActionsValidForModuleFilter;
		if (valid && !valid.has(act)) {
			userEffectiveActionFilter = '';
		}
	});
</script>

{#if !canView}
	<ErrorState status={403} />
{:else if managementView === 'list'}
	<div class="container mx-auto space-y-6 py-6">
		<!-- Header -->
		<div class="flex items-center justify-between">
			<div>
				<h1 class="text-3xl font-bold">Gestión de Usuarios y Roles</h1>
				<p class="text-muted-foreground">
					Administra usuarios, roles y permisos de tu organización
				</p>
			</div>
		</div>

		<!-- Tabs -->
		<Tabs.Root value="usuarios" class="w-full">
			<Tabs.List class="grid w-full grid-cols-2">
				<Tabs.Trigger value="usuarios">
					<Users class="mr-2 h-4 w-4" />
					Usuarios
				</Tabs.Trigger>
				<Tabs.Trigger value="roles">
					<Shield class="mr-2 h-4 w-4" />
					Roles y Permisos
				</Tabs.Trigger>
			</Tabs.List>

			<!-- Tab: Usuarios -->
			<Tabs.Content value="usuarios" class="mt-6 space-y-6">
				<div class="flex justify-end gap-2">
					{#if canCreate}
					<Button onclick={() => (showInviteDialog = true)}>
						<svg class="mr-2 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
						Invitar Usuario
					</Button>
					{/if}
				</div>

				<div class="grid gap-6">
					<!-- Estadísticas -->
					{#if stats}
						<div class="grid gap-4 md:grid-cols-4">
							<Card.Root>
								<Card.Header class="flex flex-row items-center justify-between space-y-0 pb-2">
									<Card.Title class="text-sm font-medium">Total Usuarios</Card.Title>
									<Users class="h-4 w-4 text-muted-foreground" />
								</Card.Header>
								<Card.Content>
									<div class="text-2xl font-bold">{stats.total_users}</div>
								</Card.Content>
							</Card.Root>

							<Card.Root>
								<Card.Header class="flex flex-row items-center justify-between space-y-0 pb-2">
									<Card.Title class="text-sm font-medium">Activos</Card.Title>
									<UserCheck class="h-4 w-4 text-green-600" />
								</Card.Header>
								<Card.Content>
									<div class="text-2xl font-bold text-green-600">{stats.active_users}</div>
								</Card.Content>
							</Card.Root>

							<Card.Root>
								<Card.Header class="flex flex-row items-center justify-between space-y-0 pb-2">
									<Card.Title class="text-sm font-medium">Disponibles</Card.Title>
									<AlertCircle class="h-4 w-4 text-blue-600" />
								</Card.Header>
								<Card.Content>
									<div class="text-2xl font-bold text-blue-600">{stats.users_available}</div>
									<p class="text-xs text-muted-foreground">
										de {stats.max_users_allowed} permitidos
									</p>
								</Card.Content>
							</Card.Root>

							<Card.Root>
								<Card.Header class="flex flex-row items-center justify-between space-y-0 pb-2">
									<Card.Title class="text-sm font-medium">Uso de Licencia</Card.Title>
								</Card.Header>
								<Card.Content>
									<div class="text-2xl font-bold">{stats.usage_percentage.toFixed(1)}%</div>
									<div class="mt-2 h-2 w-full rounded-full bg-gray-200">
										<div
											class="h-2 rounded-full transition-all"
											class:bg-green-600={stats.usage_percentage < 70}
											class:bg-yellow-600={stats.usage_percentage >= 70 &&
												stats.usage_percentage < 90}
											class:bg-red-600={stats.usage_percentage >= 90}
											style="width: {stats.usage_percentage}%"
										></div>
									</div>
								</Card.Content>
							</Card.Root>
						</div>
					{/if}

					<!-- Tabla de Usuarios -->
					<Card.Root>
						<Card.Header>
							<div class="flex items-center justify-between">
								<div>
									<Card.Title>Usuarios</Card.Title>
									<Card.Description>Listado de todos los usuarios de la plataforma</Card.Description
									>
								</div>
								<div class="relative w-64">
									<Search class="absolute top-2.5 left-2 h-4 w-4 text-muted-foreground" />
									<Input placeholder="Buscar usuarios..." class="pl-8" />
								</div>
							</div>
						</Card.Header>
						<Card.Content>
							<Table.Root>
								<Table.Header>
									<Table.Row>
										<Table.Head>Usuario</Table.Head>
										<Table.Head>Nombre Completo</Table.Head>
										<Table.Head>Email</Table.Head>
										<Table.Head>Estado</Table.Head>
										<Table.Head class="text-right">Acciones</Table.Head>
									</Table.Row>
								</Table.Header>
								<Table.Body>
									{#if loading}
										<Table.Row>
											<Table.Cell colspan={5} class="py-8 text-center">
												<div class="flex items-center justify-center gap-2">
													<RefreshCw class="h-4 w-4 animate-spin" />
													Cargando usuarios...
												</div>
											</Table.Cell>
										</Table.Row>
									{:else if users.length === 0}
										<Table.Row>
											<Table.Cell colspan={5} class="py-8 text-center text-muted-foreground">
												No se encontraron usuarios
											</Table.Cell>
										</Table.Row>
									{:else}
										{#each users as user (user.id)}
											<Table.Row>
												<Table.Cell>
													<div class="flex flex-col">
														<span class="font-medium">{user.username}</span>
														{#if user.email_verified}
															<Badge variant="secondary" class="w-fit text-[10px]">Verificado</Badge
															>
														{/if}
													</div>
												</Table.Cell>
												<Table.Cell>{user.first_name} {user.last_name}</Table.Cell>
												<Table.Cell>{user.email}</Table.Cell>
												<Table.Cell>
													{#if user.enabled}
														<Badge class="bg-green-600 hover:bg-green-700">Activo</Badge>
													{:else}
														<Badge variant="destructive">Inactivo</Badge>
													{/if}
												</Table.Cell>
												<Table.Cell class="text-right">
													<div class="flex justify-end gap-1">
														<Tooltip.Root>
															<Tooltip.Trigger>
																<Button
																	variant="ghost"
																	size="icon"
																	onclick={() => openRolesDialog(user)}
																	disabled={!canManageUserRoles}
																>
																	<Shield class="h-4 w-4" />
																</Button>
															</Tooltip.Trigger>
															<Tooltip.Content>Gestionar Roles</Tooltip.Content>
														</Tooltip.Root>

														<Tooltip.Root>
															<Tooltip.Trigger>
																<Button
																	variant="ghost"
																	size="icon"
																	onclick={() => openPasswordDialog(user)}
																	disabled={!canEditUserProfile}
																>
																	<Key class="h-4 w-4" />
																</Button>
															</Tooltip.Trigger>
															<Tooltip.Content>Cambiar Contraseña</Tooltip.Content>
														</Tooltip.Root>

														<Tooltip.Root>
															<Tooltip.Trigger>
																<Button
																	variant="ghost"
																	size="icon"
																	onclick={() => openEditDialog(user)}
																	disabled={!canEditUserProfile}
																>
																	<Pencil class="h-4 w-4" />
																</Button>
															</Tooltip.Trigger>
															<Tooltip.Content>Editar Usuario</Tooltip.Content>
														</Tooltip.Root>

														<Tooltip.Root>
															<Tooltip.Trigger>
																<Button
																	variant="ghost"
																	size="icon"
																	onclick={() => openDeleteDialog(user)}
																	disabled={!canDelete}
																>
																	<Trash2 class="h-4 w-4 text-destructive" />
																</Button>
															</Tooltip.Trigger>
															<Tooltip.Content>Eliminar Usuario</Tooltip.Content>
														</Tooltip.Root>
													</div>
												</Table.Cell>
											</Table.Row>
										{/each}
									{/if}
								</Table.Body>
							</Table.Root>
						</Card.Content>
					</Card.Root>
				</div>
			</Tabs.Content>

			<!-- Tab: Roles y Permisos -->
			<Tabs.Content value="roles" class="mt-6">
				{#if !canAccessRolesTab}
					<div class="flex min-h-[400px] items-center justify-center rounded-lg border bg-muted/20">
					<ErrorState status={403} />
					</div>
				{:else}
					<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
					<!-- Roles List -->
					<div class="lg:col-span-1">
						<div class="rounded-lg border p-4">
							<div class="mb-4 flex items-center justify-between">
								<h2 class="flex items-center gap-2 text-lg font-semibold">
									<Shield class="h-5 w-5" />
									Roles
								</h2>
								<Button size="sm" onclick={openCreateRoleDialog} disabled={!canCreateRoles}>
									<Plus class="h-4 w-4" />
								</Button>
							</div>

							{#if rolesState.length === 0}
								<div class="py-8 text-center text-muted-foreground">No hay roles disponibles</div>
							{:else}
								<div class="space-y-2">
									{#each rolesState as role (role.id)}
										<div
											class="flex items-center gap-2 rounded-lg border p-2 {selectedRoleForPermissions?.id ===
											role.id
												? 'border-primary bg-primary/10'
												: 'hover:bg-accent'}"
										>
											<Button
												variant="ghost"
												class="h-auto flex-1 justify-start p-2"
												onclick={() => selectRoleForPermissions(role)}
											>
												<div class="flex w-full flex-col items-start gap-1">
													<div class="flex w-full items-center gap-2">
														<Shield class="h-4 w-4 flex-shrink-0" />
														<span class="truncate text-sm font-medium">{role.name}</span>
													</div>
													{#if !role.is_active}
														<Badge variant="secondary" class="text-xs">Inactivo</Badge>
													{/if}
												</div>
											</Button>
											<div class="flex gap-1">
												<Button
													variant="ghost"
													size="sm"
													class="h-8 w-8 p-0"
													onclick={() => openEditRoleDialog(role)}
													disabled={!canEditRoles}
												>
													<Pencil class="h-3 w-3" />
												</Button>
												<Button
													variant="ghost"
													size="sm"
													class="h-8 w-8 p-0"
													onclick={() => handleDeleteRole(role)}
													disabled={!canDeleteRoles}
												>
													<Trash2 class="h-3 w-3" />
												</Button>
											</div>
										</div>
									{/each}
								</div>
							{/if}
						</div>
					</div>

					<!-- Permissions List -->
					<div class="lg:col-span-2">
						{#if selectedRoleForPermissions}
							<div class="rounded-lg border">
								<div class="flex items-center justify-between border-b p-4">
									<div>
										<h2 class="flex items-center gap-2 text-lg font-semibold">
											<Key class="h-5 w-5" />
											Permisos de "{selectedRoleForPermissions.name}"
										</h2>
										<p class="text-sm text-muted-foreground">
											{#if rolePermissionsSearchQuery.trim()}
												Mostrando {filteredRolePermissions.length} de {rolePermissionsVisibleCount}{' '}
												permisos asignados
											{:else}
												{rolePermissionsVisibleCount} permisos asignados
											{/if}
										</p>
									</div>
									<div class="flex items-center gap-3">
										<div class="relative w-72">
											<Search class="absolute top-2.5 left-2 h-4 w-4 text-muted-foreground" />
											<Input
												bind:value={rolePermissionsSearchQuery}
												placeholder="Buscar permiso en este rol..."
												class="pl-8"
											/>
										</div>
										<Button
											onclick={openAddPermissionsDialog}
											disabled={availablePermissionsState.length === 0 || !canEditRoles}
										>
											<Plus class="mr-2 h-4 w-4" />
											Agregar Permisos
										</Button>
									</div>
								</div>

								<Table.Root>
									<Table.Header>
										<Table.Row>
											<Table.Head class="w-[150px]">Módulo</Table.Head>
											<Table.Head class="w-[120px]">Acción</Table.Head>
											<Table.Head>Permiso</Table.Head>
											<Table.Head class="w-[80px] text-right">Acciones</Table.Head>
										</Table.Row>
									</Table.Header>
									<Table.Body>
										{#if loadingPermissionsState}
											<Table.Row>
												<Table.Cell colspan={4} class="py-8 text-center">
													Cargando permisos...
												</Table.Cell>
											</Table.Row>
										{:else if rolePermissionsVisibleCount === 0}
											<Table.Row>
												<Table.Cell colspan={4} class="py-8 text-center">
													Este rol no tiene permisos asignados
												</Table.Cell>
											</Table.Row>
										{:else if filteredRolePermissions.length === 0}
											<Table.Row>
												<Table.Cell colspan={4} class="py-8 text-center text-muted-foreground">
													No hay coincidencias para "{rolePermissionsSearchQuery}"
												</Table.Cell>
											</Table.Row>
										{:else}
											{#each filteredRolePermissions as rp (rp.id)}
												<Table.Row>
													<Table.Cell>
														<Badge variant="outline"
															>{rp.permission?.module
																? getModuleLabel(rp.permission.module)
																: '-'}</Badge
														>
													</Table.Cell>
													<Table.Cell>
														<span class="font-medium"
															>{rp.permission?.action
																? getActionLabel(rp.permission.action)
																: '-'}</span
														>
													</Table.Cell>
													<Table.Cell>
														{#if rp.permission}
															<div class="space-y-1">
																<div>{formatPermissionLabel(rp.permission)}</div>
																<code class="text-xs text-muted-foreground"
																	>{rp.permission.code}</code
																>
															</div>
														{:else}
															<span class="text-muted-foreground">-</span>
														{/if}
													</Table.Cell>
													<Table.Cell class="text-right">
														<Button
															variant="ghost"
															size="sm"
															onclick={() => handleRemovePermission(rp.permission_id)}
															title="Quitar permiso"
															disabled={!canEditRoles}
														>
															<Trash2 class="h-4 w-4" />
														</Button>
													</Table.Cell>
												</Table.Row>
											{/each}
										{/if}
									</Table.Body>
								</Table.Root>
							</div>
						{:else}
							<div class="rounded-lg border p-12 text-center">
								<Shield class="mx-auto mb-4 h-12 w-12 text-muted-foreground" />
								<p class="text-muted-foreground">Selecciona un rol para ver sus permisos</p>
							</div>
						{/if}
					</div>
				</div>
				{/if}
			</Tabs.Content>
		</Tabs.Root>
	</div>
{:else}
	{@const modules = manageTargetType === 'user' ? modulesForUserDialog : modulesForRoleDialog}
	{@const selectedModule =
		manageTargetType === 'user' ? selectedModuleForUserDialog : selectedModuleForRoleDialog}
	{@const totalSelected =
		manageTargetType === 'user' ? selectedUserPermissionIds.length : selectedPermissionIds.length}
	{@const selectedIds =
		manageTargetType === 'user' ? selectedUserPermissionIds : selectedPermissionIds}

	<!-- ========================================
	     GESTIÓN DE PERMISOS (VISTA EMBEBIDA)
	     ======================================== -->
	<div class="flex h-screen flex-col bg-background">
		<!-- Dynamic Header -->
		<header
			class="sticky top-0 z-50 flex items-center justify-between border-b bg-background/95 px-8 py-4 backdrop-blur"
		>
			<div class="flex items-center gap-6">
				<Button
					variant="ghost"
					size="sm"
					onclick={() => (managementView = 'list')}
					class="gap-2 text-muted-foreground hover:text-foreground"
				>
					<ArrowLeft class="h-4 w-4" />
					Volver a Usuarios
				</Button>
				<div class="h-8 w-[1px] bg-border"></div>
				<div>
					<h2 class="text-xl font-bold tracking-tight">
						{#if manageTargetType === 'user'}
							Permisos de <span class="text-primary">{selectedUser?.username}</span>
						{:else}
							Permisos del Rol <span class="text-primary">"{selectedRoleForPermissions?.name}"</span
							>
						{/if}
					</h2>
					<p class="text-xs text-muted-foreground">Configuración de acceso granular y seguridad</p>
				</div>
			</div>

			<div class="flex items-center gap-3">
				<div class="mr-4 flex flex-col items-end text-sm">
					{#if manageTargetType === 'user'}
						<span class="font-bold text-primary"
							>{selectedUserPermissionIds.length} seleccionados</span
						>
					{:else}
						<span class="font-bold text-primary">{selectedPermissionIds.length} seleccionados</span>
					{/if}
					<span class="text-[10px] tracking-widest text-muted-foreground uppercase"
						>Estado por asignar</span
					>
				</div>
				<Button variant="outline" onclick={() => (managementView = 'list')}>Cancelar</Button>
				<Button
					onclick={manageTargetType === 'user'
						? handleGrantUserPermissions
						: handleAssignPermissions}
					disabled={manageTargetType === 'user'
						? selectedUserPermissionIds.length === 0
						: selectedPermissionIds.length === 0}
					class="gap-2 px-8 shadow-lg shadow-primary/20"
				>
					<Check class="h-4 w-4" />
					Guardar Cambios
				</Button>
			</div>
		</header>

		<div class="flex flex-1 overflow-hidden">
			<!-- Sidebar Módulos -->
			<aside class="w-80 overflow-y-auto border-r bg-muted/20">
				<div class="sticky top-0 z-10 border-b bg-muted/40 p-6 backdrop-blur">
					<div class="relative">
						<Search
							class="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground"
						/>
						<Input
							type="text"
							placeholder="Filtrar permisos..."
							bind:value={permissionSearchQuery}
							oninput={() => manageTargetType === 'role' && updatePermissionsByModuleForRole()}
							class="w-full border-none bg-background pl-10 shadow-sm"
						/>
					</div>
				</div>

				<nav class="space-y-2 p-4">
					<button
						class="flex w-full items-center justify-between rounded-xl px-4 py-3 text-sm font-semibold transition-all {selectedModule ===
						'all'
							? 'bg-primary text-primary-foreground shadow-md ring-4 ring-primary/10'
							: 'text-muted-foreground hover:bg-accent/50 hover:text-foreground'}"
						onclick={() =>
							manageTargetType === 'user'
								? (selectedModuleForUserDialog = 'all')
								: (selectedModuleForRoleDialog = 'all')}
					>
						<span class="flex items-center gap-3">
							<Shield class="h-4 w-4" />
							Todos los Módulos
						</span>
						{#if totalSelected > 0}
							<Badge
								variant={selectedModule === 'all' ? 'secondary' : 'default'}
								class="h-5 rounded-full px-2"
							>
								{totalSelected}
							</Badge>
						{/if}
					</button>

					{#each sidebarGroups as group}
						{@const groupModules = modules.filter((m) => group.keys.includes(m.module))}
						{#if groupModules.length > 0}
							<div class="space-y-1">
								{#each groupModules as { module, permissions, moduleSelectedCount }}
									<button
										class="flex w-full items-center justify-between rounded-xl px-4 py-2.5 text-sm transition-all {selectedModule ===
										module
											? 'bg-primary/10 font-semibold text-primary'
											: 'text-muted-foreground hover:bg-muted/50 hover:text-foreground'}"
										onclick={() => {
											if (manageTargetType === 'user') {
												selectedModuleForUserDialog = selectedModuleForUserDialog === module ? 'all' : module;
												selectedSubModuleForUserDialog = 'all';
											} else {
												selectedModuleForRoleDialog = selectedModuleForRoleDialog === module ? 'all' : module;
												selectedSubModuleForRoleDialog = 'all';
											}
										}}
									>
										<span class="truncate pr-2">{getModuleLabel(module)}</span>
										<div class="flex items-center gap-2">
											{#if moduleSelectedCount > 0}
												<Badge
													variant={selectedModule === module ? 'default' : 'secondary'}
													class="h-5 rounded-full px-2"
												>
													{moduleSelectedCount}
												</Badge>
											{/if}
											<span class="text-[10px] opacity-40">({permissions.length})</span>
										</div>
									</button>

									{#if module === 'general_catalogs' && selectedModule === 'general_catalogs'}
										<div class="mt-2 ml-4 space-y-1 border-l-2 border-primary/20 py-2 pl-4">
											<button
												class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
													manageTargetType === 'user'
														? selectedSubModuleForUserDialog === 'all'
														: selectedSubModuleForRoleDialog === 'all'
												)
													? 'bg-primary/5 font-medium text-primary'
													: 'text-muted-foreground hover:bg-accent/50'}"
												onclick={() =>
													manageTargetType === 'user'
														? (selectedSubModuleForUserDialog = 'all')
														: (selectedSubModuleForRoleDialog = 'all')}
											>
												Todos
											</button>
											{#each generalCatalogsResources as resource}
												<button
													class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
														manageTargetType === 'user'
															? selectedSubModuleForUserDialog === resource
															: selectedSubModuleForRoleDialog === resource
													)
														? 'bg-primary/5 font-medium text-primary'
														: 'text-muted-foreground hover:bg-accent/50'}"
													onclick={() =>
														manageTargetType === 'user'
															? (selectedSubModuleForUserDialog = resource)
															: (selectedSubModuleForRoleDialog = resource)}
												>
													{getSubModuleLabel(resource)}
												</button>
											{/each}
										</div>
									{/if}

									{#if module === 'fractions' && selectedModule === 'fractions'}
										<div class="mt-2 ml-4 space-y-1 border-l-2 border-primary/20 py-2 pl-4">
											<button
												class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
													manageTargetType === 'user'
														? selectedSubModuleForUserDialog === 'all'
														: selectedSubModuleForRoleDialog === 'all'
												)
													? 'bg-primary/5 font-medium text-primary'
													: 'text-muted-foreground hover:bg-accent/50'}"
												onclick={() =>
													manageTargetType === 'user'
														? (selectedSubModuleForUserDialog = 'all')
														: (selectedSubModuleForRoleDialog = 'all')}
											>
												Todos
											</button>
											{#each fractionsResources as resource}
												<button
													class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
														manageTargetType === 'user'
															? selectedSubModuleForUserDialog === resource
															: selectedSubModuleForRoleDialog === resource
													)
														? 'bg-primary/5 font-medium text-primary'
														: 'text-muted-foreground hover:bg-accent/50'}"
													onclick={() =>
														manageTargetType === 'user'
															? (selectedSubModuleForUserDialog = resource)
															: (selectedSubModuleForRoleDialog = resource)}
												>
													{getSubModuleLabel(resource)}
												</button>
											{/each}
										</div>
									{/if}

									{#if module === 'transports' && selectedModule === 'transports'}
										<div class="mt-2 ml-4 space-y-1 border-l-2 border-primary/20 py-2 pl-4">
											<button
												class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
													manageTargetType === 'user'
														? selectedSubModuleForUserDialog === 'all'
														: selectedSubModuleForRoleDialog === 'all'
												)
													? 'bg-primary/5 font-medium text-primary'
													: 'text-muted-foreground hover:bg-accent/50'}"
												onclick={() =>
													manageTargetType === 'user'
														? (selectedSubModuleForUserDialog = 'all')
														: (selectedSubModuleForRoleDialog = 'all')}
											>
												Todos
											</button>
											{#each transportsResources as resource}
												<button
													class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
														manageTargetType === 'user'
															? selectedSubModuleForUserDialog === resource
															: selectedSubModuleForRoleDialog === resource
													)
														? 'bg-primary/5 font-medium text-primary'
														: 'text-muted-foreground hover:bg-accent/50'}"
													onclick={() =>
														manageTargetType === 'user'
															? (selectedSubModuleForUserDialog = resource)
															: (selectedSubModuleForRoleDialog = resource)}
												>
													{getSubModuleLabel(resource)}
												</button>
											{/each}
										</div>
									{/if}

									{#if module === 'goods' && selectedModule === 'goods'}
										<div class="mt-2 ml-4 space-y-1 border-l-2 border-primary/20 py-2 pl-4">
											<button
												class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
													manageTargetType === 'user'
														? selectedSubModuleForUserDialog === 'all'
														: selectedSubModuleForRoleDialog === 'all'
												)
													? 'bg-primary/5 font-medium text-primary'
													: 'text-muted-foreground hover:bg-accent/50'}"
												onclick={() =>
													manageTargetType === 'user'
														? (selectedSubModuleForUserDialog = 'all')
														: (selectedSubModuleForRoleDialog = 'all')}
											>
												Todos
											</button>
											{#each goodsResources as resource}
												<button
													class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
														manageTargetType === 'user'
															? selectedSubModuleForUserDialog === resource
															: selectedSubModuleForRoleDialog === resource
													)
														? 'bg-primary/5 font-medium text-primary'
														: 'text-muted-foreground hover:bg-accent/50'}"
													onclick={() =>
														manageTargetType === 'user'
															? (selectedSubModuleForUserDialog = resource)
															: (selectedSubModuleForRoleDialog = resource)}
												>
													{getSubModuleLabel(resource)}
												</button>
											{/each}
										</div>
									{/if}

									{#if module === 'pedimentos' && selectedModule === 'pedimentos'}
										<div class="mt-2 ml-4 space-y-1 border-l-2 border-primary/20 py-2 pl-4">
											<button
												class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
													manageTargetType === 'user'
														? selectedSubModuleForUserDialog === 'all'
														: selectedSubModuleForRoleDialog === 'all'
												)
													? 'bg-primary/5 font-medium text-primary'
													: 'text-muted-foreground hover:bg-accent/50'}"
												onclick={() =>
													manageTargetType === 'user'
														? (selectedSubModuleForUserDialog = 'all')
														: (selectedSubModuleForRoleDialog = 'all')}
											>
												Todos
											</button>
											{#each pedimentosResources as resource}
												<button
													class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
														manageTargetType === 'user'
															? selectedSubModuleForUserDialog === resource
															: selectedSubModuleForRoleDialog === resource
													)
														? 'bg-primary/5 font-medium text-primary'
														: 'text-muted-foreground hover:bg-accent/50'}"
													onclick={() =>
														manageTargetType === 'user'
															? (selectedSubModuleForUserDialog = resource)
															: (selectedSubModuleForRoleDialog = resource)}
												>
													{getSubModuleLabel(resource)}
												</button>
											{/each}
										</div>
									{/if}

									{#if module === 'invoice_imp' && selectedModule === 'invoice_imp'}
										<div class="mt-2 ml-4 space-y-1 border-l-2 border-primary/20 py-2 pl-4">
											<button
												class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
													manageTargetType === 'user'
														? selectedSubModuleForUserDialog === 'all'
														: selectedSubModuleForRoleDialog === 'all'
												)
													? 'bg-primary/5 font-medium text-primary'
													: 'text-muted-foreground hover:bg-accent/50'}"
												onclick={() =>
													manageTargetType === 'user'
														? (selectedSubModuleForUserDialog = 'all')
														: (selectedSubModuleForRoleDialog = 'all')}
											>
												Todos
											</button>
											{#each invoiceImpResources as resource}
												<button
													class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
														manageTargetType === 'user'
															? selectedSubModuleForUserDialog === resource
															: selectedSubModuleForRoleDialog === resource
													)
														? 'bg-primary/5 font-medium text-primary'
														: 'text-muted-foreground hover:bg-accent/50'}"
													onclick={() =>
														manageTargetType === 'user'
															? (selectedSubModuleForUserDialog = resource)
															: (selectedSubModuleForRoleDialog = resource)}
												>
													{getSubModuleLabel(resource)}
												</button>
											{/each}
										</div>
									{/if}

									{#if module === 'invoice_exp' && selectedModule === 'invoice_exp'}
										<div class="mt-2 ml-4 space-y-1 border-l-2 border-primary/20 py-2 pl-4">
											<button
												class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
													manageTargetType === 'user'
														? selectedSubModuleForUserDialog === 'all'
														: selectedSubModuleForRoleDialog === 'all'
												)
													? 'bg-primary/5 font-medium text-primary'
													: 'text-muted-foreground hover:bg-accent/50'}"
												onclick={() =>
													manageTargetType === 'user'
														? (selectedSubModuleForUserDialog = 'all')
														: (selectedSubModuleForRoleDialog = 'all')}
											>
												Todos
											</button>
											{#each invoiceExpResources as resource}
												<button
													class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
														manageTargetType === 'user'
															? selectedSubModuleForUserDialog === resource
															: selectedSubModuleForRoleDialog === resource
													)
														? 'bg-primary/5 font-medium text-primary'
														: 'text-muted-foreground hover:bg-accent/50'}"
													onclick={() =>
														manageTargetType === 'user'
															? (selectedSubModuleForUserDialog = resource)
															: (selectedSubModuleForRoleDialog = resource)}
												>
													{getSubModuleLabel(resource)}
												</button>
											{/each}
										</div>
									{/if}

									{#if module === 'export' && selectedModule === 'export'}
										<div class="mt-2 ml-4 space-y-1 border-l-2 border-primary/20 py-2 pl-4">
											<button
												class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
													manageTargetType === 'user'
														? selectedSubModuleForUserDialog === 'all'
														: selectedSubModuleForRoleDialog === 'all'
												)
													? 'bg-primary/5 font-medium text-primary'
													: 'text-muted-foreground hover:bg-accent/50'}"
												onclick={() =>
													manageTargetType === 'user'
														? (selectedSubModuleForUserDialog = 'all')
														: (selectedSubModuleForRoleDialog = 'all')}
											>
												Todos
											</button>
											{#each exportResources as resource}
												<button
													class="flex w-full items-center rounded-lg px-3 py-1.5 text-xs transition-all {(
														manageTargetType === 'user'
															? selectedSubModuleForUserDialog === resource
															: selectedSubModuleForRoleDialog === resource
													)
														? 'bg-primary/5 font-medium text-primary'
														: 'text-muted-foreground hover:bg-accent/50'}"
													onclick={() =>
														manageTargetType === 'user'
															? (selectedSubModuleForUserDialog = resource)
															: (selectedSubModuleForRoleDialog = resource)}
												>
													{getSubModuleLabel(resource)}
												</button>
											{/each}
										</div>
									{/if}
								{/each}
							</div>
						{/if}
					{/each}

					{#if true}
						{@const otherModules = modules.filter(
							(m) => !sidebarGroups.some((g) => g.keys.includes(m.module))
						)}
						{#if otherModules.length > 0}
							<div
								class="mt-6 mb-2 px-4 text-[10px] font-bold tracking-[0.2em] text-muted-foreground/60 uppercase"
							>
								Otros Recursos
							</div>
							<div class="space-y-1">
								{#each otherModules as { module, permissions, moduleSelectedCount }}
									<button
										class="flex w-full items-center justify-between rounded-xl px-4 py-2.5 text-sm transition-all {selectedModule ===
										module
											? 'bg-primary/10 font-semibold text-primary'
											: 'text-muted-foreground hover:bg-muted/50 hover:text-foreground'}"
										onclick={() =>
											manageTargetType === 'user'
												? (selectedModuleForUserDialog = module)
												: (selectedModuleForRoleDialog = module)}
									>
										<span class="truncate pr-2">{getModuleLabel(module)}</span>
										<div class="flex items-center gap-2">
											{#if moduleSelectedCount > 0}
												<Badge
													variant={selectedModule === module ? 'default' : 'secondary'}
													class="h-5 rounded-full px-2"
												>
													{moduleSelectedCount}
												</Badge>
											{/if}
											<span class="text-[10px] opacity-40">({permissions.length})</span>
										</div>
									</button>
								{/each}
							</div>
						{/if}
					{/if}
				</nav>
			</aside>

			<!-- Canvas Principal -->
			<main class="flex-1 overflow-y-auto bg-background/50 p-10">
				<div class="mx-auto max-w-6xl space-y-12">
					{#if modules.length === 0}
						<div
							class="flex h-96 flex-col items-center justify-center rounded-3xl border-2 border-dashed border-muted-foreground/20 text-muted-foreground"
						>
							<Key class="mb-6 h-16 w-16 opacity-10" />
							<p class="text-lg font-medium">No se encontraron permisos disponibles</p>
						</div>
					{:else}
						{#each modules as { module, permissions } (module)}
							{#if selectedModule === 'all' || selectedModule === module}
							<div class="flex items-center justify-between border-b border-border/50 bg-background/50 pb-4 backdrop-blur-sm">
								<div class="space-y-1">
									<h3 class="text-lg font-medium tracking-tight text-foreground/90 capitalize">
										{selectedModule === 'all' ? 'Resumen Global' : (selectedModule || '').replace('_', ' ')}
									</h3>
									<div class="flex items-center gap-2">
										<div class="h-1.5 w-1.5 rounded-full bg-emerald-500/60 animate-pulse"></div>
										<p class="text-xs text-muted-foreground font-medium">
											{allPermissionsState.filter((p) => {
												const matchesSearch =
													!permissionSearchQuery ||
													p.code.toLowerCase().includes(permissionSearchQuery.toLowerCase()) ||
													p.description?.toLowerCase().includes(permissionSearchQuery.toLowerCase());

												const isSubModuleParent = [
													'general_catalogs', 'fractions', 'transports', 'goods',
													'pedimentos', 'invoice_imp', 'invoice_exp', 'export',
													'users', 'reports', 'roles'
												].includes(p.module);
												
												const selectedSub = manageTargetType === 'user' ? selectedSubModuleForUserDialog : selectedSubModuleForRoleDialog;

												const matchesSub =
													!isSubModuleParent ||
													(() => {
														if (selectedSub === 'all') return true;
														const selectedParts = selectedSub.split('.');
														const codeParts = p.code.split('.');
														return codeParts.length === selectedParts.length + 1 &&
															   codeParts.slice(0, selectedParts.length).join('.') === selectedSub;
													})();
												
												const currentModule = selectedModule === 'all' ? p.module : selectedModule;
												return p.module === currentModule && matchesSearch && matchesSub;
											}).length} activos para selección
										</p>
									</div>
								</div>
								<div class="flex items-center gap-3">
									<button
										class="group relative flex items-center gap-2 overflow-hidden rounded-full border border-slate-200 bg-white px-4 py-2 text-xs font-semibold text-slate-700 shadow-sm transition-all hover:border-slate-300 hover:bg-slate-50 dark:border-slate-800 dark:bg-slate-950 dark:text-slate-300"
										onclick={() => handleBulkSelection('select')}
									>
										<span class="absolute inset-0 bg-slate-400/5 transition-transform group-hover:scale-105"></span>
										<Check class="h-3.5 w-3.5 text-slate-500" />
										Seleccionar todo
									</button>
									<button
										class="group relative flex items-center gap-2 overflow-hidden rounded-full border border-orange-100 bg-orange-50/30 px-4 py-2 text-xs font-semibold text-orange-700/80 transition-all hover:border-orange-200 hover:bg-orange-50 dark:border-orange-950 dark:bg-orange-950/20 dark:text-orange-400"
										onclick={() => handleBulkSelection('deselect')}
									>
										<Trash2 class="h-3.5 w-3.5 text-orange-500/70" />
										Limpiar sección
									</button>
								</div>
							</div>
								{@const selectedSub =
									manageTargetType === 'user'
										? selectedSubModuleForUserDialog
										: selectedSubModuleForRoleDialog}
								{@const filtered = permissions.filter((p: Permission) => {
									const matchesSearch =
										!permissionSearchQuery ||
										formatPermissionLabel(p)
											.toLowerCase()
											.includes(permissionSearchQuery.toLowerCase()) ||
										p.code.toLowerCase().includes(permissionSearchQuery.toLowerCase());
									const isSubModuleParent = [
										'general_catalogs',
										'fractions',
										'transports',
														'goods',
										'pedimentos',
										'invoice_imp',
										'invoice_exp',
										'export',
										'users',
										'reports',
										'roles'
									].includes(module);
									const matchesSub =
										!isSubModuleParent ||
										(() => {
											const selectedSub = manageTargetType === 'user' ? selectedSubModuleForUserDialog : selectedSubModuleForRoleDialog;
											if (selectedSub === 'all') return true;
											
											const selectedParts = selectedSub.split('.');
											const codeParts = p.code.split('.');
											
											// Verificamos que el código empiece con el prefijo exacto
											// Y que tenga exactamente un nivel más de profundidad (la acción)
											const isImmediateChild = codeParts.length === selectedParts.length + 1;
											const startsWithExact = codeParts.slice(0, selectedParts.length).join('.') === selectedSub;
											
											return isImmediateChild && startsWithExact;
										})();
									return matchesSearch && matchesSub;
								})}

								{#if filtered.length > 0}
									<section class="space-y-6">
										<div
											class="flex items-center justify-between border-b border-muted-foreground/10 pb-4"
										>
											<div class="flex items-center gap-4">
												<div
													class="flex h-10 w-10 items-center justify-center rounded-xl bg-primary/10 text-primary"
												>
													<Key class="h-5 w-5" />
												</div>
												<div>
													<h3 class="text-2xl font-bold tracking-tight">
														{getModuleLabel(module)}
													</h3>
													<p class="text-sm text-muted-foreground">
														Gestiona el acceso para el componente {module}
													</p>
												</div>
											</div>
											<Button
												variant="secondary"
												size="sm"
												class="h-9 px-4 text-xs font-bold tracking-wider uppercase"
												onclick={() => {
													const allSelected = filtered.every((p: Permission) =>
														selectedIds.includes(p.id)
													);
													if (manageTargetType === 'user') {
														if (allSelected) {
															selectedUserPermissionIds = selectedUserPermissionIds.filter(
																(id) => !filtered.some((fp: Permission) => fp.id === id)
															);
														} else {
															const toAdd = filtered
																.map((p: Permission) => p.id)
																.filter((id: number) => !selectedUserPermissionIds.includes(id));
															selectedUserPermissionIds = [...selectedUserPermissionIds, ...toAdd];
														}
													} else {
														if (allSelected) {
															selectedPermissionIds = selectedPermissionIds.filter(
																(id) => !filtered.some((fp: Permission) => fp.id === id)
															);
														} else {
															const toAdd = filtered
																.map((p: Permission) => p.id)
																.filter((id: number) => !selectedPermissionIds.includes(id));
															selectedPermissionIds = [...selectedPermissionIds, ...toAdd];
														}
													}
												}}
											>
												{#if filtered.every((p: Permission) => selectedIds.includes(p.id))}
													Deseleccionar Módulo
												{:else}
													Seleccionar Módulo
												{/if}
											</Button>
										</div>

										<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
											{#each filtered as permission (permission.id)}
												<!-- svelte-ignore a11y_click_events_have_key_events -->
												<!-- svelte-ignore a11y_no_static_element_interactions -->
												<div
													class="group relative cursor-pointer overflow-hidden rounded-2xl border bg-card p-5 transition-all hover:border-primary/50 hover:shadow-xl hover:shadow-primary/5 {selectedIds.includes(
														permission.id
													)
														? 'border-primary bg-primary/[0.03] ring-1 ring-primary'
														: ''}"
													onclick={() =>
														manageTargetType === 'user'
															? toggleUserPermission(permission.id)
															: togglePermission(permission.id)}
												>
													<div class="flex items-start gap-4">
														<div class="pt-1">
															<Checkbox
																id="perm-{permission.id}"
																checked={selectedIds.includes(permission.id)}
																onCheckedChange={() =>
																	manageTargetType === 'user'
																		? toggleUserPermission(permission.id)
																		: togglePermission(permission.id)}
																class="pointer-events-none h-5 w-5 rounded-md"
															/>
														</div>
														<div class="flex-1 space-y-3">
															<Label
																for="perm-{permission.id}"
																class="block cursor-pointer text-sm leading-tight font-bold transition-colors group-hover:text-primary"
															>
																{formatPermissionLabel(permission)}
															</Label>
															<div class="flex flex-wrap items-center gap-2">
																<span
																	class="inline-flex items-center rounded-md border px-2 py-0.5 text-[9px] font-black tracking-widest uppercase {getActionColor(
																		permission.action
																	)}"
																>
																	{getActionLabel(permission.action)}
																</span>
																<code
																	class="text-[9px] text-muted-foreground/60 transition-colors group-hover:text-muted-foreground"
																>
																	{permission.code}
																</code>
															</div>
														</div>
													</div>
												</div>
											{/each}
										</div>
									</section>
								{/if}
							{/if}
						{/each}
					{/if}
				</div>
			</main>
		</div>
	</div>
{/if}

<!-- ========================================
     DIÁLOGOS - USUARIOS
     ======================================== -->

<!-- Diálogo Invitar Usuario -->
<Dialog.Root bind:open={showInviteDialog}>
	<Dialog.Content class="max-w-md">
		<Dialog.Header>
			<Dialog.Title>Invitar Usuario</Dialog.Title>
			<Dialog.Description>
				Se generará un enlace de registro válido por 48 horas y de un solo uso.
			</Dialog.Description>
		</Dialog.Header>

		{#if inviteResult}
			<!-- Resultado: mostrar URL para copiar -->
			<div class="space-y-4">
				<div class="rounded-md bg-green-50 border border-green-200 p-4">
					<p class="text-sm font-medium text-green-800">Invitación generada</p>
					<p class="text-sm text-green-700 mt-1">
						Enviada a <strong>{inviteResult.email}</strong>.
						También puedes copiar el enlace manualmente:
					</p>
				</div>
				<div class="space-y-2">
					<Label>Enlace de invitación</Label>
					<div class="flex gap-2">
						<code class="flex-1 rounded border bg-muted px-3 py-2 text-xs break-all">
							{inviteResult.invite_url}
						</code>
						<Button size="sm" variant="outline" onclick={copyInviteUrl}>
							{#if inviteCopied}
								<Check class="h-4 w-4" />
							{:else}
								Copiar
							{/if}
						</Button>
					</div>
				</div>
			</div>
			<Dialog.Footer>
				<Button onclick={closeInviteDialog}>Cerrar</Button>
			</Dialog.Footer>
		{:else}
			<!-- Formulario -->
			<div class="space-y-4">
				<div class="space-y-2">
					<Label for="invite_email">Email *</Label>
					<Input
						id="invite_email"
						type="email"
						bind:value={inviteEmail}
						placeholder="usuario@empresa.com"
						required
					/>
				</div>
				<div class="space-y-2">
					<Label for="invite_role">Rol</Label>
					<Select.Root type="single" value={String(inviteRoleId || '')} onValueChange={(v) => (inviteRoleId = Number(v))}>
						<Select.Trigger id="invite_role">
							{availableRoles.find((r) => r.id === inviteRoleId)?.name ?? 'Selecciona un rol'}
						</Select.Trigger>
						<Select.Content>
							{#each availableRoles as role}
								<Select.Item value={String(role.id)}>{role.name}</Select.Item>
							{/each}
						</Select.Content>
					</Select.Root>
				</div>
			</div>
			<Dialog.Footer>
				<Button variant="outline" onclick={closeInviteDialog}>Cancelar</Button>
				<Button onclick={sendInvite} disabled={inviteLoading || !inviteEmail || !inviteRoleId}>
					{inviteLoading ? 'Generando...' : 'Enviar invitación'}
				</Button>
			</Dialog.Footer>
		{/if}
	</Dialog.Content>
</Dialog.Root>

<Dialog.Root bind:open={showCreateDialog}>
	<Dialog.Content class="max-w-md">
		<Dialog.Header>
			<Dialog.Title>Crear Nuevo Usuario</Dialog.Title>
			<Dialog.Description>
				Ingresa la información del nuevo usuario. Se enviará un correo para configurar su
				contraseña.
			</Dialog.Description>
		</Dialog.Header>
		<div class="space-y-4">
			<div class="grid grid-cols-2 gap-4">
				<div class="space-y-2">
					<Label for="first_name">Nombre *</Label>
					<Input id="first_name" bind:value={createForm.first_name} required />
				</div>
				<div class="space-y-2">
					<Label for="last_name">Apellido *</Label>
					<Input id="last_name" bind:value={createForm.last_name} required />
				</div>
			</div>
			<div class="space-y-2">
				<Label for="username">Usuario *</Label>
				<Input id="username" bind:value={createForm.username} required />
			</div>
			<div class="space-y-2">
				<Label for="email">Email *</Label>
				<Input id="email" type="email" bind:value={createForm.email} required />
			</div>
			<div class="space-y-2">
				<Label for="password">Contraseña Temporal *</Label>
				<Input id="password" type="password" bind:value={createForm.password} required />
				<p class="text-xs text-muted-foreground">Mínimo 8 caracteres</p>
			</div>
		</div>
		<Dialog.Footer>
			<Button variant="outline" onclick={() => (showCreateDialog = false)}>Cancelar</Button>
			<Button onclick={handleCreate}>Crear Usuario</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>

<!-- Diálogo Editar Usuario -->
<Dialog.Root bind:open={showEditDialog}>
	<Dialog.Content class="max-w-md">
		<Dialog.Header>
			<Dialog.Title>Editar Usuario</Dialog.Title>
			<Dialog.Description>
				Modifica la información del usuario {selectedUser?.username}
			</Dialog.Description>
		</Dialog.Header>
		<div class="space-y-4">
			<div class="grid grid-cols-2 gap-4">
				<div class="space-y-2">
					<Label for="edit_first_name">Nombre</Label>
					<Input id="edit_first_name" bind:value={editForm.first_name} />
				</div>
				<div class="space-y-2">
					<Label for="edit_last_name">Apellido</Label>
					<Input id="edit_last_name" bind:value={editForm.last_name} />
				</div>
			</div>
			<div class="space-y-2">
				<Label for="edit_email">Email</Label>
				<Input id="edit_email" type="email" bind:value={editForm.email} />
			</div>
			<div class="flex items-center space-x-2">
				<input type="checkbox" id="edit_enabled" bind:checked={editForm.enabled} class="h-4 w-4" />
				<Label for="edit_enabled">Usuario activo</Label>
			</div>
			<div class="flex items-center space-x-2">
				<input
					type="checkbox"
					id="edit_email_verified"
					bind:checked={editForm.email_verified}
					class="h-4 w-4"
				/>
				<Label for="edit_email_verified">Email verificado</Label>
			</div>
		</div>
		<Dialog.Footer>
			<Button variant="outline" onclick={() => (showEditDialog = false)}>Cancelar</Button>
			<Button onclick={handleUpdate}>Guardar Cambios</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>

<!-- Diálogo Cambiar Contraseña -->
<Dialog.Root bind:open={showPasswordDialog}>
	<Dialog.Content class="max-w-md">
		<Dialog.Header>
			<Dialog.Title>Cambiar Contraseña</Dialog.Title>
			<Dialog.Description>
				Establece una nueva contraseña para {selectedUser?.username}
			</Dialog.Description>
		</Dialog.Header>
		<div class="space-y-4">
			<div class="space-y-2">
				<Label for="new_password">Nueva Contraseña</Label>
				<Input id="new_password" type="password" bind:value={passwordForm.password} />
			</div>
			<div class="space-y-2">
				<Label for="confirm_password">Confirmar Contraseña</Label>
				<Input id="confirm_password" type="password" bind:value={passwordForm.confirmPassword} />
			</div>
			<div class="flex items-center space-x-2">
				<input
					type="checkbox"
					id="temporary"
					bind:checked={passwordForm.temporary}
					class="h-4 w-4"
				/>
				<Label for="temporary">Contraseña temporal (debe cambiarla al iniciar sesión)</Label>
			</div>
		</div>
		<Dialog.Footer>
			<Button variant="outline" onclick={() => (showPasswordDialog = false)}>Cancelar</Button>
			<Button onclick={handleChangePassword}>Cambiar Contraseña</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>

<!-- Diálogo Eliminar Usuario -->
<AlertDialog.Root bind:open={showDeleteDialog}>
	<AlertDialog.Content>
		<AlertDialog.Header>
			<AlertDialog.Title>¿Eliminar usuario?</AlertDialog.Title>
			<AlertDialog.Description>
				¿Estás seguro de que deseas eliminar a
				<strong>{selectedUser?.username}</strong>?
				<br /><br />
				{#if deleteLoadingCount}
					<span class="text-muted-foreground text-sm">Verificando membresías...</span>
				{:else if deleteUserTenantCount > 1}
					<span class="text-amber-600 dark:text-amber-400 text-sm">
						⚠️ Este usuario pertenece a
						<strong>{deleteUserTenantCount} tenants</strong>. Puedes eliminarlo solo del
						tenant actual o de todos.
					</span>
				{/if}
			</AlertDialog.Description>
		</AlertDialog.Header>
		<AlertDialog.Footer class="flex-col gap-2 sm:flex-row">
			<AlertDialog.Cancel>Cancelar</AlertDialog.Cancel>

			{#if deleteLoadingCount}
				<!-- Esperando conteo de tenants: deshabilitar acciones -->
				<Button variant="outline" disabled>
					<UserX class="mr-2 h-4 w-4" />
					Cargando...
				</Button>
			{:else if deleteUserTenantCount > 1}
				<!-- Solo del tenant actual -->
				<Button variant="outline" onclick={() => handleDelete(true, 'current')}>
					<UserX class="mr-2 h-4 w-4" />
					Desactivar (este tenant)
				</Button>
				<AlertDialog.Action
					onclick={() => handleDelete(false, 'current')}
					class="text-destructive-foreground bg-destructive hover:bg-destructive/90"
				>
					<Trash2 class="mr-2 h-4 w-4" />
					Eliminar (este tenant)
				</AlertDialog.Action>
				<!-- De todos los tenants -->
				<Button variant="outline" onclick={() => handleDelete(true, 'all')}>
					<UserX class="mr-2 h-4 w-4" />
					Desactivar (todos)
				</Button>
				<AlertDialog.Action
					onclick={() => handleDelete(false, 'all')}
					class="text-destructive-foreground bg-destructive hover:bg-destructive/90"
				>
					<Trash2 class="mr-2 h-4 w-4" />
					Eliminar (todos)
				</AlertDialog.Action>
			{:else}
				<!-- Usuario en un solo tenant: comportamiento original -->
				<Button variant="outline" onclick={() => handleDelete(true, 'current')}>
					<UserX class="mr-2 h-4 w-4" />
					Desactivar
				</Button>
				<AlertDialog.Action
					onclick={() => handleDelete(false, 'current')}
					class="text-destructive-foreground bg-destructive hover:bg-destructive/90"
				>
					<Trash2 class="mr-2 h-4 w-4" />
					Eliminar Permanente
				</AlertDialog.Action>
			{/if}
		</AlertDialog.Footer>
	</AlertDialog.Content>
</AlertDialog.Root>
<!-- Diálogo Gestión de Roles -->
<Dialog.Root bind:open={showRolesDialog}>
	<Dialog.Content class="max-w-2xl">
		<Dialog.Header>
			<Dialog.Title>Gestionar Roles - {selectedUser?.username}</Dialog.Title>
			<Dialog.Description>Asigna o remueve roles para este usuario</Dialog.Description>
		</Dialog.Header>

		<div class="space-y-6 py-4">
			<!-- Lista de roles asignados -->
			<div class="space-y-2">
				<Label>Roles Asignados</Label>
				{#if loadingRoles}
					<div class="flex items-center justify-center py-8">
						<RefreshCw class="h-6 w-6 animate-spin text-muted-foreground" />
					</div>
				{:else if userRoles.length === 0}
					<div class="py-8 text-center text-muted-foreground">
						Este usuario no tiene roles asignados
					</div>
				{:else}
					<div class="space-y-2">
						{#each userRoles as userRole}
							<div class="flex items-center justify-between rounded-lg border p-3">
								<div class="flex items-center gap-3">
									<Shield class="h-5 w-5 text-primary" />
									<div>
										<div class="font-medium">
											{userRole.company_role?.name || 'Rol desconocido'}
										</div>
										<div class="text-sm text-muted-foreground">
											Asignado el {new Date(userRole.created_at).toLocaleDateString()}
										</div>
									</div>
								</div>
								<Button variant="ghost" size="sm" onclick={() => removeRole(userRole.id)}>
									<Trash2 class="h-4 w-4 text-destructive" />
								</Button>
							</div>
						{/each}
					</div>
				{/if}
			</div>

			<!-- Asignar nuevo rol -->
			<div class="space-y-2">
				<Label>Asignar Nuevo Rol</Label>
				{#if unassignedRoles.length === 0}
					<p class="text-sm text-muted-foreground">
						No hay roles disponibles. Para cambiar de rol, primero remueve el rol actual usando el
						botón de eliminar arriba.
					</p>
				{:else}
					<div class="flex gap-2">
						<Select.Root
							type="single"
							value={typeof selectedRoleId === 'number'
								? selectedRoleId.toString()
								: selectedRoleId}
							onValueChange={(v: string | undefined) => (selectedRoleId = v ? parseInt(v) : 0)}
						>
							<Select.Trigger class="flex-1">
								{selectedRoleId && selectedRoleId !== 0
									? availableRoles.find(
											(r) =>
												r.id ===
												(typeof selectedRoleId === 'string'
													? parseInt(selectedRoleId)
													: selectedRoleId)
										)?.name || 'Selecciona un rol'
									: 'Selecciona un rol'}
							</Select.Trigger>
							<Select.Content>
								{#each unassignedRoles as role}
									<Select.Item value={role.id.toString()}>{role.name}</Select.Item>
								{/each}
							</Select.Content>
						</Select.Root>
						<Button onclick={assignRole} disabled={!selectedRoleId || selectedRoleId === 0}>
							<Plus class="mr-2 h-4 w-4" />
							Asignar
						</Button>
					</div>
				{/if}
			</div>
		</div>

		<Dialog.Footer class="flex justify-between">
			<Button
				variant="outline"
				onclick={() => {
					if (selectedUser) {
						loadUserEffectivePermissions().then(() => {
							showRolesDialog = false;
							showUserPermissionsDialog = true;
						});
					}
				}}
			>
				<Key class="mr-2 h-4 w-4" />
				Permisos Individuales
			</Button>
			<Button variant="outline" onclick={() => (showRolesDialog = false)}>Cerrar</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>

<!-- Diálogo Permisos Individuales de Usuario -->
<Dialog.Root bind:open={showUserPermissionsDialog}>
	<Dialog.Content class="flex max-h-[85vh] max-w-3xl flex-col overflow-hidden">
		<Dialog.Header>
			<Dialog.Title>Permisos Individuales - {selectedUser?.username}</Dialog.Title>
			<Dialog.Description>
				Concede permisos extra o revoca permisos del rol para este usuario específico
			</Dialog.Description>
		</Dialog.Header>

		<div class="flex-1 space-y-4 overflow-y-auto py-4">
			{#if loadingUserPermissions}
				<div class="flex items-center justify-center py-12">
					<RefreshCw class="h-8 w-8 animate-spin text-muted-foreground" />
				</div>
			{:else if effectivePermissions}
				<!-- Resumen de permisos -->
				<div class="grid grid-cols-3 gap-3 rounded-lg bg-accent/50 p-4">
					<div class="text-center">
						<div class="text-2xl font-bold text-primary">
							{effectiveInheritedVisibleCount}
						</div>
						<div class="text-xs text-muted-foreground">Del Rol</div>
					</div>
					<div class="text-center">
						<div class="text-2xl font-bold text-green-600">
							{effectiveGrantedVisibleCount}
						</div>
						<div class="text-xs text-muted-foreground">Concedidos Extra</div>
					</div>
					<div class="text-center">
						<div class="text-2xl font-bold text-destructive">
							{effectiveRevokedVisibleCount}
						</div>
						<div class="text-xs text-muted-foreground">Revocados</div>
					</div>
				</div>

				<div class="relative">
					<Search class="absolute top-2.5 left-2 h-4 w-4 text-muted-foreground" />
					<Input
						type="text"
						placeholder="Buscar en revocados/heredados/concedidos..."
						bind:value={userEffectiveSearchQuery}
						class="pl-8"
					/>
				</div>

				<div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
					<div class="space-y-2">
						<Label>Módulo</Label>
						<Select.SelectSearchable
							bind:value={userEffectiveModuleFilter}
							items={userEffectiveModuleFilterItems}
							placeholder="Todos los módulos"
							searchPlaceholder="Buscar módulo..."
							emptyMessage="No se encontraron módulos"
						/>
					</div>
					<div class="space-y-2">
						<Label>Acción</Label>
						<Select.SelectSearchable
							bind:value={userEffectiveActionFilter}
							items={userEffectiveActionFilterItems}
							placeholder="Todas las acciones"
							searchPlaceholder="Buscar acción..."
							emptyMessage="No se encontraron acciones"
						/>
					</div>
				</div>

				<!-- Permisos Concedidos Extra -->
				{#if effectiveGrantedVisibleCount > 0}
					<div class="space-y-2">
						<div class="flex items-center justify-between">
							<Label class="flex items-center gap-2 text-green-600">
								<Plus class="h-4 w-4" />
								Permisos Extra Concedidos
							</Label>
							<Badge variant="secondary">
								{filteredGrantedPermissions.length}/{effectiveGrantedVisibleCount}
							</Badge>
						</div>
						<div class="max-h-48 space-y-1 overflow-y-auto rounded-lg border p-2">
							{#if filteredGrantedPermissions.length === 0}
								<div class="rounded px-3 py-2 text-sm text-muted-foreground">
									Sin coincidencias en permisos concedidos
								</div>
							{:else}
								{#each filteredGrantedPermissions as perm}
									<div class="flex items-center justify-between gap-2 rounded px-3 py-2 hover:bg-accent/50">
										<div class="min-w-0 flex-1 space-y-1">
											<div class="flex flex-wrap items-center gap-2">
												<Badge variant="outline">{getModuleLabel(perm.module)}</Badge>
												<span class="text-sm font-medium">{getActionLabel(perm.action)}</span>
											</div>
											<div class="truncate text-sm font-medium">{formatPermissionLabel(perm)}</div>
											<code class="text-xs text-muted-foreground">{perm.code}</code>
										</div>
										<Button
											variant="ghost"
											size="sm"
											onclick={() => handleRemoveUserPermission(perm.id)}
											title="Quitar concesión individual"
										>
											<Trash2 class="h-3 w-3 text-destructive" />
										</Button>
									</div>
								{/each}
							{/if}
						</div>
					</div>
				{/if}

				<!-- Permisos Revocados -->
				{#if effectiveRevokedVisibleCount > 0}
					<div class="space-y-2">
						<div class="flex items-center justify-between">
							<Label class="flex items-center gap-2 text-destructive">
								<AlertCircle class="h-4 w-4" />
								Permisos Revocados del Rol
							</Label>
							<Badge variant="destructive">
								{filteredRevokedPermissions.length}/{effectiveRevokedVisibleCount}
							</Badge>
						</div>
						<div class="max-h-48 space-y-1 overflow-y-auto rounded-lg border p-2">
							{#if filteredRevokedPermissions.length === 0}
								<div class="rounded px-3 py-2 text-sm text-muted-foreground">
									Sin coincidencias en permisos revocados
								</div>
							{:else}
								{#each filteredRevokedPermissions as perm}
									<div class="flex items-center justify-between gap-2 rounded px-3 py-2 hover:bg-accent/50">
										<div class="min-w-0 flex-1 space-y-1">
											<div class="flex flex-wrap items-center gap-2">
												<Badge variant="outline">{getModuleLabel(perm.module)}</Badge>
												<span class="text-sm font-medium">{getActionLabel(perm.action)}</span>
											</div>
											<div class="truncate text-sm font-medium line-through">
												{formatPermissionLabel(perm)}
											</div>
											<code class="text-xs text-muted-foreground">{perm.code}</code>
										</div>
										<Button
											variant="ghost"
											size="sm"
											onclick={() => handleRemoveUserPermission(perm.id)}
											title="Restaurar permiso (quitar revocación)"
										>
											<Trash2 class="h-3 w-3" />
										</Button>
									</div>
								{/each}
							{/if}
						</div>
					</div>
				{/if}

				<!-- Permisos del Rol (solo info + opción de revocar) -->
				{#if effectiveInheritedVisibleCount > 0}
					<div class="space-y-2 border-t pt-4">
						<div class="flex items-center justify-between">
							<Label class="text-muted-foreground">Permisos Heredados del Rol</Label>
							<Badge variant="outline">
								{filteredInheritedPermissions.length}/{effectiveInheritedVisibleCount}
							</Badge>
						</div>
						<div class="max-h-48 space-y-1 overflow-y-auto rounded-lg border p-2">
							{#if filteredInheritedPermissions.length === 0}
								<div class="rounded px-3 py-2 text-sm text-muted-foreground">
									Sin coincidencias en permisos heredados
								</div>
							{:else}
								{#each filteredInheritedPermissions as perm}
									<div
										class="flex items-start justify-between gap-2 rounded px-2 py-2 hover:bg-accent/30"
									>
										<div class="min-w-0 flex-1 space-y-1">
											<div class="flex flex-wrap items-center gap-2">
												<Badge variant="outline">{getModuleLabel(perm.module)}</Badge>
												<span class="text-sm font-medium text-foreground"
													>{getActionLabel(perm.action)}</span
												>
											</div>
											<div class="text-sm text-foreground">{formatPermissionLabel(perm)}</div>
											<code class="text-xs text-muted-foreground">{perm.code}</code>
										</div>
										{#if !effectivePermissions.revoked_permissions.some((r) => r.id === perm.id)}
											<Button
												variant="ghost"
												size="sm"
												class="shrink-0 self-start"
												onclick={() => handleRevokeUserPermission(perm.id)}
												title="Revocar este permiso para este usuario"
											>
												<span class="text-xs text-destructive">Revocar</span>
											</Button>
										{/if}
									</div>
								{/each}
							{/if}
						</div>
					</div>
				{/if}

				{#if userEffectiveHasActiveListFilters && !hasUserEffectiveSearchMatches}
					<div class="rounded-lg border border-dashed p-4 text-center text-sm text-muted-foreground">
						No hay permisos que coincidan con tu búsqueda o con los filtros de módulo y acción en
						concedidos, revocados o heredados.
					</div>
				{/if}
			{/if}
		</div>

		<Dialog.Footer class="flex-shrink-0">
			<Button
				variant="outline"
				onclick={() => {
					showUserPermissionsDialog = false;
					showRolesDialog = true;
				}}
			>
				Volver a Roles
			</Button>
			<div class="flex-1"></div>
			<Button
				variant="default"
				onclick={() => {
					showUserPermissionsDialog = false;
					openGrantUserPermDialog();
				}}
			>
				<Plus class="mr-2 h-4 w-4" />
				Conceder Permisos
			</Button>
			<Button onclick={() => (showUserPermissionsDialog = false)}>Cerrar</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>

<!-- Create/Edit Role Dialog -->
<Dialog.Root bind:open={showRoleDialog}>
	<Dialog.Content>
		<Dialog.Header>
			<Dialog.Title>
				{editingRole ? 'Editar Rol' : 'Nuevo Rol'}
			</Dialog.Title>
		</Dialog.Header>

		<div class="grid gap-4 py-4">
			<div class="grid gap-2">
				<Label for="role-name">Nombre</Label>
				<Input id="role-name" bind:value={roleFormData.name} placeholder="Administrador" />
			</div>

			<div class="grid gap-2">
				<Label for="role-code">Código</Label>
				<Input id="role-code" bind:value={roleFormData.code} placeholder="ADMIN" />
			</div>

			<div class="grid gap-2">
				<Label for="role-description">Descripción</Label>
				<Textarea
					id="role-description"
					bind:value={roleFormData.description}
					placeholder="Rol con acceso completo al sistema"
				/>
			</div>

			<div class="flex items-center space-x-2">
				<Switch id="role-is_active" bind:checked={roleFormData.is_active} />
				<Label for="role-is_active">Activo</Label>
			</div>
		</div>

		<Dialog.Footer>
			<Button variant="outline" onclick={() => (showRoleDialog = false)}>Cancelar</Button>
			<Button onclick={handleRoleSubmit}>
				{editingRole ? 'Actualizar' : 'Crear'}
			</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>

<!-- Delete Role Confirmation Dialog -->
<AlertDialog.Root bind:open={showDeleteRoleDialog}>
	<AlertDialog.Content>
		<AlertDialog.Header>
			<AlertDialog.Title>¿Eliminar rol permanentemente?</AlertDialog.Title>
			<AlertDialog.Description>
				{#if roleToDelete}
					Estás a punto de eliminar el rol <strong>"{roleToDelete.name}"</strong> de forma
					permanente.
					<br /><br />
					Esta acción <strong class="text-destructive">NO se puede deshacer</strong> y el rol será
					eliminado completamente del sistema.
					<br /><br />
					{#if rolePermissionsState.length > 0 && selectedRoleForPermissions?.id === roleToDelete.id}
						<span class="text-muted-foreground"
							>Este rol tiene {rolePermissionsState.length}
							{rolePermissionsState.length === 1 ? 'permiso asignado' : 'permisos asignados'}.</span
						>
					{/if}
					<br />
					Si solo deseas desactivarlo temporalmente, usa el interruptor "Activo" en el modo de edición.
				{/if}
			</AlertDialog.Description>
		</AlertDialog.Header>
		<AlertDialog.Footer>
			<AlertDialog.Cancel>Cancelar</AlertDialog.Cancel>
			<AlertDialog.Action
				onclick={confirmDeleteRole}
				class="bg-destructive hover:bg-destructive/90"
			>
				Eliminar permanentemente
			</AlertDialog.Action>
		</AlertDialog.Footer>
	</AlertDialog.Content>
</AlertDialog.Root>
