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

import { m } from '$lib/paraglide/messages.js';
import PdfControls from './PdfControls.svelte';

afterEach(cleanup);

const defaultProps = {
	currentPage: 1,
	totalPages: 3,
	isLoaded: true,
	showAnnotations: false,
	annotationCount: 0,
	onPrev: vi.fn(),
	onNext: vi.fn(),
	onZoomIn: vi.fn(),
	onZoomOut: vi.fn(),
	onToggleAnnotations: vi.fn()
};

describe('PdfControls — annotation toggle visibility', () => {
	it('renders annotation toggle when annotationCount is greater than zero', async () => {
		render(PdfControls, { ...defaultProps, annotationCount: 3 });
		await expect
			.element(page.getByRole('button', { name: m.pdf_annotations_show() }))
			.toBeInTheDocument();
	});

	it('does not render annotation toggle when annotationCount is zero', async () => {
		render(PdfControls, { ...defaultProps, annotationCount: 0 });
		await expect
			.element(page.getByRole('button', { name: m.pdf_annotations_show() }))
			.not.toBeInTheDocument();
	});
});

describe('PdfControls — annotation toggle label', () => {
	it('shows show-annotations label when annotations are hidden', async () => {
		render(PdfControls, { ...defaultProps, annotationCount: 2, showAnnotations: false });
		const btn = page.getByRole('button', { name: m.pdf_annotations_show() });
		await expect.element(btn).toBeInTheDocument();
	});

	it('shows hide-annotations label when annotations are visible', async () => {
		render(PdfControls, { ...defaultProps, annotationCount: 2, showAnnotations: true });
		const btn = page.getByRole('button', { name: m.pdf_annotations_hide() });
		await expect.element(btn).toBeInTheDocument();
	});
});

describe('PdfControls — annotation toggle contrast (WCAG 2.1 AA)', () => {
	it('uses text-primary class on annotation toggle button when annotations are hidden', async () => {
		const { container } = render(PdfControls, {
			...defaultProps,
			annotationCount: 2,
			showAnnotations: false
		});
		const allButtons = container.querySelectorAll('button');
		const annotationBtn = Array.from(allButtons).find((b) =>
			[m.pdf_annotations_show(), m.pdf_annotations_hide()].includes(
				b.getAttribute('aria-label') ?? ''
			)
		);
		expect(annotationBtn).not.toBeNull();
		expect(annotationBtn!.className).toContain('text-primary');
		expect(annotationBtn!.className).not.toContain('text-accent');
	});
});

describe('PdfControls — focus rings (WCAG 2.1 §2.4.7)', () => {
	it('annotation toggle button has focus-visible:ring-2 focus ring', async () => {
		const { container } = render(PdfControls, {
			...defaultProps,
			annotationCount: 2,
			showAnnotations: false
		});
		const allButtons = container.querySelectorAll('button');
		const annotationBtn = Array.from(allButtons).find((b) =>
			[m.pdf_annotations_show(), m.pdf_annotations_hide()].includes(
				b.getAttribute('aria-label') ?? ''
			)
		);
		expect(annotationBtn).not.toBeNull();
		expect(annotationBtn!.className).toContain('focus-visible:ring-2');
	});

	it('icon-only nav/zoom buttons each have focus-visible:ring-2 focus ring', async () => {
		const { container } = render(PdfControls, { ...defaultProps });
		const allButtons = container.querySelectorAll('button');
		const iconOnlyButtons = Array.from(allButtons).filter((b) => {
			const label = b.getAttribute('aria-label') ?? '';
			return [
				m.viewer_previous_page(),
				m.viewer_next_page(),
				m.viewer_zoom_out(),
				m.viewer_zoom_in()
			].includes(label);
		});
		expect(iconOnlyButtons).toHaveLength(4);
		for (const btn of iconOnlyButtons) {
			expect(btn.className).toContain('focus-visible:ring-2');
		}
	});
});

describe('PdfControls — touch targets (WCAG 2.2 §2.5.8)', () => {
	it('annotation toggle button has min-h-[44px] touch target', async () => {
		const { container } = render(PdfControls, {
			...defaultProps,
			annotationCount: 2,
			showAnnotations: false
		});
		const allButtons = container.querySelectorAll('button');
		const annotationBtn = Array.from(allButtons).find((b) =>
			[m.pdf_annotations_show(), m.pdf_annotations_hide()].includes(
				b.getAttribute('aria-label') ?? ''
			)
		);
		expect(annotationBtn).not.toBeNull();
		expect(annotationBtn!.className).toContain('min-h-[44px]');
	});

	it('annotation toggle button has min-w-[44px] touch target', async () => {
		const { container } = render(PdfControls, {
			...defaultProps,
			annotationCount: 2,
			showAnnotations: false
		});
		const allButtons = container.querySelectorAll('button');
		const annotationBtn = Array.from(allButtons).find((b) =>
			[m.pdf_annotations_show(), m.pdf_annotations_hide()].includes(
				b.getAttribute('aria-label') ?? ''
			)
		);
		expect(annotationBtn).not.toBeNull();
		expect(annotationBtn!.className).toContain('min-w-[44px]');
	});

	it('annotation toggle reflects pressed state via aria-pressed', async () => {
		const { container: c1 } = render(PdfControls, {
			...defaultProps,
			annotationCount: 2,
			showAnnotations: false
		});
		const btn1 = Array.from(c1.querySelectorAll('button')).find((b) =>
			[m.pdf_annotations_show(), m.pdf_annotations_hide()].includes(
				b.getAttribute('aria-label') ?? ''
			)
		);
		expect(btn1!.getAttribute('aria-pressed')).toBe('false');
		cleanup();

		const { container: c2 } = render(PdfControls, {
			...defaultProps,
			annotationCount: 2,
			showAnnotations: true
		});
		const btn2 = Array.from(c2.querySelectorAll('button')).find((b) =>
			[m.pdf_annotations_show(), m.pdf_annotations_hide()].includes(
				b.getAttribute('aria-label') ?? ''
			)
		);
		expect(btn2!.getAttribute('aria-pressed')).toBe('true');
	});

	it('icon-only nav/zoom buttons each have min-h-[44px] touch target', async () => {
		const { container } = render(PdfControls, { ...defaultProps });
		const allButtons = container.querySelectorAll('button');
		const iconOnlyButtons = Array.from(allButtons).filter((b) => {
			const label = b.getAttribute('aria-label') ?? '';
			return [
				m.viewer_previous_page(),
				m.viewer_next_page(),
				m.viewer_zoom_out(),
				m.viewer_zoom_in()
			].includes(label);
		});
		expect(iconOnlyButtons).toHaveLength(4);
		for (const btn of iconOnlyButtons) {
			expect(btn.className).toContain('min-h-[44px]');
		}
	});

	it('icon-only nav/zoom buttons each have min-w-[44px] touch target', async () => {
		const { container } = render(PdfControls, { ...defaultProps });
		const allButtons = container.querySelectorAll('button');
		const iconOnlyButtons = Array.from(allButtons).filter((b) => {
			const label = b.getAttribute('aria-label') ?? '';
			return [
				m.viewer_previous_page(),
				m.viewer_next_page(),
				m.viewer_zoom_out(),
				m.viewer_zoom_in()
			].includes(label);
		});
		expect(iconOnlyButtons).toHaveLength(4);
		for (const btn of iconOnlyButtons) {
			expect(btn.className).toContain('min-w-[44px]');
		}
	});
});
