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

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

afterEach(cleanup);

const baseItem = (overrides: Partial<ActivityFeedItemDTO> = {}): ActivityFeedItemDTO =>
	({
		kind: 'TEXT_SAVED',
		documentId: 'doc-1',
		documentTitle: 'Brief 1899',
		actor: {
			id: 'u-1',
			name: 'Anna Schmidt',
			initials: 'AS',
			color: '#336699'
		},
		count: 1,
		happenedAt: '2026-04-14T14:02:00Z',
		happenedAtUntil: null,
		youMentioned: false,
		...overrides
	}) as ActivityFeedItemDTO;

describe('DashboardActivityFeed', () => {
	it('renders the feed caption and show-all link', async () => {
		render(DashboardActivityFeed, { props: { feed: [] } });

		await expect.element(page.getByText('Kommentare & Aktivität')).toBeVisible();
		const link = document.querySelector('a[href="/aktivitaeten"]');
		expect(link).not.toBeNull();
	});

	it('renders nothing in the list when the feed is empty', async () => {
		render(DashboardActivityFeed, { props: { feed: [] } });

		const lists = document.querySelectorAll('ul');
		expect(lists.length).toBe(0);
	});

	it('renders one row per feed item with the actor initials', async () => {
		render(DashboardActivityFeed, {
			props: {
				feed: [baseItem(), baseItem({ documentId: 'doc-2', documentTitle: 'Brief 1900' })]
			}
		});

		const items = document.querySelectorAll('li');
		expect(items.length).toBe(2);
		expect(document.body.textContent).toContain('AS');
	});

	it('renders the question-mark badge when no actor is set', async () => {
		render(DashboardActivityFeed, {
			props: { feed: [baseItem({ actor: null as unknown as undefined })] }
		});

		const li = document.querySelector('li');
		expect(li?.textContent).toContain('?');
	});

	it('renders the rollup count badge when count > 1', async () => {
		render(DashboardActivityFeed, {
			props: { feed: [baseItem({ count: 5 })] }
		});

		const badge = document.querySelector('[data-testid="feed-rollup-count"]');
		expect(badge?.textContent?.trim()).toBe('5');
	});

	it('omits the rollup count badge when count is 1', async () => {
		render(DashboardActivityFeed, { props: { feed: [baseItem({ count: 1 })] } });

		const badge = document.querySelector('[data-testid="feed-rollup-count"]');
		expect(badge).toBeNull();
	});

	it('renders the "für dich" badge when youMentioned is true', async () => {
		render(DashboardActivityFeed, {
			props: { feed: [baseItem({ youMentioned: true })] }
		});

		await expect.element(page.getByText(/für dich/i)).toBeVisible();
	});

	it('maps the kind enum to a localized verb (TEXT_SAVED)', async () => {
		render(DashboardActivityFeed, {
			props: { feed: [baseItem({ kind: 'TEXT_SAVED' as ActivityFeedItemDTO['kind'] })] }
		});

		expect(document.body.textContent).toContain('hat Text gespeichert in');
	});

	it('maps the kind enum to a localized verb (FILE_UPLOADED)', async () => {
		render(DashboardActivityFeed, {
			props: { feed: [baseItem({ kind: 'FILE_UPLOADED' as ActivityFeedItemDTO['kind'] })] }
		});

		expect(document.body.textContent).toContain('hat eine Datei hochgeladen');
	});

	it('falls back to the raw kind when no verb is mapped', async () => {
		render(DashboardActivityFeed, {
			props: {
				feed: [baseItem({ kind: 'UNKNOWN_KIND' as unknown as ActivityFeedItemDTO['kind'] })]
			}
		});

		expect(document.body.textContent).toContain('UNKNOWN_KIND');
	});

	it('renders a rollup time range when happenedAtUntil is set and count > 1', async () => {
		render(DashboardActivityFeed, {
			props: {
				feed: [
					baseItem({
						happenedAt: '2026-04-14T14:02:00Z',
						happenedAtUntil: '2026-04-14T14:32:00Z',
						count: 3
					})
				]
			}
		});

		// "14:02–14:32" appears (with the en-dash)
		expect(document.body.textContent).toMatch(/\d{2}:\d{2}–\d{2}:\d{2}/);
	});

	it('uses the actor initials as the fallback name when name is null', async () => {
		render(DashboardActivityFeed, {
			props: {
				feed: [
					baseItem({
						actor: {
							id: 'u-2',
							name: null as unknown as undefined,
							initials: 'XR',
							color: '#000'
						}
					})
				]
			}
		});

		const strong = document.querySelector('strong');
		expect(strong?.textContent).toBe('XR');
	});

	it('builds the document detail href from documentId', async () => {
		render(DashboardActivityFeed, {
			props: { feed: [baseItem({ documentId: 'doc-xyz', documentTitle: 'Brief 1901' })] }
		});

		const link = document.querySelector('a[href="/documents/doc-xyz"]');
		expect(link).not.toBeNull();
	});
});
