import assert from "node:assert/strict";
import { test } from "vitest";

import { createExtensionUIContext } from "./extension-ui-controller.js";

test("notify_when_host_has_extension_notify_uses_dedicated_handler", () => {
	const calls: unknown[][] = [];
	const ui = createExtensionUIContext({
		showExtensionNotify(message: string, type: string) {
			calls.push([message, type]);
		},
	});

	ui.notify("Ready", "success");

	assert.deepEqual(calls, [["Ready", "success"]]);
});

test("notify_when_extension_notify_missing_routes_errors_and_warnings_to_existing_host_methods", () => {
	const errors: string[] = [];
	const warnings: string[] = [];
	const ui = createExtensionUIContext({
		showError(message: string) {
			errors.push(message);
		},
		showWarning(message: string) {
			warnings.push(message);
		},
	});

	ui.notify("Failed", "error");
	ui.notify("Careful", "warning");

	assert.deepEqual(errors, ["Failed"]);
	assert.deepEqual(warnings, ["Careful"]);
});

test("notify_when_extension_notify_missing_routes_info_and_success_to_status", () => {
	const statuses: unknown[][] = [];
	const ui = createExtensionUIContext({
		showStatus(message: string, options?: unknown) {
			statuses.push([message, options]);
		},
	});

	ui.notify("Started", "info");
	ui.notify("Done", "success");

	assert.deepEqual(statuses, [
		["Started", { append: false }],
		["Done", { append: true }],
	]);
});

test("set_widget_when_host_supports_widgets_uses_dedicated_handler", () => {
	const calls: unknown[][] = [];
	const ui = createExtensionUIContext({
		setExtensionWidget(key: string, content: unknown, options?: unknown) {
			calls.push([key, content, options]);
		},
	});

	const content = ["Ready"];
	const options = { placement: "belowEditor" as const };
	ui.setWidget("sf-notifications", content, options);

	assert.deepEqual(calls, [["sf-notifications", content, options]]);
});

test("set_widget_when_widget_host_throws_degrades_silently_without_extension_error", () => {
	const ui = createExtensionUIContext({
		setExtensionWidget() {
			throw new TypeError("host.setExtensionWidget is not a function");
		},
	});

	// Should not throw — the widget setter catches invocation errors.
	ui.setWidget("sf-progress", ["Ready"], { placement: "belowEditor" });
});

test("set_widget_when_widget_host_missing_degrades_to_no_op", () => {
	const ui = createExtensionUIContext({
		// No setExtensionWidget — host does not support extension widgets.
	});

	// Should not throw — the widget setter is a no-op when unsupported.
	ui.setWidget("sf-notifications", ["Ready", "Next"], {
		placement: "belowEditor",
	});
});

test("set_widget_when_widget_host_missing_ignores_factory_without_throwing", () => {
	const ui = createExtensionUIContext({
		// No setExtensionWidget — host does not support extension widgets.
	});

	// Should not throw — factory widgets are silently ignored when unsupported.
	ui.setWidget(
		"sf-notifications",
		() => ({
			render: () => [],
			invalidate: () => {},
		}),
		{ placement: "belowEditor" },
	);
});

test("dialog_methods_when_host_dialogs_missing_degrade_without_throwing", async () => {
	const ui = createExtensionUIContext({
		// RPC/headless-style hosts may not implement interactive dialogs.
	});

	await assert.doesNotReject(async () => {
		assert.equal(await ui.confirm("Proceed?", "Dangerous command"), false);
		assert.equal(await ui.select("Pick one", ["a", "b"]), undefined);
		assert.equal(await ui.input("Value", "placeholder"), undefined);
	});
});
