import { describe, expect, test } from "bun:test";
import { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import {
	getGoogleMapsLocationCapability,
	getGoogleMapsPlaceLabel,
	mapGooglePlacesSuggestions,
} from "@/lib/google-maps";

const renderLocationAutocomplete = async (capability: {
	enabled: boolean;
	region: string;
	reason: "configured" | "missing_server_api_key" | "disabled";
}) => {
	const { LocationAutocomplete } = await import("@/components/location-autocomplete");

	return renderToStaticMarkup(
		createElement(LocationAutocomplete, {
			capability,
			id: "event-location",
			onChange: () => {},
			value: "",
		}),
	);
};

describe("Google Maps location capability boundary", () => {
	test("disables Google Maps search when the server API key is missing", () => {
		expect(getGoogleMapsLocationCapability({ serverApiKey: "" })).toEqual({
			enabled: false,
			reason: "missing_server_api_key",
			region: "us",
		});
	});

	test("enables Google Maps search when the server API key is present", () => {
		expect(
			getGoogleMapsLocationCapability({ serverApiKey: "maps-server-key", region: "gb" }),
		).toEqual({
			enabled: true,
			reason: "configured",
			region: "gb",
		});
	});
});

describe("LocationAutocomplete fallback mode", () => {
	test("renders a plain text location field when Google Maps configuration is unavailable", async () => {
		const markup = await renderLocationAutocomplete({
			enabled: false,
			reason: "missing_server_api_key",
			region: "us",
		});

		expect(markup).toContain('data-location-mode="manual"');
		expect(markup).toContain('placeholder="Location"');
		expect(markup).not.toContain("Search Google Maps");
	});
});

describe("LocationAutocomplete configured mode", () => {
	test("renders a server-backed Google Maps-assisted input path while keeping manual typing available", async () => {
		const markup = await renderLocationAutocomplete({
			enabled: true,
			reason: "configured",
			region: "us",
		});

		expect(markup).toContain('data-location-mode="google-maps-server"');
		expect(markup).toContain('placeholder="Search Google Maps or type a location"');
		expect(markup).toContain("Search Google Maps or keep typing a custom location.");
	});
});

describe("Google Maps place label selection", () => {
	test("prefers the chosen prediction label for the visible location value", () => {
		expect(
			getGoogleMapsPlaceLabel({
				displayName: "Google HQ",
				formattedAddress: "1600 Amphitheatre Parkway, Mountain View, CA",
				predictionText: "Googleplex",
			}),
		).toBe("Googleplex");
	});
});

describe("Google Places server response mapping", () => {
	test("maps server autocomplete predictions into lightweight suggestion records", () => {
		expect(
			mapGooglePlacesSuggestions({
				suggestions: [
					{
						placePrediction: {
							place: "places/abc123",
							structuredFormat: {
								secondaryText: { text: "Mountain View, CA" },
							},
							text: { text: "Googleplex" },
						},
					},
				],
			}),
		).toEqual([
			{
				formattedAddress: "Mountain View, CA",
				placeId: "abc123",
				text: "Googleplex",
			},
		]);
	});
});
