// Vitest coverage for the Phase 20 dismantle confirmation. The
// inspector requires an explicit second click ("colonists die") when
// the player tries to dismantle a colonist-laden group over a
// foreign planet — engine rule reference:
// `controller/ship_group.go.shipGroupDismantle:177-179` (over a
// foreign planet, `UnloadColonists` is not called and the cargo is
// lost).

import "@testing-library/jest-dom/vitest";
import "fake-indexeddb/auto";
import { fireEvent, render, waitFor } from "@testing-library/svelte";
import { afterEach, beforeEach, describe, expect, test } from "vitest";

import { i18n } from "../src/lib/i18n/index.svelte";
import type {
	ReportLocalShipGroup,
	ReportPlanet,
	ShipClassSummary,
} from "../src/api/game-state";
import ShipGroup, {
	type ShipGroupSelection,
} from "../src/lib/inspectors/ship-group.svelte";
import {
	ORDER_DRAFT_CONTEXT_KEY,
	OrderDraftStore,
} from "../src/sync/order-draft.svelte";
import { IDBCache } from "../src/platform/store/idb-cache";
import { openGalaxyDB, type GalaxyDB } from "../src/platform/store/idb";
import type { Cache } from "../src/platform/store/index";
import type { IDBPDatabase } from "idb";

const GAME_ID = "11111111-2222-3333-4444-555555555555";

let db: IDBPDatabase<GalaxyDB>;
let dbName: string;
let cache: Cache;
let draft: OrderDraftStore;

const PLANETS: ReportPlanet[] = [
	{
		number: 99,
		name: "Outpost",
		x: 100,
		y: 100,
		kind: "other",
		owner: "Foreign",
		size: 500,
		resources: 5,
		industryStockpile: 0,
		materialsStockpile: 0,
		industry: 500,
		population: 500,
		colonists: 100,
		production: "Capital",
		freeIndustry: 500,
	},
	{
		number: 17,
		name: "Castle",
		x: 50,
		y: 50,
		kind: "local",
		owner: null,
		size: 1000,
		resources: 5,
		industryStockpile: 0,
		materialsStockpile: 0,
		industry: 1000,
		population: 1000,
		colonists: 100,
		production: "Capital",
		freeIndustry: 1000,
	},
];

const SHIP_CLASS_FRONTIER: ShipClassSummary = {
	name: "Frontier",
	drive: 5,
	armament: 0,
	weapons: 0,
	shields: 0,
	cargo: 1,
};

beforeEach(async () => {
	dbName = `galaxy-ship-group-dismantle-${crypto.randomUUID()}`;
	db = await openGalaxyDB(dbName);
	cache = new IDBCache(db);
	draft = new OrderDraftStore();
	await draft.init({ cache, gameId: GAME_ID });
	i18n.resetForTests("en");
});

afterEach(async () => {
	draft.dispose();
	db.close();
	await new Promise<void>((resolve) => {
		const req = indexedDB.deleteDatabase(dbName);
		req.onsuccess = () => resolve();
		req.onerror = () => resolve();
		req.onblocked = () => resolve();
	});
});

function group(
	overrides: Partial<ReportLocalShipGroup> = {},
): ReportLocalShipGroup {
	return {
		id: "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
		count: 2,
		class: "Frontier",
		tech: { drive: 1, weapons: 0, shields: 0, cargo: 1 },
		cargo: "COL",
		load: 1.5,
		destination: 99,
		origin: null,
		range: null,
		speed: 0,
		mass: 12,
		state: "In_Orbit",
		fleet: null,
		...overrides,
	};
}

function mount(g: ReportLocalShipGroup) {
	const selection: ShipGroupSelection = { variant: "local", group: g };
	const context = new Map<unknown, unknown>([
		[ORDER_DRAFT_CONTEXT_KEY, draft],
	]);
	return render(ShipGroup, {
		props: {
			selection,
			planets: PLANETS,
			localShipClass: [SHIP_CLASS_FRONTIER],
			localFleets: [],
			otherRaces: ["Aliens"],
			mapWidth: 1000,
			mapHeight: 1000,
			localPlayerDrive: 5,
			localPlayerWeapons: 1,
			localPlayerShields: 1,
			localPlayerCargo: 2,
		},
		context,
	});
}

describe("ship-group inspector — dismantle confirmation", () => {
	test("first click on dismantle of foreign-COL group shows the warning and adds nothing", async () => {
		const ui = mount(group());
		await fireEvent.click(ui.getByTestId("inspector-ship-group-action-dismantle"));
		expect(
			ui.getByTestId("inspector-ship-group-form-dismantle-warning"),
		).toBeInTheDocument();
		const confirm = ui.getByTestId(
			"inspector-ship-group-form-dismantle-confirm",
		);
		expect(confirm).toHaveTextContent(/colonists die/i);
		await fireEvent.click(confirm);
		expect(draft.commands).toHaveLength(0);
	});

	test("second click on the colonists-die confirm emits dismantleShipGroup", async () => {
		const ui = mount(group());
		await fireEvent.click(ui.getByTestId("inspector-ship-group-action-dismantle"));
		const confirm = ui.getByTestId(
			"inspector-ship-group-form-dismantle-confirm",
		);
		await fireEvent.click(confirm);
		await fireEvent.click(confirm);
		await waitFor(() => expect(draft.commands).toHaveLength(1));
		const cmd = draft.commands[0]!;
		expect(cmd.kind).toBe("dismantleShipGroup");
	});

	test("dismantle over own planet skips the warning even with COL aboard", async () => {
		const ui = mount(group({ destination: 17 }));
		await fireEvent.click(ui.getByTestId("inspector-ship-group-action-dismantle"));
		expect(
			ui.queryByTestId("inspector-ship-group-form-dismantle-warning"),
		).toBeNull();
		await fireEvent.click(
			ui.getByTestId("inspector-ship-group-form-dismantle-confirm"),
		);
		await waitFor(() => expect(draft.commands).toHaveLength(1));
		expect(draft.commands[0]!.kind).toBe("dismantleShipGroup");
	});

	test("dismantle over foreign planet without colonists skips the warning", async () => {
		const ui = mount(group({ cargo: "NONE", load: 0 }));
		await fireEvent.click(ui.getByTestId("inspector-ship-group-action-dismantle"));
		expect(
			ui.queryByTestId("inspector-ship-group-form-dismantle-warning"),
		).toBeNull();
		await fireEvent.click(
			ui.getByTestId("inspector-ship-group-form-dismantle-confirm"),
		);
		await waitFor(() => expect(draft.commands).toHaveLength(1));
	});
});
