/* @vitest-environment node */

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";

vi.mock("@/lib/auth/session", () => ({
	getSession: vi.fn(),
}));

import { getSession } from "@/lib/auth/session";
import { GET, dynamic } from "./route.js";

describe("GET /api/branches/[branch]/[year]/months", () => {
	let tmpRoot;
	const originalNasRoot = process.env.NAS_ROOT_PATH;

	beforeEach(async () => {
		vi.clearAllMocks();
		tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "api-months-"));
		process.env.NAS_ROOT_PATH = tmpRoot;

		await fs.mkdir(path.join(tmpRoot, "NL01", "2024", "10"), {
			recursive: true,
		});
	});

	afterEach(async () => {
		process.env.NAS_ROOT_PATH = originalNasRoot;
		if (tmpRoot) await fs.rm(tmpRoot, { recursive: true, force: true });
	});

	it('exports dynamic="force-dynamic" (RHL-006)', () => {
		expect(dynamic).toBe("force-dynamic");
	});

	it("returns 401 when unauthenticated", async () => {
		getSession.mockResolvedValue(null);

		const res = await GET(
			new Request("http://localhost/api/branches/NL01/2024/months"),
			{ params: Promise.resolve({ branch: "NL01", year: "2024" }) }
		);

		expect(res.status).toBe(401);
		expect(await res.json()).toEqual({
			error: { message: "Unauthorized", code: "AUTH_UNAUTHENTICATED" },
		});
	});

	it("returns 403 when branch user accesses a different branch", async () => {
		getSession.mockResolvedValue({
			role: "branch",
			branchId: "NL01",
			userId: "u1",
		});

		const res = await GET(
			new Request("http://localhost/api/branches/NL02/2024/months"),
			{ params: Promise.resolve({ branch: "NL02", year: "2024" }) }
		);

		expect(res.status).toBe(403);
		expect(await res.json()).toEqual({
			error: { message: "Forbidden", code: "AUTH_FORBIDDEN_BRANCH" },
		});
	});

	it("returns months for a valid branch/year when allowed", async () => {
		getSession.mockResolvedValue({
			role: "admin",
			branchId: null,
			userId: "u2",
		});

		const res = await GET(
			new Request("http://localhost/api/branches/NL01/2024/months"),
			{ params: Promise.resolve({ branch: "NL01", year: "2024" }) }
		);

		expect(res.status).toBe(200);
		expect(await res.json()).toEqual({
			branch: "NL01",
			year: "2024",
			months: ["10"],
		});
	});

	it("returns 400 when branch or year is missing (authenticated)", async () => {
		getSession.mockResolvedValue({
			role: "admin",
			branchId: null,
			userId: "u2",
		});

		const res = await GET(
			new Request("http://localhost/api/branches/NL01//months"),
			{ params: Promise.resolve({ branch: "NL01", year: undefined }) }
		);

		expect(res.status).toBe(400);
		expect(await res.json()).toEqual({
			error: {
				message: "Missing required route parameter(s)",
				code: "VALIDATION_MISSING_PARAM",
				details: { params: ["year"] },
			},
		});
	});

	it("returns 404 when the year folder does not exist (authorized)", async () => {
		getSession.mockResolvedValue({
			role: "admin",
			branchId: null,
			userId: "u2",
		});

		const res = await GET(
			new Request("http://localhost/api/branches/NL01/2099/months"),
			{ params: Promise.resolve({ branch: "NL01", year: "2099" }) }
		);

		expect(res.status).toBe(404);
		expect(await res.json()).toEqual({
			error: {
				message: "Not found",
				code: "FS_NOT_FOUND",
				details: { branch: "NL01", year: "2099" },
			},
		});
	});
});
