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

import { createConfirmService, CONFIRM_KEY } from '$lib/shared/services/confirm.svelte.js';

const { default: GeschichtePage } = await import('./+page.svelte');

afterEach(cleanup);

const baseGeschichte = (overrides: Record<string, unknown> = {}) => ({
	id: 'g1',
	title: 'Die Reise nach Berlin',
	body: '<p>Im Jahr 1923 fuhr Helene...</p>',
	publishedAt: '2026-04-15T10:00:00Z' as string | null,
	author: { firstName: 'Anna', lastName: 'Schmidt', email: 'anna@example.com' } as {
		firstName?: string;
		lastName?: string;
		email: string;
	} | null,
	persons: [] as { id: string; displayName: string }[],
	documents: [] as { id: string; title: string; documentDate?: string | null }[],
	...overrides
});

const baseData = (overrides: Record<string, unknown> = {}) => ({
	geschichte: baseGeschichte(),
	canBlogWrite: false,
	...overrides
});

describe('geschichten/[id] page', () => {
	it('renders the geschichte title as the level-1 heading', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: { data: baseData() }
		});

		await expect
			.element(page.getByRole('heading', { level: 1, name: /reise nach berlin/i }))
			.toBeVisible();
	});

	it('renders the author full name from firstName + lastName', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: { data: baseData() }
		});

		await expect.element(page.getByText(/Anna Schmidt/)).toBeVisible();
	});

	it('falls back to author email when no name is set', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: {
				data: baseData({
					geschichte: baseGeschichte({
						author: { firstName: undefined, lastName: undefined, email: 'fallback@example.com' }
					})
				})
			}
		});

		await expect.element(page.getByText(/fallback@example.com/)).toBeVisible();
	});

	it('renders an empty author when author is null', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: { data: baseData({ geschichte: baseGeschichte({ author: null }) }) }
		});

		await expect.element(page.getByRole('heading', { level: 1 })).toBeVisible();
	});

	it('renders the publishedAt date suffix when publishedAt is set', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: { data: baseData() }
		});

		await expect.element(page.getByText(/veröffentlicht am/i)).toBeVisible();
	});

	it('omits the publishedAt suffix when publishedAt is null', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: { data: baseData({ geschichte: baseGeschichte({ publishedAt: null }) }) }
		});

		await expect.element(page.getByText(/veröffentlicht am/i)).not.toBeInTheDocument();
	});

	it('omits the persons section when there are no linked persons', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: { data: baseData() }
		});

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

	it('renders the persons section when there are linked persons', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: {
				data: baseData({
					geschichte: baseGeschichte({
						persons: [
							{ id: 'p1', displayName: 'Helene Schmidt' },
							{ id: 'p2', displayName: 'Karl 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 the documents section when there are no linked documents', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: { data: baseData() }
		});

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

	it('renders the documents section when there are linked documents', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: {
				data: baseData({
					geschichte: baseGeschichte({
						documents: [{ id: 'd1', title: 'Brief 1923', documentDate: '1923-04-15' }]
					})
				})
			}
		});

		await expect.element(page.getByText('Erwähnte Dokumente')).toBeVisible();
		await expect.element(page.getByText('Brief 1923')).toBeVisible();
	});

	it('renders edit and delete actions when canBlogWrite is true', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: { data: baseData({ canBlogWrite: true }) }
		});

		await expect
			.element(page.getByRole('link', { name: /bearbeiten/i }))
			.toHaveAttribute('href', '/geschichten/g1/edit');
		await expect.element(page.getByRole('button', { name: /löschen/i })).toBeVisible();
	});

	it('hides edit and delete actions when canBlogWrite is false', async () => {
		render(GeschichtePage, {
			context: new Map([[CONFIRM_KEY, createConfirmService()]]),
			props: { data: baseData({ canBlogWrite: false }) }
		});

		await expect.element(page.getByRole('link', { name: /bearbeiten/i })).not.toBeInTheDocument();
		await expect.element(page.getByRole('button', { name: /löschen/i })).not.toBeInTheDocument();
	});
});
