import { describe, it, expect, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import type { components } from '$lib/generated/api';

const { default: StoryReader } = await import('./StoryReader.svelte');

afterEach(cleanup);

type GeschichteView = components['schemas']['GeschichteView'];

const baseGeschichte = (overrides: Partial<GeschichteView> = {}): GeschichteView => ({
	id: 'g1',
	title: 'Die Reise nach Berlin',
	body: '<p>Im Jahr 1923 fuhr Helene...</p>',
	type: 'STORY',
	status: 'PUBLISHED',
	author: { id: 'u1', displayName: 'Anna Schmidt' },
	persons: [],
	items: [],
	createdAt: '2026-01-01T00:00:00Z',
	updatedAt: '2026-01-01T00:00:00Z',
	...overrides
});

describe('StoryReader', () => {
	it('renders body HTML content', async () => {
		render(StoryReader, { props: { geschichte: baseGeschichte() } });

		await expect.element(page.getByText(/Im Jahr 1923/)).toBeVisible();
	});

	it('omits persons section when persons array is empty', async () => {
		render(StoryReader, { props: { geschichte: baseGeschichte({ persons: [] }) } });

		await expect.element(page.getByText(/Personen in dieser Geschichte/i)).not.toBeInTheDocument();
	});

	it('renders persons section with firstName + lastName joined', async () => {
		render(StoryReader, {
			props: {
				geschichte: baseGeschichte({
					persons: [
						{ id: 'p1', firstName: 'Helene', lastName: 'Schmidt' },
						{ id: 'p2', firstName: 'Karl', lastName: 'Müller' }
					]
				})
			}
		});

		await expect.element(page.getByText('Personen in dieser Geschichte')).toBeVisible();
		await expect.element(page.getByText('Helene Schmidt')).toBeVisible();
		await expect.element(page.getByText('Karl Müller')).toBeVisible();
	});

	it('omits documents section when no items have documents', async () => {
		render(StoryReader, { props: { geschichte: baseGeschichte({ items: [] }) } });

		await expect.element(page.getByText('Erwähnte Dokumente')).not.toBeInTheDocument();
	});

	it('renders document reference cards with title and link for items with documents', async () => {
		render(StoryReader, {
			props: {
				geschichte: baseGeschichte({
					items: [
						{
							id: 'i1',
							position: 0,
							document: {
								id: 'd1',
								title: 'Brief vom 12. Juli 1938',
								documentDate: '1938-07-12',
								senderName: 'Franz Raddatz',
								receiverName: 'Emma Müller',
								datePrecision: 'DAY',
								receiverCount: 1
							} as unknown as NonNullable<components['schemas']['JourneyItemView']['document']>,
							note: 'Wichtiger Brief'
						}
					]
				})
			}
		});

		await expect.element(page.getByText('Erwähnte Dokumente')).toBeVisible();
		await expect.element(page.getByText('Brief vom 12. Juli 1938')).toBeVisible();
		await expect.element(page.getByText(/von Franz Raddatz an Emma Müller/)).toBeVisible();
		await expect.element(page.getByText('Wichtiger Brief')).toBeVisible();

		const link = document.querySelector<HTMLAnchorElement>('a[href="/documents/d1"]');
		expect(link).not.toBeNull();
	});

	it('person chip link meets 44px touch-target minimum height', async () => {
		render(StoryReader, {
			props: {
				geschichte: baseGeschichte({
					persons: [{ id: 'p1', firstName: 'Helene', lastName: 'Schmidt' }]
				})
			}
		});

		const link = document.querySelector<HTMLAnchorElement>('a[href^="/persons/"]');
		const rect = link?.getBoundingClientRect();
		expect(rect?.height).toBeGreaterThanOrEqual(44);
	});

	it('person chip shows avatar initials', async () => {
		render(StoryReader, {
			props: {
				geschichte: baseGeschichte({
					persons: [{ id: 'p1', firstName: 'Helene', lastName: 'Schmidt' }]
				})
			}
		});

		const chip = document.querySelector<HTMLAnchorElement>('a[href="/persons/p1"]');
		expect(chip?.textContent).toContain('HS');
	});

	it('XSS: Story body is sanitised — injected payload does not execute', async () => {
		// StoryReader uses {@html safeHtml(g.body)} — DOMPurify must strip the payload.
		render(StoryReader, {
			props: {
				geschichte: baseGeschichte({
					body: '<img src=x onerror="(window as any).__xss_story=1">'
				})
			}
		});

		expect((window as { __xss_story?: number }).__xss_story).toBeUndefined();
	});
});
