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

import ReaderRecentDocs from './ReaderRecentDocs.svelte';
import type { components } from '$lib/generated/api';

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

afterEach(() => {
	cleanup();
});

const baseDoc: DocumentListItem = {
	id: 'doc1',
	title: 'Brief an Hans',
	originalFilename: 'brief.pdf',
	metaDatePrecision: 'UNKNOWN',
	completionPercentage: 0,
	receivers: [],
	tags: [],
	contributors: [],
	matchData: {
		titleOffsets: [],
		senderMatched: false,
		matchedReceiverIds: [],
		matchedTagIds: [],
		snippetOffsets: [],
		summaryOffsets: []
	},
	createdAt: '2025-01-01T12:00:00Z',
	updatedAt: '2025-01-01T12:00:00Z'
};

const updatedDoc: DocumentListItem = {
	...baseDoc,
	id: 'doc2',
	title: 'Urkunde 1920',
	createdAt: '2025-01-01T12:00:00Z',
	updatedAt: '2025-03-01T12:00:00Z'
};

describe('ReaderRecentDocs', () => {
	it('renders a link to /documents/{id} for each document', async () => {
		render(ReaderRecentDocs, { documents: [baseDoc] });
		const link = page.getByRole('link', { name: /Brief an Hans/ });
		await expect.element(link).toHaveAttribute('href', '/documents/doc1');
	});

	it('card has overflow-hidden and flex-col classes (no p-6, no shadow-sm)', async () => {
		render(ReaderRecentDocs, { documents: [baseDoc] });
		const heading = page.getByRole('heading', { level: 3 });
		const card = (await heading.element())?.closest('div');
		const rootCard = card?.parentElement;
		const cls = rootCard?.className ?? '';
		expect(cls).toMatch(/overflow-hidden/);
		expect(cls).toMatch(/flex-col/);
		expect(cls).not.toMatch(/\bp-6\b/);
		expect(cls).not.toMatch(/shadow-sm/);
	});

	it('card-head contains an h3 (not h2)', async () => {
		render(ReaderRecentDocs, { documents: [baseDoc] });
		const h3 = page.getByRole('heading', { level: 3 });
		await expect.element(h3).toBeInTheDocument();
		const h2 = page.getByRole('heading', { level: 2 });
		await expect.element(h2).not.toBeInTheDocument();
	});

	it('"Alle Dokumente" link in card-head points to /documents', async () => {
		render(ReaderRecentDocs, { documents: [baseDoc] });
		const link = page.getByRole('link', { name: /Alle Dokumente/i });
		await expect.element(link).toHaveAttribute('href', '/documents');
	});

	it('"Alle Dokumente" link has min-h-[44px]', async () => {
		render(ReaderRecentDocs, { documents: [baseDoc] });
		const link = page.getByRole('link', { name: /Alle Dokumente/i });
		const cls = ((await link.element()) as HTMLElement).className;
		expect(cls).toMatch(/min-h-\[44px\]/);
	});

	it('doc-row link has min-h-[44px] touch target', async () => {
		render(ReaderRecentDocs, { documents: [baseDoc] });
		const link = page.getByRole('link', { name: /Brief an Hans/ });
		const cls = ((await link.element()) as HTMLElement).className;
		expect(cls).toMatch(/min-h-\[44px\]/);
	});

	it('thumb element has correct classes', async () => {
		render(ReaderRecentDocs, { documents: [baseDoc] });
		const link = page.getByRole('link', { name: /Brief an Hans/ });
		const el = (await link.element()) as HTMLElement;
		const thumb = el.querySelector('[class*="w-5"][class*="h-6"]');
		expect(thumb).not.toBeNull();
		expect(thumb!.className).toMatch(/bg-canvas/);
		expect(thumb!.className).toMatch(/border-line/);
		expect(thumb!.className).toMatch(/rounded-/);
	});

	it('shows "Neu" accent-pill badge when document was created within the last 7 days', async () => {
		const recentDoc: DocumentListItem = {
			...baseDoc,
			id: 'doc-recent',
			createdAt: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
			updatedAt: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString()
		};
		render(ReaderRecentDocs, { documents: [recentDoc] });
		const badge = page.getByText(/^Neu$/i);
		await expect.element(badge).toBeInTheDocument();
		const cls = ((await badge.element()) as HTMLElement).className;
		expect(cls).toMatch(/bg-accent-bg/);
		expect(cls).toMatch(/rounded-full/);
		expect(cls).toMatch(/\btext-ink\b/);
	});

	it('shows no badge when document was created more than 7 days ago', async () => {
		render(ReaderRecentDocs, { documents: [updatedDoc] });
		const badge = page.getByText(/^Neu$/i);
		await expect.element(badge).not.toBeInTheDocument();
		const updatedBadge = page.getByText(/^Aktualisiert$/i);
		await expect.element(updatedBadge).not.toBeInTheDocument();
	});

	it('shows "Neu" badge when document was created 6 days ago', async () => {
		const almostOldDoc: DocumentListItem = {
			...baseDoc,
			id: 'doc-almost-old',
			createdAt: new Date(Date.now() - 6 * 24 * 60 * 60 * 1000).toISOString(),
			updatedAt: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString()
		};
		render(ReaderRecentDocs, { documents: [almostOldDoc] });
		const badge = page.getByText(/^Neu$/i);
		await expect.element(badge).toBeInTheDocument();
	});

	it('renders sender name text when sender is present', async () => {
		const docWithSender: DocumentListItem = {
			...baseDoc,
			sender: {
				id: 'p1',
				lastName: 'Müller',
				firstName: 'Anna',
				displayName: 'Anna Müller',
				personType: 'PERSON' as const,
				birthDatePrecision: 'UNKNOWN' as const,
				deathDatePrecision: 'UNKNOWN' as const,
				familyMember: false,
				provisional: false
			}
		};
		render(ReaderRecentDocs, { documents: [docWithSender] });
		const link = page.getByRole('link', { name: /Brief an Hans/ });
		const el = (await link.element()) as HTMLElement;
		expect(el.textContent).toContain('Anna Müller');
	});

	it('shows em-dash when sender is absent', async () => {
		render(ReaderRecentDocs, { documents: [baseDoc] });
		const link = page.getByRole('link', { name: /Brief an Hans/ });
		const el = (await link.element()) as HTMLElement;
		expect(el.textContent).toContain('—');
	});
});
