import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { describe, it, expect, vi } from "vitest";
import { CreateSessionForm } from "./CreateSessionForm";
import type { Project } from "@/types/project";
import type { ToolType } from "@/types/tool-type";

vi.mock("@/api/git_repositories", () => ({
	listRepositories: vi.fn(),
}));

vi.mock("@/api/sessions", () => ({
	createInstance: vi.fn(),
	startInstance: vi.fn(),
}));

vi.mock("@/api/settings", () => ({
	updateUserConfig: vi.fn(),
}));

import { listRepositories } from "@/api/git-repositories";
import { createInstance } from "@/api/sessions";

const mockProjects = [
	{
		id: "p1",
		name: "Project One",
		description: null,
		owner_id: "u1",
		default_ssh_key_id: null,
	},
	{
		id: "p2",
		name: "Project Two",
		description: null,
		owner_id: "u1",
		default_ssh_key_id: null,
	},
] as Project[];

const mockToolTypes = [
	{
		id: "t1",
		name: "vscode",
		display_name: "VS Code",
		description: null,
		category: "editor",
		interfaces: ["web"],
		default_port: 8443,
		definition_type: "compose",
		compose_template: "",
		dockerfile_template: null,
		readiness_probe: null,
		required_variables: [],
		is_builtin: true,
		build_context: null,
		created_by_id: "u1",
		created_at: "",
		updated_at: "",
	},
	{
		id: "t2",
		name: "terminal",
		display_name: "Terminal",
		description: null,
		category: "shell",
		interfaces: ["terminal"],
		default_port: 22,
		definition_type: "dockerfile",
		compose_template: null,
		dockerfile_template: "",
		readiness_probe: null,
		required_variables: [],
		is_builtin: true,
		build_context: null,
		created_by_id: "u1",
		created_at: "",
		updated_at: "",
	},
] as ToolType[];

describe("CreateSessionForm", () => {
	it("renders form with create button", () => {
		render(
			<CreateSessionForm
				projects={mockProjects}
				toolTypes={mockToolTypes}
				onCreated={vi.fn()}
			/>,
		);

		expect(screen.getByText("Create New Session")).toBeInTheDocument();
		expect(screen.getByText("Create Session")).toBeInTheDocument();
	});

	it("shows validation error when fields are missing", async () => {
		render(
			<CreateSessionForm
				projects={mockProjects}
				toolTypes={mockToolTypes}
				onCreated={vi.fn()}
			/>,
		);

		const { container } = render(
			<CreateSessionForm
				projects={mockProjects}
				toolTypes={mockToolTypes}
				onCreated={vi.fn()}
			/>,
		);

		const submitBtn = container.querySelector(
			'button[type="submit"]',
		) as HTMLButtonElement;
		fireEvent.click(submitBtn);

		await waitFor(() => {
			expect(
				screen.getByText(/project, repository, and tool type are required/i),
			).toBeInTheDocument();
		});

		expect(createInstance).not.toHaveBeenCalled();
	});

	it("loads repositories when project selected", async () => {
		const mockedList = listRepositories as ReturnType<typeof vi.fn>;
		mockedList.mockResolvedValueOnce([{ id: "r1", name: "repo-one" }]);

		const { container } = render(
			<CreateSessionForm
				projects={mockProjects}
				toolTypes={mockToolTypes}
				onCreated={vi.fn()}
			/>,
		);

		const projectSelect = container.querySelector(
			"select",
		) as HTMLSelectElement;
		fireEvent.change(projectSelect, { target: { value: "p1" } });

		await waitFor(() => {
			expect(listRepositories).toHaveBeenCalledWith("p1");
		});
	});
});
