import { beforeEach, describe, expect, it, vi } from "vitest";
import { AlbumNotFoundException } from "../exceptions";
import { apiClient } from "./axiosClient";
import { getAlbum } from "./getAlbum";

vi.mock("./axiosClient", () => ({
	apiClient: {
		get: vi.fn(),
		post: vi.fn(),
	},
}));

describe("getAlbum", () => {
	beforeEach(() => {
		vi.clearAllMocks();
	});

	it("should throw AlbumNotFoundException if canonical URL is missing", async () => {
		(apiClient.get as any).mockResolvedValue({ data: "<html></html>" });
		await expect(getAlbum("http://example.com")).rejects.toThrow(
			AlbumNotFoundException,
		);
	});

	it("should parse album metadata correctly", async () => {
		const mockHtml = `
      <html>
        <head>
          <link rel="canonical" href="https://photos.app.goo.gl/ALBUM_ID" />
        </head>
        <script>var x = "key=ALBUM_KEY";</script>
      </html>
    `;
		(apiClient.get as any).mockResolvedValue({ data: mockHtml });

		// Constructing the complex RPC response structure expected by getAlbum.ts
		// parsedResponse indices:
		// 1: albumItems (array)
		// 2: nextToken (string)
		// 3: albumDetails (array) -> [id, title, [dates...], downloadUrl, cover, owner...]

		// albumDetails indices:
		// 0: id
		// 1: title
		// 2: dates -> [,,,4:createdAt,,,,8:updatedAt]
		// 3: downloadUrl (not used in destructuring directly, but index 32 is sharedUrl? No, let's check code)
		// Code: const [albumId, albumTitle, albumDates, downloadUrl, albumCover, albumOwner] = albumDetails;
		// Index 32: sharedUrl

		const albumDates = [
			null,
			null,
			null,
			null,
			1600000000,
			null,
			null,
			null,
			1600000000,
		];
		const albumCover = ["cover_url", 100, 100];
		const albumOwner = [
			null,
			"OwnerID",
			null,
			"OwnerPhoto",
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			["Owner Fullname", null, null, "Owner Name"],
		];

		const albumDetails: any[] = [
			"ALBUM_ID",
			"Album Title",
			albumDates,
			"DownloadUrl",
			albumCover,
			albumOwner,
		];
		// pad to index 32 for sharedUrl
		for (let i = 6; i < 32; i++) albumDetails.push(null);
		albumDetails[32] = "SharedUrl";

		const parsedResponse = [
			null,
			[], // albumItems
			"NextToken",
			albumDetails,
		];

		const mockRpcResponse =
			`)]}'` +
			JSON.stringify([["w", "snAcKc", JSON.stringify(parsedResponse)]]);

		(apiClient.post as any).mockResolvedValue({ data: mockRpcResponse });

		const album = await getAlbum("http://example.com");

		expect(album.id).toBe("ALBUM_ID");
		expect(album.title).toBe("Album Title");
		expect(album.key).toBe("ALBUM_KEY");
		expect(album.owner?.fullname).toBe("Owner Fullname");
	});
});
