import { afterEach, beforeEach, describe, it, expect, vi } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import UsersListPanel from './UsersListPanel.svelte';

vi.mock('$app/state', () => ({
	page: { url: { pathname: '/admin/users/u1' } }
}));

afterEach(cleanup);

const users = [
	{
		id: 'u1',
		email: 'reader@example.com',
		firstName: 'Lea',
		lastName: 'Leserin',
		groups: [{ id: 'g1', name: 'Leser', permissions: ['READ_ALL'] }]
	},
	{
		id: 'u2',
		email: 'admin@example.com',
		firstName: null,
		lastName: null,
		groups: [{ id: 'g2', name: 'Admins', permissions: ['ADMIN'] }]
	}
];

describe('UsersListPanel — header', () => {
	it('renders the panel title', async () => {
		render(UsersListPanel, { users });
		await expect.element(page.getByText(/Alle Benutzer/i)).toBeInTheDocument();
	});

	it('renders a new-user link pointing to /admin/users/new', async () => {
		render(UsersListPanel, { users });
		await expect
			.element(page.getByRole('link', { name: /neuer benutzer/i }))
			.toHaveAttribute('href', '/admin/users/new');
	});

	it('renders a search input', async () => {
		render(UsersListPanel, { users });
		await expect.element(page.getByRole('searchbox')).toBeInTheDocument();
	});
});

describe('UsersListPanel — user items', () => {
	it('renders each email', async () => {
		render(UsersListPanel, { users });
		await expect.element(page.getByText('reader@example.com')).toBeInTheDocument();
		await expect.element(page.getByText('admin@example.com')).toBeInTheDocument();
	});

	it('each user links to /admin/users/[id]', async () => {
		const { container } = render(UsersListPanel, { users });
		const links = container.querySelectorAll<HTMLAnchorElement>('a[href^="/admin/users/u"]');
		expect(links.length).toBe(2);
		expect(links[0].getAttribute('href')).toBe('/admin/users/u1');
		expect(links[1].getAttribute('href')).toBe('/admin/users/u2');
	});

	it('shows full name as subtitle when available', async () => {
		render(UsersListPanel, { users });
		await expect.element(page.getByText('Lea Leserin')).toBeInTheDocument();
	});

	it('shows group name chip', async () => {
		render(UsersListPanel, { users });
		await expect.element(page.getByText('Leser', { exact: true })).toBeInTheDocument();
	});
});

describe('UsersListPanel — active state', () => {
	it('marks the active user link with aria-current=page', async () => {
		render(UsersListPanel, { users });
		await expect
			.element(page.getByRole('link', { name: /reader/i }))
			.toHaveAttribute('aria-current', 'page');
	});

	it('does not mark the inactive user link with aria-current', async () => {
		render(UsersListPanel, { users });
		await expect
			.element(page.getByRole('link', { name: /admin/i }))
			.not.toHaveAttribute('aria-current');
	});
});

describe('UsersListPanel — empty state', () => {
	it('shows empty state message when users array is empty', async () => {
		render(UsersListPanel, { users: [] });
		await expect.element(page.getByText(/keine benutzer/i)).toBeInTheDocument();
	});
});

// ─── Collapse toggle ──────────────────────────────────────────────────────────

describe('UsersListPanel — collapse toggle', () => {
	beforeEach(() => localStorage.removeItem('admin_users_list_collapsed'));

	it('renders a collapse button with aria-label', async () => {
		render(UsersListPanel, { users });
		await expect
			.element(page.getByRole('button', { name: /Liste einklappen/i }))
			.toBeInTheDocument();
	});

	it('clicking collapse shows the expand handle', async () => {
		render(UsersListPanel, { users });
		await page.getByRole('button', { name: /Liste einklappen/i }).click();
		await expect
			.element(page.getByRole('button', { name: /Liste ausklappen/i }))
			.toBeInTheDocument();
	});

	it('clicking expand handle restores the full panel', async () => {
		render(UsersListPanel, { users });
		await page.getByRole('button', { name: /Liste einklappen/i }).click();
		await page.getByRole('button', { name: /Liste ausklappen/i }).click();
		await expect
			.element(page.getByRole('button', { name: /Liste einklappen/i }))
			.toBeInTheDocument();
	});

	it('autocollapse prop starts the panel in collapsed state', async () => {
		render(UsersListPanel, { users, autocollapse: true });
		await expect
			.element(page.getByRole('button', { name: /Liste ausklappen/i }))
			.toBeInTheDocument();
	});

	it('persists collapse state using the users-specific localStorage key', async () => {
		render(UsersListPanel, { users });
		const setSpy = vi.spyOn(Storage.prototype, 'setItem');
		document.querySelector<HTMLButtonElement>('[aria-label="Liste einklappen"]')!.click();
		await vi.waitFor(() =>
			expect(setSpy).toHaveBeenCalledWith('admin_users_list_collapsed', 'true')
		);
		setSpy.mockRestore();
	});
});
