import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
import { HttpResponse, http, server } from "~/test/msw/server";
import { cleanup, render, screen, userEvent, waitFor, within } from "~/test/test-utils";
import { fromAny } from "@total-typescript/shoehorn";

await mock.module("@tanstack/react-router", () => ({
	useNavigate: () => mock(() => {}),
}));

import { RestoreForm } from "../restore-form";

class MockEventSource {
	addEventListener() {}
	close() {}
	onerror: ((event: Event) => void) | null = null;

	constructor(public url: string) {}
}

const originalEventSource = globalThis.EventSource;

beforeEach(() => {
	globalThis.EventSource = MockEventSource as unknown as typeof EventSource;
});

afterEach(() => {
	globalThis.EventSource = originalEventSource;
	cleanup();
});

describe("RestoreForm", () => {
	test("restores the selected ancestor folder path from a broader display root", async () => {
		let restoreRequestBody: unknown;

		server.use(
			http.get("/api/v1/repositories/:shortId/snapshots/:snapshotId/files", () => {
				return HttpResponse.json({
					files: [
						{ name: "subdir", path: "/mnt/project/subdir", type: "dir" },
						{ name: "deep.tx", path: "/mnt/project/subdir/deep.tx", type: "file" },
					],
				});
			}),
			http.post("/api/v1/repositories/:shortId/restore", async ({ request }) => {
				restoreRequestBody = await request.json();
				return HttpResponse.json({
					success: true,
					message: "Snapshot restored successfully",
					filesRestored: 1,
					filesSkipped: 0,
				});
			}),
		);

		render(
			<RestoreForm
				repository={fromAny({ shortId: "repo-1", name: "Repo 1" })}
				snapshotId="snap-1"
				returnPath="/repositories/repo-1/snap-1"
				queryBasePath="/mnt/project/subdir"
				displayBasePath="/mnt"
			/>,
		);

		const row = await screen.findByRole("button", { name: "project" });
		await userEvent.click(within(row).getByRole("checkbox"));
		await userEvent.click(screen.getByRole("button", { name: "Restore 1 item" }));

		await waitFor(() => {
			expect(restoreRequestBody).toEqual({
				snapshotId: "snap-1",
				include: ["/mnt/project"],
				selectedItemKind: "dir",
				overwrite: "always",
			});
		});
	});
});
