<script lang="ts">
	import { getApiBaseUrl } from '$lib/api/config';
	import { authenticatedFetch, getCurrentUserId } from '$lib/auth';
	import { updateUserRoles } from '$features/roles/api/roles';

	// Types
	interface User {
		id: string;
		email: string;
		role: string;
		roleLabel: string;
		roles: string[];
		firstName: string;
		lastName: string;
		statut: string;
		createdAt: string;
		invitedAt: string | null;
		activatedAt: string | null;
		blockedAt: string | null;
		blockedReason: string | null;
		invitationExpiree: boolean;
	}

	// Role options (admin can assign these roles)
	const ROLE_OPTIONS = [
		{ value: 'ROLE_SUPER_ADMIN', label: 'Super Admin' },
		{ value: 'ROLE_ADMIN', label: 'Directeur' },
		{ value: 'ROLE_PROF', label: 'Enseignant' },
		{ value: 'ROLE_VIE_SCOLAIRE', label: 'Vie Scolaire' },
		{ value: 'ROLE_SECRETARIAT', label: 'Secrétariat' },
		{ value: 'ROLE_PARENT', label: 'Parent' },
		{ value: 'ROLE_ELEVE', label: 'Élève' }
	];

	// Statut options for filter
	const STATUT_OPTIONS = [
		{ value: 'pending', label: 'En attente' },
		{ value: 'consent', label: 'Consentement requis' },
		{ value: 'active', label: 'Actif' },
		{ value: 'suspended', label: 'Suspendu' },
		{ value: 'archived', label: 'Archivé' }
	];

	// State
	let users = $state<User[]>([]);
	let isLoading = $state(true);
	let error = $state<string | null>(null);
	let successMessage = $state<string | null>(null);
	let showCreateModal = $state(false);

	// Filters
	let filterRole = $state<string>('');
	let filterStatut = $state<string>('');

	// Form state
	let newFirstName = $state('');
	let newLastName = $state('');
	let newEmail = $state('');
	let newRoles = $state<string[]>([]);
	let isSubmitting = $state(false);
	let isResending = $state<string | null>(null);

	// Block modal state
	let showBlockModal = $state(false);
	let blockTargetUser = $state<User | null>(null);
	let blockReason = $state('');
	let isBlocking = $state(false);
	let isUnblocking = $state<string | null>(null);

	// Roles modal state
	let showRolesModal = $state(false);
	let rolesTargetUser = $state<User | null>(null);
	let selectedRoles = $state<string[]>([]);
	let isSavingRoles = $state(false);

	// Load users on mount
	$effect(() => {
		loadUsers();
	});

	async function loadUsers() {
		try {
			isLoading = true;
			error = null;
			const apiUrl = getApiBaseUrl();
			const params = new URLSearchParams();
			if (filterRole) params.set('role', filterRole);
			if (filterStatut) params.set('statut', filterStatut);
			const queryString = params.toString();
			const url = `${apiUrl}/users${queryString ? `?${queryString}` : ''}`;
			const response = await authenticatedFetch(url);

			if (!response.ok) {
				throw new Error('Erreur lors du chargement des utilisateurs');
			}

			const data = await response.json();
			users = data['hydra:member'] ?? data['member'] ?? (Array.isArray(data) ? data : []);
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur inconnue';
			users = [];
		} finally {
			isLoading = false;
		}
	}

	function applyFilters() {
		loadUsers();
	}

	function resetFilters() {
		filterRole = '';
		filterStatut = '';
		loadUsers();
	}

	async function handleCreateUser() {
		if (!newFirstName.trim() || !newLastName.trim() || !newEmail.trim() || newRoles.length === 0) return;

		try {
			isSubmitting = true;
			error = null;
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(`${apiUrl}/users`, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify({
					firstName: newFirstName.trim(),
					lastName: newLastName.trim(),
					email: newEmail.trim().toLowerCase(),
					roles: newRoles
				})
			});

			if (!response.ok) {
				let errorMessage = `Erreur lors de la création (${response.status})`;
				try {
					const errorData = await response.json();
					if (errorData['hydra:description']) {
						errorMessage = errorData['hydra:description'];
					} else if (errorData.message) {
						errorMessage = errorData.message;
					} else if (errorData.detail) {
						errorMessage = errorData.detail;
					}
				} catch {
					// JSON parsing failed, keep default message
				}
				throw new Error(errorMessage);
			}

			successMessage = `L'invitation a été envoyée à ${newEmail.trim()}.`;
			await loadUsers();
			closeModal();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur lors de la création';
		} finally {
			isSubmitting = false;
		}
	}

	async function handleResendInvitation(userId: string) {
		try {
			isResending = userId;
			error = null;
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(`${apiUrl}/users/${userId}/resend-invitation`, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify({})
			});

			if (!response.ok) {
				let errorMessage = `Erreur lors du renvoi (${response.status})`;
				try {
					const errorData = await response.json();
					if (errorData['hydra:description']) {
						errorMessage = errorData['hydra:description'];
					} else if (errorData.message) {
						errorMessage = errorData.message;
					} else if (errorData.detail) {
						errorMessage = errorData.detail;
					}
				} catch {
					// JSON parsing failed, keep default message
				}
				throw new Error(errorMessage);
			}

			successMessage = 'L\'invitation a été renvoyée avec succès.';
			await loadUsers();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur lors du renvoi';
		} finally {
			isResending = null;
		}
	}

	function openCreateModal() {
		showCreateModal = true;
		newFirstName = '';
		newLastName = '';
		newEmail = '';
		newRoles = [];
		error = null;
	}

	function closeModal() {
		showCreateModal = false;
	}

	function getStatutLabel(statut: string): string {
		switch (statut) {
			case 'pending':
				return 'En attente';
			case 'consent':
				return 'Consentement requis';
			case 'active':
				return 'Actif';
			case 'suspended':
				return 'Suspendu';
			case 'archived':
				return 'Archivé';
			default:
				return statut;
		}
	}

	function getStatutClass(statut: string, invitationExpiree: boolean): string {
		if (invitationExpiree) return 'status-expired';
		switch (statut) {
			case 'active':
				return 'status-active';
			case 'pending':
			case 'consent':
				return 'status-pending';
			case 'suspended':
				return 'status-blocked';
			case 'archived':
				return 'status-archived';
			default:
				return '';
		}
	}

	function getStatutDisplay(statut: string, invitationExpiree: boolean): string {
		if (invitationExpiree) return 'Invitation expirée';
		return getStatutLabel(statut);
	}

	function canResendInvitation(user: User): boolean {
		return user.statut === 'pending' || user.statut === 'consent';
	}

	function canBlockUser(user: User): boolean {
		return user.statut === 'active' && user.id !== getCurrentUserId();
	}

	function openBlockModal(user: User) {
		blockTargetUser = user;
		blockReason = '';
		showBlockModal = true;
	}

	function closeBlockModal() {
		showBlockModal = false;
		blockTargetUser = null;
		blockReason = '';
	}

	async function handleBlockUser() {
		if (!blockTargetUser || !blockReason.trim()) return;

		try {
			isBlocking = true;
			error = null;
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(`${apiUrl}/users/${blockTargetUser.id}/block`, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify({
					reason: blockReason.trim()
				})
			});

			if (!response.ok) {
				let errorMessage = `Erreur lors du blocage (${response.status})`;
				try {
					const errorData = await response.json();
					if (errorData['hydra:description']) {
						errorMessage = errorData['hydra:description'];
					} else if (errorData.message) {
						errorMessage = errorData.message;
					} else if (errorData.detail) {
						errorMessage = errorData.detail;
					}
				} catch {
					// JSON parsing failed, keep default message
				}
				throw new Error(errorMessage);
			}

			successMessage = `L'utilisateur ${blockTargetUser.firstName} ${blockTargetUser.lastName} a été bloqué.`;
			closeBlockModal();
			await loadUsers();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur lors du blocage';
		} finally {
			isBlocking = false;
		}
	}

	async function handleUnblockUser(user: User) {
		try {
			isUnblocking = user.id;
			error = null;
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(`${apiUrl}/users/${user.id}/unblock`, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify({})
			});

			if (!response.ok) {
				let errorMessage = `Erreur lors du déblocage (${response.status})`;
				try {
					const errorData = await response.json();
					if (errorData['hydra:description']) {
						errorMessage = errorData['hydra:description'];
					} else if (errorData.message) {
						errorMessage = errorData.message;
					} else if (errorData.detail) {
						errorMessage = errorData.detail;
					}
				} catch {
					// JSON parsing failed, keep default message
				}
				throw new Error(errorMessage);
			}

			successMessage = `L'utilisateur ${user.firstName} ${user.lastName} a été débloqué.`;
			await loadUsers();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur lors du déblocage';
		} finally {
			isUnblocking = null;
		}
	}

	function openRolesModal(user: User) {
		rolesTargetUser = user;
		selectedRoles = [...(user.roles ?? [user.role])];
		showRolesModal = true;
		error = null;
	}

	function closeRolesModal() {
		showRolesModal = false;
		rolesTargetUser = null;
		selectedRoles = [];
	}

	function toggleRole(roleValue: string) {
		if (selectedRoles.includes(roleValue)) {
			if (selectedRoles.length > 1) {
				selectedRoles = selectedRoles.filter((r) => r !== roleValue);
			}
		} else {
			selectedRoles = [...selectedRoles, roleValue];
		}
	}

	async function handleSaveRoles() {
		if (!rolesTargetUser || selectedRoles.length === 0) return;

		try {
			isSavingRoles = true;
			error = null;
			await updateUserRoles(rolesTargetUser.id, selectedRoles);
			successMessage = `Les rôles de ${rolesTargetUser.firstName} ${rolesTargetUser.lastName} ont été mis à jour.`;
			closeRolesModal();
			await loadUsers();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur lors de la mise à jour des rôles';
		} finally {
			isSavingRoles = false;
		}
	}

	function toggleNewRole(roleValue: string) {
		if (newRoles.includes(roleValue)) {
			newRoles = newRoles.filter((r) => r !== roleValue);
		} else {
			newRoles = [...newRoles, roleValue];
		}
	}

	function getRoleLabelByValue(roleValue: string): string {
		const found = ROLE_OPTIONS.find((r) => r.value === roleValue);
		return found?.label ?? roleValue;
	}

	function formatDate(dateStr: string | null): string {
		if (!dateStr) return '-';
		return new Date(dateStr).toLocaleDateString('fr-FR', {
			day: '2-digit',
			month: '2-digit',
			year: 'numeric'
		});
	}
</script>

<svelte:head>
	<title>Gestion des utilisateurs - Classeo</title>
</svelte:head>

<div class="users-page">
	<header class="page-header">
		<div class="header-content">
			<h1>Gestion des utilisateurs</h1>
			<p class="subtitle">Invitez et gérez les utilisateurs de votre établissement</p>
		</div>
		<button class="btn-primary" onclick={openCreateModal}>
			<span class="btn-icon">+</span>
			Inviter un utilisateur
		</button>
	</header>

	{#if error}
		<div class="alert alert-error">
			{error}
			<button class="alert-close" onclick={() => (error = null)}>×</button>
		</div>
	{/if}

	{#if successMessage}
		<div class="alert alert-success">
			{successMessage}
			<button class="alert-close" onclick={() => (successMessage = null)}>×</button>
		</div>
	{/if}

	<!-- Filters -->
	<div class="filters-bar">
		<div class="filter-group">
			<label for="filter-role">Rôle</label>
			<select id="filter-role" bind:value={filterRole}>
				<option value="">Tous les rôles</option>
				{#each ROLE_OPTIONS as role}
					<option value={role.value}>{role.label}</option>
				{/each}
			</select>
		</div>
		<div class="filter-group">
			<label for="filter-statut">Statut</label>
			<select id="filter-statut" bind:value={filterStatut}>
				<option value="">Tous les statuts</option>
				{#each STATUT_OPTIONS as statut}
					<option value={statut.value}>{statut.label}</option>
				{/each}
			</select>
		</div>
		<div class="filter-actions">
			<button class="btn-secondary btn-sm" onclick={applyFilters}>Filtrer</button>
			<button class="btn-text btn-sm" onclick={resetFilters}>Réinitialiser</button>
		</div>
	</div>

	{#if isLoading}
		<div class="loading-state">
			<div class="spinner"></div>
			<p>Chargement des utilisateurs...</p>
		</div>
	{:else if users.length === 0}
		<div class="empty-state">
			<span class="empty-icon">👥</span>
			<h2>Aucun utilisateur</h2>
			<p>Commencez par inviter votre premier utilisateur</p>
			<button class="btn-primary" onclick={openCreateModal}>Inviter un utilisateur</button>
		</div>
	{:else}
		<div class="users-table-container">
			<table class="users-table">
				<thead>
					<tr>
						<th>Nom</th>
						<th>Email</th>
						<th>Rôle</th>
						<th>Statut</th>
						<th>Date d'invitation</th>
						<th>Actions</th>
					</tr>
				</thead>
				<tbody>
					{#each users as user (user.id)}
						<tr>
							<td class="user-name-cell">
								<span class="user-fullname">{user.firstName} {user.lastName}</span>
							</td>
							<td class="user-email">{user.email}</td>
							<td>
								<div class="role-badges">
									{#if user.roles && user.roles.length > 0}
										{#each user.roles as roleValue}
											<span class="role-badge">{getRoleLabelByValue(roleValue)}</span>
										{/each}
									{:else}
										<span class="role-badge">{user.roleLabel}</span>
									{/if}
								</div>
							</td>
							<td>
								<span class="status-badge {getStatutClass(user.statut, user.invitationExpiree)}">
									{getStatutDisplay(user.statut, user.invitationExpiree)}
								</span>
								{#if user.statut === 'suspended' && user.blockedReason}
									<span class="blocked-reason" title={user.blockedReason}>
										{user.blockedReason}
									</span>
								{/if}
							</td>
							<td class="date-cell">{formatDate(user.invitedAt)}</td>
							<td class="actions-cell">
								{#if user.id !== getCurrentUserId()}
									<button
										class="btn-secondary btn-sm"
										onclick={() => openRolesModal(user)}
									>
										Rôles
									</button>
								{/if}
								{#if canResendInvitation(user)}
									<button
										class="btn-secondary btn-sm"
										onclick={() => handleResendInvitation(user.id)}
										disabled={isResending === user.id}
									>
										{#if isResending === user.id}
											Envoi...
										{:else}
											Renvoyer l'invitation
										{/if}
									</button>
								{/if}
								{#if canBlockUser(user)}
									<button
										class="btn-danger btn-sm"
										onclick={() => openBlockModal(user)}
									>
										Bloquer
									</button>
								{/if}
								{#if user.statut === 'suspended'}
									<button
										class="btn-success btn-sm"
										onclick={() => handleUnblockUser(user)}
										disabled={isUnblocking === user.id}
									>
										{#if isUnblocking === user.id}
											Déblocage...
										{:else}
											Débloquer
										{/if}
									</button>
								{/if}
							</td>
						</tr>
					{/each}
				</tbody>
			</table>
		</div>
	{/if}
</div>

<!-- Create User Modal -->
{#if showCreateModal}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="modal-overlay" onclick={closeModal} role="presentation">
		<div
			class="modal"
			role="dialog"
			aria-modal="true"
			aria-labelledby="modal-title"
			tabindex="-1"
			onclick={(e) => e.stopPropagation()}
			onkeydown={(e) => { if (e.key === 'Escape') closeModal(); }}
		>
			<header class="modal-header">
				<h2 id="modal-title">Inviter un utilisateur</h2>
				<button class="modal-close" onclick={closeModal} aria-label="Fermer">×</button>
			</header>

			<form
				class="modal-body"
				onsubmit={(e) => {
					e.preventDefault();
					handleCreateUser();
				}}
			>
				<div class="form-row">
					<div class="form-group">
						<label for="user-firstname">Prénom *</label>
						<input
							type="text"
							id="user-firstname"
							bind:value={newFirstName}
							placeholder="ex: Marie"
							required
							minlength="2"
							maxlength="100"
						/>
					</div>
					<div class="form-group">
						<label for="user-lastname">Nom *</label>
						<input
							type="text"
							id="user-lastname"
							bind:value={newLastName}
							placeholder="ex: Dupont"
							required
							minlength="2"
							maxlength="100"
						/>
					</div>
				</div>

				<div class="form-group">
					<label for="user-email">Email *</label>
					<input
						type="email"
						id="user-email"
						bind:value={newEmail}
						placeholder="ex: marie.dupont@email.com"
						required
					/>
				</div>

				<fieldset class="roles-fieldset">
					<legend class="roles-legend">Rôle(s) *</legend>
					{#each ROLE_OPTIONS as role}
						<label class="role-checkbox-label">
							<input
								type="checkbox"
								checked={newRoles.includes(role.value)}
								onchange={() => toggleNewRole(role.value)}
							/>
							<span class="role-checkbox-text">{role.label}</span>
						</label>
					{/each}
				</fieldset>

				<div class="form-hint-block">
					Un email d'invitation sera automatiquement envoyé à l'utilisateur.
					L'invitation expire au bout de 7 jours.
				</div>

				<div class="modal-actions">
					<button type="button" class="btn-secondary" onclick={closeModal} disabled={isSubmitting}>
						Annuler
					</button>
					<button
						type="submit"
						class="btn-primary"
						disabled={isSubmitting || !newFirstName.trim() || !newLastName.trim() || !newEmail.trim() || newRoles.length === 0}
					>
						{#if isSubmitting}
							Envoi de l'invitation...
						{:else}
							Envoyer l'invitation
						{/if}
					</button>
				</div>
			</form>
		</div>
	</div>
{/if}

<!-- Block User Modal -->
{#if showBlockModal && blockTargetUser}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="modal-overlay" onclick={closeBlockModal} role="presentation">
		<div
			class="modal"
			role="dialog"
			aria-modal="true"
			aria-labelledby="block-modal-title"
			tabindex="-1"
			onclick={(e) => e.stopPropagation()}
			onkeydown={(e) => { if (e.key === 'Escape') closeBlockModal(); }}
		>
			<header class="modal-header">
				<h2 id="block-modal-title">Bloquer un utilisateur</h2>
				<button class="modal-close" onclick={closeBlockModal} aria-label="Fermer">×</button>
			</header>

			<form
				class="modal-body"
				onsubmit={(e) => {
					e.preventDefault();
					handleBlockUser();
				}}
			>
				<div class="block-warning">
					Vous allez bloquer <strong>{blockTargetUser.firstName} {blockTargetUser.lastName}</strong> ({blockTargetUser.email}).
					L'utilisateur ne pourra plus se connecter.
				</div>

				<div class="form-group">
					<label for="block-reason">Raison du blocage *</label>
					<textarea
						id="block-reason"
						bind:value={blockReason}
						placeholder="ex: Comportement inapproprié, compte compromis..."
						required
						rows="3"
					></textarea>
				</div>

				<div class="modal-actions">
					<button type="button" class="btn-secondary" onclick={closeBlockModal} disabled={isBlocking}>
						Annuler
					</button>
					<button
						type="submit"
						class="btn-danger"
						disabled={isBlocking || !blockReason.trim()}
					>
						{#if isBlocking}
							Blocage en cours...
						{:else}
							Confirmer le blocage
						{/if}
					</button>
				</div>
			</form>
		</div>
	</div>
{/if}

<!-- Edit Roles Modal -->
{#if showRolesModal && rolesTargetUser}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="modal-overlay" onclick={closeRolesModal} role="presentation">
		<div
			class="modal"
			role="dialog"
			aria-modal="true"
			aria-labelledby="roles-modal-title"
			tabindex="-1"
			onclick={(e) => e.stopPropagation()}
			onkeydown={(e) => { if (e.key === 'Escape') closeRolesModal(); }}
		>
			<header class="modal-header">
				<h2 id="roles-modal-title">Modifier les rôles</h2>
				<button class="modal-close" onclick={closeRolesModal} aria-label="Fermer">×</button>
			</header>

			<div class="modal-body">
				<p class="roles-modal-user">
					{rolesTargetUser.firstName} {rolesTargetUser.lastName} ({rolesTargetUser.email})
				</p>

				<fieldset class="roles-fieldset">
					<legend class="roles-legend">Rôles attribués</legend>
					{#each ROLE_OPTIONS as role}
						<label class="role-checkbox-label">
							<input
								type="checkbox"
								checked={selectedRoles.includes(role.value)}
								onchange={() => toggleRole(role.value)}
								disabled={selectedRoles.includes(role.value) && selectedRoles.length === 1}
							/>
							<span class="role-checkbox-text">{role.label}</span>
							{#if selectedRoles.includes(role.value) && selectedRoles.length === 1}
								<span class="role-checkbox-hint">(dernier rôle)</span>
							{/if}
						</label>
					{/each}
				</fieldset>

				<div class="form-hint-block">
					Un utilisateur doit avoir au moins un rôle. Les utilisateurs avec plusieurs rôles
					pourront basculer entre leurs différentes vues.
				</div>

				<div class="modal-actions">
					<button type="button" class="btn-secondary" onclick={closeRolesModal} disabled={isSavingRoles}>
						Annuler
					</button>
					<button
						type="button"
						class="btn-primary"
						onclick={handleSaveRoles}
						disabled={isSavingRoles || selectedRoles.length === 0}
					>
						{#if isSavingRoles}
							Enregistrement...
						{:else}
							Enregistrer
						{/if}
					</button>
				</div>
			</div>
		</div>
	</div>
{/if}

<style>
	.users-page {
		padding: 1.5rem;
		max-width: 1200px;
		margin: 0 auto;
	}

	.page-header {
		display: flex;
		justify-content: space-between;
		align-items: flex-start;
		gap: 1rem;
		margin-bottom: 1.5rem;
		flex-wrap: wrap;
	}

	.header-content h1 {
		margin: 0;
		font-size: 1.5rem;
		font-weight: 700;
		color: #1f2937;
	}

	.subtitle {
		margin: 0.25rem 0 0;
		color: #6b7280;
		font-size: 0.875rem;
	}

	/* Buttons */
	.btn-primary {
		display: inline-flex;
		align-items: center;
		gap: 0.5rem;
		padding: 0.75rem 1.25rem;
		background: #3b82f6;
		color: white;
		border: none;
		border-radius: 0.5rem;
		font-weight: 600;
		cursor: pointer;
		transition: background 0.2s;
	}

	.btn-primary:hover:not(:disabled) {
		background: #2563eb;
	}

	.btn-primary:disabled {
		opacity: 0.6;
		cursor: not-allowed;
	}

	.btn-secondary {
		padding: 0.5rem 1rem;
		background: white;
		color: #374151;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-weight: 500;
		cursor: pointer;
		transition: all 0.2s;
	}

	.btn-secondary:hover:not(:disabled) {
		background: #f3f4f6;
	}

	.btn-secondary:disabled {
		opacity: 0.6;
		cursor: not-allowed;
	}

	.btn-danger {
		display: inline-flex;
		align-items: center;
		gap: 0.5rem;
		padding: 0.5rem 1rem;
		background: #dc2626;
		color: white;
		border: none;
		border-radius: 0.375rem;
		font-weight: 500;
		cursor: pointer;
		transition: background 0.2s;
	}

	.btn-danger:hover:not(:disabled) {
		background: #b91c1c;
	}

	.btn-danger:disabled {
		opacity: 0.6;
		cursor: not-allowed;
	}

	.btn-success {
		display: inline-flex;
		align-items: center;
		gap: 0.5rem;
		padding: 0.5rem 1rem;
		background: #16a34a;
		color: white;
		border: none;
		border-radius: 0.375rem;
		font-weight: 500;
		cursor: pointer;
		transition: background 0.2s;
	}

	.btn-success:hover:not(:disabled) {
		background: #15803d;
	}

	.btn-success:disabled {
		opacity: 0.6;
		cursor: not-allowed;
	}

	.btn-text {
		padding: 0.5rem 1rem;
		background: none;
		color: #6b7280;
		border: none;
		border-radius: 0.375rem;
		font-weight: 500;
		cursor: pointer;
		transition: color 0.2s;
	}

	.btn-text:hover {
		color: #374151;
	}

	.btn-sm {
		padding: 0.375rem 0.75rem;
		font-size: 0.875rem;
	}

	.btn-icon {
		font-size: 1.25rem;
		line-height: 1;
	}

	/* Alerts */
	.alert {
		display: flex;
		align-items: center;
		gap: 0.75rem;
		padding: 1rem;
		border-radius: 0.5rem;
		margin-bottom: 1rem;
	}

	.alert-error {
		background: #fef2f2;
		border: 1px solid #fecaca;
		color: #dc2626;
	}

	.alert-success {
		background: #f0fdf4;
		border: 1px solid #bbf7d0;
		color: #16a34a;
	}

	.alert-close {
		margin-left: auto;
		padding: 0.25rem 0.5rem;
		background: none;
		border: none;
		font-size: 1.25rem;
		cursor: pointer;
		opacity: 0.6;
	}

	.alert-close:hover {
		opacity: 1;
	}

	/* Filters */
	.filters-bar {
		display: flex;
		align-items: flex-end;
		gap: 1rem;
		margin-bottom: 1.5rem;
		padding: 1rem;
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 0.75rem;
		flex-wrap: wrap;
	}

	.filter-group {
		display: flex;
		flex-direction: column;
		gap: 0.25rem;
	}

	.filter-group label {
		font-size: 0.75rem;
		font-weight: 500;
		color: #6b7280;
		text-transform: uppercase;
		letter-spacing: 0.05em;
	}

	.filter-group select {
		padding: 0.5rem 0.75rem;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-size: 0.875rem;
		min-width: 180px;
		background: white;
	}

	.filter-group select:focus {
		outline: none;
		border-color: #3b82f6;
		box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
	}

	.filter-actions {
		display: flex;
		gap: 0.5rem;
		align-items: center;
	}

	/* Loading & Empty */
	.loading-state,
	.empty-state {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		padding: 3rem;
		text-align: center;
		background: white;
		border-radius: 0.75rem;
		border: 2px dashed #e5e7eb;
	}

	.spinner {
		width: 2rem;
		height: 2rem;
		border: 3px solid #e5e7eb;
		border-top-color: #3b82f6;
		border-radius: 50%;
		animation: spin 0.8s linear infinite;
	}

	@keyframes spin {
		to {
			transform: rotate(360deg);
		}
	}

	.empty-icon {
		font-size: 3rem;
		margin-bottom: 1rem;
	}

	.empty-state h2 {
		margin: 0 0 0.5rem;
		font-size: 1.25rem;
		color: #1f2937;
	}

	.empty-state p {
		margin: 0 0 1.5rem;
		color: #6b7280;
	}

	/* Table */
	.users-table-container {
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 0.75rem;
		overflow-x: auto;
	}

	.users-table {
		width: 100%;
		border-collapse: collapse;
	}

	.users-table th {
		text-align: left;
		padding: 0.75rem 1rem;
		font-size: 0.75rem;
		font-weight: 600;
		color: #6b7280;
		text-transform: uppercase;
		letter-spacing: 0.05em;
		border-bottom: 1px solid #e5e7eb;
		background: #f9fafb;
	}

	.users-table td {
		padding: 0.75rem 1rem;
		font-size: 0.875rem;
		color: #374151;
		border-bottom: 1px solid #f3f4f6;
	}

	.users-table tr:last-child td {
		border-bottom: none;
	}

	.users-table tr:hover td {
		background: #f9fafb;
	}

	.user-name-cell {
		white-space: nowrap;
	}

	.user-fullname {
		font-weight: 500;
		color: #1f2937;
	}

	.user-email {
		color: #6b7280;
	}

	.date-cell {
		white-space: nowrap;
		color: #6b7280;
	}

	.actions-cell {
		white-space: nowrap;
		display: flex;
		gap: 0.5rem;
		align-items: center;
	}

	/* Badges */
	.role-badge {
		display: inline-block;
		padding: 0.125rem 0.5rem;
		background: #eff6ff;
		color: #3b82f6;
		border-radius: 9999px;
		font-size: 0.75rem;
		font-weight: 500;
	}

	.status-badge {
		display: inline-block;
		padding: 0.125rem 0.5rem;
		border-radius: 9999px;
		font-size: 0.75rem;
		font-weight: 500;
	}

	.status-active {
		background: #f0fdf4;
		color: #16a34a;
	}

	.status-pending {
		background: #fffbeb;
		color: #d97706;
	}

	.status-expired {
		background: #fef2f2;
		color: #dc2626;
	}

	.status-blocked {
		background: #fef2f2;
		color: #dc2626;
	}

	.status-archived {
		background: #f3f4f6;
		color: #6b7280;
	}

	.blocked-reason {
		display: block;
		margin-top: 0.25rem;
		font-size: 0.75rem;
		color: #6b7280;
		font-style: italic;
		max-width: 200px;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	/* Modal */
	.modal-overlay {
		position: fixed;
		inset: 0;
		background: rgba(0, 0, 0, 0.5);
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 1rem;
		z-index: 100;
	}

	.modal {
		background: white;
		border-radius: 0.75rem;
		width: 100%;
		max-width: 32rem;
		max-height: 90vh;
		overflow: auto;
		box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
	}

	.modal-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 1.25rem 1.5rem;
		border-bottom: 1px solid #e5e7eb;
	}

	.modal-header h2 {
		margin: 0;
		font-size: 1.125rem;
		font-weight: 600;
		color: #1f2937;
	}

	.modal-close {
		padding: 0.25rem 0.5rem;
		background: none;
		border: none;
		font-size: 1.5rem;
		line-height: 1;
		color: #6b7280;
		cursor: pointer;
	}

	.modal-close:hover {
		color: #1f2937;
	}

	.modal-body {
		padding: 1.5rem;
	}

	.form-row {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 1rem;
	}

	.form-group {
		margin-bottom: 1.25rem;
	}

	.form-group label {
		display: block;
		margin-bottom: 0.5rem;
		font-weight: 500;
		color: #374151;
	}

	.form-group input {
		width: 100%;
		padding: 0.75rem 1rem;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-size: 1rem;
		transition: border-color 0.2s;
	}

	.form-group input:focus {
		outline: none;
		border-color: #3b82f6;
		box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
	}

	.block-warning {
		padding: 0.75rem 1rem;
		background: #fef2f2;
		border: 1px solid #fecaca;
		border-radius: 0.375rem;
		font-size: 0.875rem;
		color: #dc2626;
		margin-bottom: 1.25rem;
		line-height: 1.5;
	}

	.form-group textarea {
		width: 100%;
		padding: 0.75rem 1rem;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-size: 1rem;
		font-family: inherit;
		resize: vertical;
		transition: border-color 0.2s;
	}

	.form-group textarea:focus {
		outline: none;
		border-color: #3b82f6;
		box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
	}

	.form-hint-block {
		padding: 0.75rem 1rem;
		background: #eff6ff;
		border-radius: 0.375rem;
		font-size: 0.875rem;
		color: #3b82f6;
		margin-bottom: 1.25rem;
	}

	.modal-actions {
		display: flex;
		justify-content: flex-end;
		gap: 0.75rem;
		padding-top: 1rem;
		border-top: 1px solid #e5e7eb;
	}

	/* Role badges */
	.role-badges {
		display: flex;
		flex-wrap: wrap;
		gap: 0.25rem;
	}

	/* Roles modal */
	.roles-modal-user {
		margin: 0 0 1.25rem;
		font-size: 0.875rem;
		color: #6b7280;
	}

	.roles-fieldset {
		border: 1px solid #e5e7eb;
		border-radius: 0.5rem;
		padding: 1rem;
		margin: 0 0 1.25rem;
	}

	.roles-legend {
		font-size: 0.875rem;
		font-weight: 600;
		color: #374151;
		padding: 0 0.5rem;
	}

	.role-checkbox-label {
		display: flex;
		align-items: center;
		gap: 0.5rem;
		padding: 0.5rem 0;
		cursor: pointer;
	}

	.role-checkbox-label input[type='checkbox'] {
		width: 1rem;
		height: 1rem;
		accent-color: #3b82f6;
	}

	.role-checkbox-text {
		font-size: 0.875rem;
		color: #374151;
	}

	.role-checkbox-hint {
		font-size: 0.75rem;
		color: #9ca3af;
		font-style: italic;
	}

	@media (max-width: 768px) {
		.filters-bar {
			flex-direction: column;
			align-items: stretch;
		}

		.filter-group select {
			min-width: auto;
			width: 100%;
		}

		.form-row {
			grid-template-columns: 1fr;
		}

		.users-table th:nth-child(5),
		.users-table td:nth-child(5) {
			display: none;
		}
	}
</style>
