// #region AdminRolesPageTest [C:2] [TYPE Module] [SEMANTICS test,admin,roles,rbac,page]
// @BRIEF Verify Admin Roles page renders correctly after data load and shows loading state transitions.
// @RELATION BINDS_TO -> [AdminRolesPage]
// @TEST_CONTRACT: loading state -> loading text visible during fetch, table visible after
// @TEST_CONTRACT: roles list -> mock roles appear in table after adminService resolves
// @TEST_EDGE: error state -> error message displayed on API failure

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/svelte';
import AdminRolesPage from '../roles/+page.svelte';

// ── i18n mock ─────────────────────────────────────────────────────
const mockTranslations = {
	common: {
		loading: 'Loading...',
		error: 'Error',
		edit: 'Edit',
		delete: 'Delete',
		cancel: 'Cancel',
		save: 'Save',
		actions: 'Actions',
	},
	admin: {
		roles: {
			title: 'Role Management',
			create: 'Create Role',
			name: 'Role Name',
			description: 'Description',
			permissions: 'Permissions',
			loading: 'Loading roles...',
			no_roles: 'No roles found.',
			modal_create_title: 'Create New Role',
			modal_edit_title: 'Edit Role',
			permissions_hint: 'Select permissions for this role.',
			confirm_delete: 'Are you sure?',
			load_failed: 'Failed to load roles data.',
			save_failed: 'Failed to save role: {error}',
			delete_failed: 'Failed to delete role: {error}',
		}
	}
};

vi.mock('$lib/i18n/index.svelte.js', () => ({
	t: {
		subscribe: (fn: (v: unknown) => void) => {
			fn(mockTranslations);
			return () => {};
		}
	},
	getT: () => mockTranslations,
	_: (key: string) => key,
}));

// ── Logger mock ───────────────────────────────────────────────────
vi.mock('$lib/cot-logger', () => ({
	log: vi.fn(),
	setTraceId: vi.fn(),
	getTraceId: vi.fn(() => 'test-trace-id'),
}));

// ── $app mocks (for ProtectedRoute) ───────────────────────────────
vi.mock('$app/navigation', () => ({
	goto: vi.fn(),
	push: vi.fn(),
	replace: vi.fn(),
	prefetch: vi.fn(),
	prefetchRoutes: vi.fn(),
}));

vi.mock('$app/environment', () => ({
	browser: true,
	dev: true,
	building: false,
}));

// ── Auth mock (authenticated admin user) ──────────────────────────
vi.mock('$lib/auth/store.svelte.js', () => {
	const authState = {
		user: { username: 'admin', roles: ['admin'] },
		token: 'admin-token',
		isAuthenticated: true,
		loading: false,
	};
	return {
		auth: {
			subscribe: (fn: (v: typeof authState) => void) => {
				fn(authState);
				return () => {};
			},
			setToken: vi.fn(),
			setUser: vi.fn(),
			logout: vi.fn(),
			setLoading: vi.fn(),
		}
	};
});

vi.mock('$lib/auth/permissions.js', () => ({
	hasPermission: () => true,
}));

// ── Admin service mock (hoisted) ──────────────────────────────────
const mockGetRoles = vi.hoisted(() => vi.fn());
const mockGetPermissions = vi.hoisted(() => vi.fn());
vi.mock('../../../services/adminService', () => ({
	adminService: {
		getRoles: mockGetRoles,
		getPermissions: mockGetPermissions,
		createRole: vi.fn(),
		updateRole: vi.fn(),
		deleteRole: vi.fn(),
	}
}));

// #region AdminRolesPageTest.Describe [C:2] [TYPE Test]
// @BRIEF Test rendering and state transitions for the Admin Roles page.
describe('Admin Roles Page', () => {
	const mockRoles = [
		{
			id: 'r1',
			name: 'Admin',
			description: 'Full system access',
			permissions: [{ id: 'p1', resource: 'all', action: '*' }],
		},
		{
			id: 'r2',
			name: 'Viewer',
			description: 'Read-only access',
			permissions: [{ id: 'p2', resource: 'dashboard', action: 'read' }],
		},
	];
	const mockPermissions = [
		{ id: 'p1', resource: 'all', action: '*' },
		{ id: 'p2', resource: 'dashboard', action: 'read' },
	];

	beforeEach(() => {
		vi.clearAllMocks();
		mockGetRoles.mockResolvedValue(mockRoles);
		mockGetPermissions.mockResolvedValue(mockPermissions);
	});

	// #region test_roles_page_renders_after_load [C:2] [TYPE Test]
	// @BRIEF After adminService resolves, the roles table is rendered with role data.
	it('renders roles table after data loads', async () => {
		render(AdminRolesPage);

		// Wait for the loaded state — roles table should show role names
		await waitFor(() => {
			expect(screen.getByText('Admin')).toBeTruthy();
		});

		expect(screen.getByText('Viewer')).toBeTruthy();
		expect(screen.getByText('Full system access')).toBeTruthy();
		expect(screen.getByText('Read-only access')).toBeTruthy();

		// Loading text should no longer be visible
		expect(screen.queryByText('Loading roles...')).toBeNull();
	});
	// #endregion test_roles_page_renders_after_load

	// #region test_loading_state_transitions [C:2] [TYPE Test]
	// @BRIEF Loading text appears initially, then disappears after data resolves.
	it('shows loading state initially, then renders table after data resolves', async () => {
		render(AdminRolesPage);

		// "Loading roles..." should be visible immediately (loading=true)
		expect(screen.getByText('Loading roles...')).toBeTruthy();

		// Wait for the mock promises to resolve
		await waitFor(() => {
			expect(screen.getByText('Admin')).toBeTruthy();
		});

		// Loading text should be gone
		expect(screen.queryByText('Loading roles...')).toBeNull();
	});
	// #endregion test_loading_state_transitions
});
// #endregion AdminRolesPageTest.Describe
// #endregion AdminRolesPageTest
