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

afterEach(cleanup);

const corrA = { id: 'a', firstName: 'Anna', lastName: 'Schmidt', displayName: 'Anna Schmidt' };
const corrB = { id: 'b', firstName: null, lastName: 'Müller', displayName: 'Müller' };

describe('CorrespondentSuggestionsDropdown', () => {
	it('renders the heading and the "all correspondents" row even when the list is empty', async () => {
		render(CorrespondentSuggestionsDropdown, {
			props: {
				correspondents: [],
				loading: false,
				senderName: 'Anna',
				onselect: () => {},
				onclose: () => {}
			}
		});

		await expect.element(page.getByText('Häufigste Korrespondenten')).toBeVisible();
		await expect.element(page.getByText('Alle Korrespondenten von Anna')).toBeVisible();
	});

	it('renders one row per correspondent when not loading', async () => {
		render(CorrespondentSuggestionsDropdown, {
			props: {
				correspondents: [corrA, corrB],
				loading: false,
				senderName: 'Anna',
				onselect: () => {},
				onclose: () => {}
			}
		});

		await expect.element(page.getByText('Anna Schmidt')).toBeVisible();
		await expect.element(page.getByText('Müller')).toBeVisible();
	});

	it('hides correspondent rows while loading is true', async () => {
		render(CorrespondentSuggestionsDropdown, {
			props: {
				correspondents: [corrA],
				loading: true,
				senderName: 'Anna',
				onselect: () => {},
				onclose: () => {}
			}
		});

		await expect.element(page.getByText('Anna Schmidt')).not.toBeInTheDocument();
		await expect.element(page.getByText('Häufigste Korrespondenten')).toBeVisible();
	});

	it('builds initials from firstName + lastName when available', async () => {
		render(CorrespondentSuggestionsDropdown, {
			props: {
				correspondents: [corrA],
				loading: false,
				senderName: 'Anna',
				onselect: () => {},
				onclose: () => {}
			}
		});

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

	it('falls back to the first two letters of lastName when firstName is missing', async () => {
		render(CorrespondentSuggestionsDropdown, {
			props: {
				correspondents: [corrB],
				loading: false,
				senderName: 'Anna',
				onselect: () => {},
				onclose: () => {}
			}
		});

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

	it('calls onselect with the correspondent id when a row is clicked', async () => {
		const onselect = vi.fn();
		render(CorrespondentSuggestionsDropdown, {
			props: {
				correspondents: [corrA],
				loading: false,
				senderName: 'Anna',
				onselect,
				onclose: () => {}
			}
		});

		await page.getByText('Anna Schmidt').click();

		expect(onselect).toHaveBeenCalledWith('a');
	});

	it('calls onselect with an empty string when the "all correspondents" row is clicked', async () => {
		const onselect = vi.fn();
		render(CorrespondentSuggestionsDropdown, {
			props: {
				correspondents: [],
				loading: false,
				senderName: 'Anna',
				onselect,
				onclose: () => {}
			}
		});

		await page.getByText('Alle Korrespondenten von Anna').click();

		expect(onselect).toHaveBeenCalledWith('');
	});

	it('calls onselect via Enter key on a focused row', async () => {
		const onselect = vi.fn();
		render(CorrespondentSuggestionsDropdown, {
			props: {
				correspondents: [corrA],
				loading: false,
				senderName: 'Anna',
				onselect,
				onclose: () => {}
			}
		});

		const row = (await page.getByText('Anna Schmidt').element()) as HTMLElement;
		row.focus();
		row.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));

		expect(onselect).toHaveBeenCalledWith('a');
	});

	it('calls onclose when the Escape key is pressed', async () => {
		const onclose = vi.fn();
		render(CorrespondentSuggestionsDropdown, {
			props: {
				correspondents: [corrA],
				loading: false,
				senderName: 'Anna',
				onselect: () => {},
				onclose
			}
		});

		const list = (await page.getByRole('listbox').element()) as HTMLElement;
		list.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));

		expect(onclose).toHaveBeenCalledOnce();
	});
});
