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

afterEach(cleanup);

const baseInfo = (overrides: Record<string, unknown> = {}) => ({
	availableSegBlocks: 10,
	ocrServiceAvailable: true,
	runs: [],
	...overrides
});

describe('SegmentationTrainingCard', () => {
	it('renders the heading and description', async () => {
		render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo() } });

		await expect
			.element(page.getByRole('heading', { name: /segmentierung trainieren/i }))
			.toBeVisible();
		await expect.element(page.getByText(/Starte ein neues Training/i)).toBeVisible();
	});

	it('shows the count of available segmentation blocks', async () => {
		render(SegmentationTrainingCard, {
			props: { trainingInfo: baseInfo({ availableSegBlocks: 42 }) }
		});

		await expect.element(page.getByText('42 Segmentierungsblöcke bereit')).toBeVisible();
	});

	it('shows zero blocks when trainingInfo is null', async () => {
		render(SegmentationTrainingCard, { props: { trainingInfo: null } });

		await expect.element(page.getByText('0 Segmentierungsblöcke bereit')).toBeVisible();
	});

	it('disables the start button when fewer than 5 blocks are available', async () => {
		render(SegmentationTrainingCard, {
			props: { trainingInfo: baseInfo({ availableSegBlocks: 3 }) }
		});

		const btn = (await page
			.getByRole('button', { name: /training starten/i })
			.element()) as HTMLButtonElement;
		expect(btn.disabled).toBe(true);
	});

	it('shows the too-few-blocks hint when fewer than 5 blocks are available', async () => {
		render(SegmentationTrainingCard, {
			props: { trainingInfo: baseInfo({ availableSegBlocks: 3 }) }
		});

		await expect
			.element(page.getByText(/Mindestens 5 Segmentierungsblöcke erforderlich/i))
			.toBeVisible();
	});

	it('disables the start button when the OCR service is reported down', async () => {
		render(SegmentationTrainingCard, {
			props: { trainingInfo: baseInfo({ ocrServiceAvailable: false }) }
		});

		const btn = (await page
			.getByRole('button', { name: /training starten/i })
			.element()) as HTMLButtonElement;
		expect(btn.disabled).toBe(true);
	});

	it('shows the service-down hint when ocrServiceAvailable is false', async () => {
		render(SegmentationTrainingCard, {
			props: { trainingInfo: baseInfo({ ocrServiceAvailable: false }) }
		});

		await expect.element(page.getByText('OCR-Dienst ist nicht erreichbar.')).toBeVisible();
	});

	it('enables the start button when blocks are sufficient and the service is up', async () => {
		render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo() } });

		const btn = (await page
			.getByRole('button', { name: /training starten/i })
			.element()) as HTMLButtonElement;
		expect(btn.disabled).toBe(false);
	});

	it('shows the success message after a successful training POST', async () => {
		const fetchSpy = vi
			.spyOn(globalThis, 'fetch')
			.mockResolvedValue(new Response('{}', { status: 200 }));
		try {
			render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo() } });

			await page.getByRole('button', { name: /training starten/i }).click();

			await expect
				.element(page.getByText('Training wurde gestartet und abgeschlossen.'))
				.toBeVisible();
		} finally {
			fetchSpy.mockRestore();
		}
	});

	it('renders the training history heading', async () => {
		render(SegmentationTrainingCard, { props: { trainingInfo: baseInfo() } });

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