// Coverage for the F8-12 sizing helpers in src/map/world.ts:
// `displayPointRadiusWorld` (the union of the pixel-space and the
// softened-by-zoom rules) and `displayStrokeWidthWorld` (pixel-space
// stroke widths). Both are pure math, so this file stays Pixi-free.

import { describe, expect, test } from "vitest";

import {
	DEFAULT_POINT_RADIUS_PX,
	PLANET_SIZE_ZOOM_ALPHA,
	displayPointRadiusWorld,
	displayStrokeWidthWorld,
} from "../src/map/world";

describe("displayPointRadiusWorld — pixel-space (pointRadiusPx)", () => {
	test("returns pixel size divided by scale at scale=1", () => {
		expect(displayPointRadiusWorld({ pointRadiusPx: 5 }, 1, 0.2)).toBe(5);
	});

	test("shrinks the world footprint as zoom grows", () => {
		expect(displayPointRadiusWorld({ pointRadiusPx: 6 }, 3, 0.2)).toBeCloseTo(2);
	});

	test("falls back to DEFAULT_POINT_RADIUS_PX when the style is bare", () => {
		expect(displayPointRadiusWorld({}, 2, 0.2)).toBeCloseTo(
			DEFAULT_POINT_RADIUS_PX / 2,
		);
	});

	test("zero-scale guard returns the raw pixel size", () => {
		expect(displayPointRadiusWorld({ pointRadiusPx: 4 }, 0, 0.2)).toBe(4);
	});
});

describe("displayPointRadiusWorld — softened by zoom (pointRadiusBasePx)", () => {
	test("at scale=scaleRef the on-screen pixel size equals the base", () => {
		const radius = displayPointRadiusWorld(
			{ pointRadiusBasePx: 6 },
			0.2,
			0.2,
		);
		// world units → 6 (base px) / 0.2 (scale) = 30
		expect(radius).toBeCloseTo(30);
		// confirm pixel-space: world * scale ≈ 6.
		expect(radius * 0.2).toBeCloseTo(6);
	});

	test("zooming in grows the on-screen pixel size sub-linearly", () => {
		const r1 = displayPointRadiusWorld({ pointRadiusBasePx: 6 }, 0.2, 0.2);
		const r10 = displayPointRadiusWorld({ pointRadiusBasePx: 6 }, 2.0, 0.2);
		// On-screen pixel size grows by scale^α (α = 0.33): 10x zoom
		// → 10^0.33 ≈ 2.15x growth.
		const onScreenAt1 = r1 * 0.2;
		const onScreenAt10 = r10 * 2.0;
		expect(onScreenAt10 / onScreenAt1).toBeCloseTo(
			Math.pow(10, PLANET_SIZE_ZOOM_ALPHA),
			3,
		);
	});

	test("ignores pointRadiusPx when pointRadiusBasePx is set", () => {
		const r = displayPointRadiusWorld(
			{ pointRadiusPx: 99, pointRadiusBasePx: 4 },
			0.4,
			0.2,
		);
		// On-screen pixel size: 4 * (0.4 / 0.2)^α = 4 * 2^0.33
		// In world units: (4 * 2^0.33) / 0.4.
		const expected = (4 * Math.pow(2, PLANET_SIZE_ZOOM_ALPHA)) / 0.4;
		expect(r).toBeCloseTo(expected, 4);
	});
});

describe("displayStrokeWidthWorld", () => {
	test("returns width / scale at any zoom", () => {
		expect(displayStrokeWidthWorld({ strokeWidthPx: 2 }, 1)).toBe(2);
		expect(displayStrokeWidthWorld({ strokeWidthPx: 2 }, 4)).toBeCloseTo(0.5);
		expect(displayStrokeWidthWorld({ strokeWidthPx: 2 }, 0.5)).toBeCloseTo(4);
	});

	test("falls back to 1 when strokeWidthPx is omitted", () => {
		expect(displayStrokeWidthWorld({}, 2)).toBeCloseTo(0.5);
	});

	test("zero-scale guard returns the raw pixel value", () => {
		expect(displayStrokeWidthWorld({ strokeWidthPx: 3 }, 0)).toBe(3);
	});
});
