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

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

afterEach(cleanup);

const groups = [
	{ id: 'g1', name: 'Administrators', permissions: ['ADMIN', 'WRITE_ALL'] },
	{ id: 'g2', name: 'Editors', permissions: ['WRITE_ALL'] },
	{ id: 'g3', name: 'Readers', permissions: [] }
];

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

	it('renders a new-group link pointing to /admin/groups/new', async () => {
		render(GroupsListPanel, { groups });
		await expect
			.element(page.getByRole('link', { name: /neue gruppe/i }))
			.toHaveAttribute('href', '/admin/groups/new');
	});
});

describe('GroupsListPanel — group items', () => {
	it('renders each group name', async () => {
		render(GroupsListPanel, { groups });
		await expect.element(page.getByRole('link', { name: /administrators/i })).toBeInTheDocument();
		await expect.element(page.getByRole('link', { name: /editors/i })).toBeInTheDocument();
	});

	it('each group links to /admin/groups/[id]', async () => {
		const { container } = render(GroupsListPanel, { groups });
		const links = container.querySelectorAll<HTMLAnchorElement>('a[href^="/admin/groups/g"]');
		expect(links.length).toBe(3);
		expect(links[0].getAttribute('href')).toBe('/admin/groups/g1');
	});

	it('shows permission count as subtitle', async () => {
		render(GroupsListPanel, { groups });
		// Administrators has 2 permissions
		await expect.element(page.getByText(/2 Berechtigungen/i)).toBeInTheDocument();
	});

	it('shows "no permissions" for a group with zero permissions', async () => {
		render(GroupsListPanel, { groups });
		await expect.element(page.getByText(/0 Berechtigungen/i)).toBeInTheDocument();
	});
});

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

	it('does not mark inactive group links with aria-current', async () => {
		render(GroupsListPanel, { groups });
		await expect
			.element(page.getByRole('link', { name: /editors/i }))
			.not.toHaveAttribute('aria-current');
	});
});

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

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

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

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

	it('clicking collapse shows the expand handle', async () => {
		render(GroupsListPanel, { groups });
		await expect
			.element(page.getByRole('button', { name: /Liste einklappen/i }))
			.toBeInTheDocument();
		document.querySelector<HTMLButtonElement>('[aria-label="Liste einklappen"]')!.click();
		await expect
			.element(page.getByRole('button', { name: /Liste ausklappen/i }))
			.toBeInTheDocument();
	});

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

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