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

afterEach(cleanup);

const baseProps = (overrides: Record<string, unknown> = {}) => ({
	senderId: '',
	receiverId: '',
	initialSenderName: '',
	initialReceiverName: '',
	sortDir: 'DESC',
	showAdvanced: false,
	documentCount: 0,
	onapplyFilters: () => {},
	onswapPersons: () => {},
	ontoggleSort: () => {},
	ontoggleAdvanced: () => {},
	...overrides
});

describe('CorrespondenzPersonBar', () => {
	it('renders the two PersonTypeahead inputs', async () => {
		render(CorrespondenzPersonBar, { props: baseProps() });

		const inputs = document.querySelectorAll('input');
		expect(inputs.length).toBeGreaterThanOrEqual(2);
	});

	it('hides the swap button when only one person is set', async () => {
		render(CorrespondenzPersonBar, { props: baseProps({ senderId: 'p1' }) });

		const swap = document.querySelector('[data-testid="conv-swap-btn"]') as HTMLElement;
		expect(swap.classList.contains('opacity-0')).toBe(true);
		expect(swap.tabIndex).toBe(-1);
	});

	it('shows the swap button when both senderId and receiverId are set', async () => {
		render(CorrespondenzPersonBar, {
			props: baseProps({ senderId: 'p1', receiverId: 'p2' })
		});

		const swap = document.querySelector('[data-testid="conv-swap-btn"]') as HTMLElement;
		expect(swap.classList.contains('opacity-0')).toBe(false);
		expect(swap.tabIndex).toBe(0);
	});

	it('renders the "Neueste" label when sortDir is DESC', async () => {
		render(CorrespondenzPersonBar, { props: baseProps({ sortDir: 'DESC' }) });

		await expect.element(page.getByText('Neueste')).toBeVisible();
	});

	it('renders the "Älteste" label when sortDir is ASC', async () => {
		render(CorrespondenzPersonBar, { props: baseProps({ sortDir: 'ASC' }) });

		await expect.element(page.getByText('Älteste')).toBeVisible();
	});

	it('marks the sort button as aria-pressed when sortDir is ASC', async () => {
		render(CorrespondenzPersonBar, { props: baseProps({ sortDir: 'ASC' }) });

		const sort = document.querySelector('[data-testid="conv-sort-btn"]') as HTMLElement;
		expect(sort.getAttribute('aria-pressed')).toBe('true');
	});

	it('renders the document count', async () => {
		render(CorrespondenzPersonBar, { props: baseProps({ documentCount: 42 }) });

		await expect.element(page.getByText('42 Briefe')).toBeVisible();
	});

	it('calls ontoggleSort when the sort button is clicked', async () => {
		const ontoggleSort = vi.fn();
		render(CorrespondenzPersonBar, { props: baseProps({ ontoggleSort }) });

		const sort = document.querySelector('[data-testid="conv-sort-btn"]') as HTMLElement;
		sort.click();

		expect(ontoggleSort).toHaveBeenCalledOnce();
	});

	it('calls onswapPersons when the swap button is clicked', async () => {
		const onswapPersons = vi.fn();
		render(CorrespondenzPersonBar, {
			props: baseProps({ senderId: 'p1', receiverId: 'p2', onswapPersons })
		});

		const swap = document.querySelector('[data-testid="conv-swap-btn"]') as HTMLElement;
		swap.click();

		expect(onswapPersons).toHaveBeenCalledOnce();
	});

	it('opens the suggestions dropdown on receiver focus when a senderId is set', async () => {
		const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(
			new Response(JSON.stringify([{ id: 'p3', firstName: 'Carl', lastName: 'Brandt' }]), {
				status: 200,
				headers: { 'Content-Type': 'application/json' }
			})
		);
		try {
			render(CorrespondenzPersonBar, {
				props: baseProps({ senderId: 'p1', receiverId: '' })
			});

			// Find the second PersonTypeahead input (Korrespondent) and trigger focus event
			const inputs = document.querySelectorAll('input[type="text"]');
			const corrInput = inputs[inputs.length - 1] as HTMLInputElement;
			corrInput.dispatchEvent(new Event('focus', { bubbles: true }));

			// Confirm the typeahead fired the suggestions fetch.
			await vi.waitFor(() => expect(fetchSpy).toHaveBeenCalled());
		} finally {
			fetchSpy.mockRestore();
		}
	});

	it('does not show advanced filter chevron rotation when showAdvanced is false', async () => {
		render(CorrespondenzPersonBar, { props: baseProps({ showAdvanced: false }) });

		// The filter toggle button has a chevron — should NOT be rotated
		const buttons = document.querySelectorAll('button');
		const filterBtn = Array.from(buttons).find((b) =>
			b.textContent?.toLowerCase().includes('filter')
		);
		const chevron = filterBtn?.querySelector('img');
		expect(chevron?.getAttribute('class')).not.toContain('rotate-180');
	});

	it('rotates the filter chevron when showAdvanced is true', async () => {
		render(CorrespondenzPersonBar, { props: baseProps({ showAdvanced: true }) });

		const buttons = document.querySelectorAll('button');
		const filterBtn = Array.from(buttons).find((b) =>
			b.textContent?.toLowerCase().includes('filter')
		);
		const chevron = filterBtn?.querySelector('img');
		expect(chevron?.getAttribute('class')).toContain('rotate-180');
	});
});
