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

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

afterEach(cleanup);

const makeGeschichte = (overrides: Record<string, unknown> = {}): GeschichteSummary =>
	({
		id: 'g1',
		title: 'Reise nach Berlin',
		body: '<p>Brief text</p>',
		status: 'PUBLISHED' as const,
		type: 'STORY' as const,
		publishedAt: '2026-04-15T10:00:00Z',
		author: {
			firstName: 'Anna',
			lastName: 'Schmidt'
		},
		...overrides
	}) as GeschichteSummary;

const baseProps = (overrides: Record<string, unknown> = {}) => ({
	geschichten: [] as GeschichteSummary[],
	personId: 'p-1',
	personName: 'Anna Schmidt',
	canWrite: false,
	...overrides
});

describe('GeschichtenCard', () => {
	it('renders nothing when geschichten is empty', async () => {
		render(GeschichtenCard, { props: baseProps() });

		expect(document.querySelector('section')).toBeNull();
	});

	it('renders the section when at least one geschichte is present', async () => {
		render(GeschichtenCard, { props: baseProps({ geschichten: [makeGeschichte()] }) });

		await expect.element(page.getByRole('heading', { name: /geschichten/i })).toBeVisible();
	});

	it('shows the write-action link when canWrite is true', async () => {
		render(GeschichtenCard, {
			props: baseProps({ geschichten: [makeGeschichte()], canWrite: true })
		});

		await expect
			.element(page.getByRole('link', { name: /geschichte schreiben/i }))
			.toHaveAttribute('href', '/geschichten/new?personId=p-1');
	});

	it('hides the write-action link when canWrite is false', async () => {
		render(GeschichtenCard, { props: baseProps({ geschichten: [makeGeschichte()] }) });

		await expect
			.element(page.getByRole('link', { name: /geschichte schreiben/i }))
			.not.toBeInTheDocument();
	});

	it('limits visible geschichten to 3', async () => {
		const geschichten = Array.from({ length: 5 }, (_, i) =>
			makeGeschichte({ id: `g${i}`, title: `Geschichte ${i + 1}` })
		);
		render(GeschichtenCard, { props: baseProps({ geschichten }) });

		await expect.element(page.getByText('Geschichte 1')).toBeVisible();
		await expect.element(page.getByText('Geschichte 3')).toBeVisible();
		await expect.element(page.getByText('Geschichte 4')).not.toBeInTheDocument();
	});

	it('renders the show-all link in the footer when there are 3 or more', async () => {
		const geschichten = Array.from({ length: 3 }, (_, i) =>
			makeGeschichte({ id: `g${i}`, title: `g${i}` })
		);
		render(GeschichtenCard, { props: baseProps({ geschichten }) });

		await expect
			.element(page.getByRole('link', { name: /alle geschichten zu anna schmidt/i }))
			.toHaveAttribute('href', '/geschichten?personId=p-1');
	});

	it('hides the show-all footer when fewer than 3 geschichten', async () => {
		render(GeschichtenCard, {
			props: baseProps({
				geschichten: [makeGeschichte({ id: 'g1' }), makeGeschichte({ id: 'g2', title: 'Two' })]
			})
		});

		await expect
			.element(page.getByRole('link', { name: /alle geschichten zu/i }))
			.not.toBeInTheDocument();
	});

	it('renders the author full name when both first and last names are set', async () => {
		render(GeschichtenCard, { props: baseProps({ geschichten: [makeGeschichte()] }) });

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

	it('falls back to [Unbekannt] when no name', async () => {
		render(GeschichtenCard, {
			props: baseProps({
				geschichten: [
					makeGeschichte({
						author: { firstName: undefined, lastName: undefined }
					})
				]
			})
		});

		await expect.element(page.getByText('[Unbekannt]')).toBeVisible();
	});
});
