import assert from "node:assert/strict";
import { describe, it } from "node:test";
import type { ClassifierContext, Provider } from "@earendil-works/pi-ai";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { parseCatalogPage, toExplabsModel } from "../src/catalog.ts";
import experientialLabs from "../src/index.ts";

// Relevant fields from the public Jev catalog entry (2026-09-30).
const jevRow = {
	model: {
		slug: "jev-latest",
		display_name: "Jev",
		status: "active",
		context_window: null,
		input_modalities: ["text"],
		output_modalities: ["text"],
		supported_params: {},
	},
	providers: [{
		provider: "typesafe",
		billing_source: "host_managed",
		input_nano_usd_per_million: 42_000_000,
		cached_input_nano_usd_per_million: 42_000_000,
		output_nano_usd_per_million: 0,
		capabilities: { supports_decisions: true, supports_tools: false },
	}],
};

describe("Jev classifiers", () => {
	it("maps decision capabilities without requiring tools and reads nano-USD pricing", () => {
		const { model, providers } = parseCatalogPage({ models: [jevRow] }).models[0];
		const mapped = toExplabsModel(model, providers, "https://gateway.example/v1");
		assert.deepEqual({ ...mapped, headers: undefined }, {
			type: "classifier",
			id: "jev-latest",
			name: "Jev",
			api: "typesafe-system-one",
			provider: "explabs",
			baseUrl: "https://gateway.example/v1",
			headers: undefined,
			input: ["text"],
			cost: { input: 0.042, output: 0, cacheRead: 0.042, cacheWrite: 0 },
			contextWindow: 32_000,
			protocolHints: { defaultProvider: "typesafe" },
		});
		assert.equal(toExplabsModel({ ...model, status: "inactive" }, providers, "https://gateway.example/v1"), undefined);
		assert.equal(toExplabsModel({ ...model, slug: "jev-batch" }, providers, "https://gateway.example/v1"), undefined);
		assert.equal(toExplabsModel(model, [], "https://gateway.example/v1"), undefined);
		assert.equal(toExplabsModel({ ...model, context_window: 48_000 }, providers, "https://gateway.example/v1")?.contextWindow, 48_000);
	});

	it("discovers, persists, and invokes Jev through the registered provider", async (t) => {
		let registered: Provider | undefined;
		experientialLabs({
			registerProvider: (provider: Provider) => { registered = provider; },
			on: () => {},
			registerCommand: () => {},
		} as unknown as ExtensionAPI);
		assert.ok(registered?.refreshModels);
		const provider = registered;
		t.mock.method(globalThis, "fetch", async (input: URL | string, init?: RequestInit) => {
			assert.equal(new URL(String(input)).searchParams.has("supports"), false);
			assert.equal(new Headers(init?.headers).get("authorization"), "Bearer xpl_test");
			return Response.json({ models: [jevRow], total: 1 });
		});
		let persisted = false;
		await provider.refreshModels!({
			credential: { type: "api_key", key: "xpl_test" },
			allowNetwork: true,
			signal: new AbortController().signal,
			publish: async ({ persist, update }) => {
				if (persist) {
					assert.equal(persist.models[0].type, "classifier");
					persisted = true;
				}
				update?.();
				return true;
			},
		});
		assert.equal(persisted, true);
		assert.deepEqual(provider.getModels(), []);
		const model = provider.getAllModels?.()[0];
		assert.equal(model?.type, "classifier");
		assert.ok(model?.type === "classifier");
		assert.ok(provider.classify);
		const context: ClassifierContext = {
			state: { prompt: "Fix a race" },
			questions: {
				complexity: { type: "choice", instructions: "Rate complexity", criteria: { simple: "Routine", complex: "Subtle" } },
				ready: { type: "bool", instructions: "Ready?", criteria: { true: "Yes", false: "No" } },
			},
		};
		const result = await provider.classify(model, context, {
			apiKey: "xpl_test",
			fetch: async (input, init) => {
				assert.equal(String(input), `${model.baseUrl}/systemone`);
				assert.equal(new Headers(init?.headers).get("authorization"), "Bearer xpl_test");
				assert.match(new Headers(init?.headers).get("user-agent") ?? "", /^pi-experientiallabs\//);
				assert.deepEqual(JSON.parse(String(init?.body)), {
					model: "jev-latest", state: context.state,
					questions: { ...context.questions, ready: { ...context.questions.ready, type: "noul" } },
				});
				return Response.json({ answers: {
					complexity: { type: "choice", choice: "complex", probabilities: { simple: 0.15, complex: 0.85 }, confidence: 0.85 },
					ready: { type: "noul", noul: 0.3 },
				}, usage: { input_tokens: 100, output_tokens: 0 } });
			},
		});
		assert.equal(result.stopReason, "stop");
		assert.equal(result.provider, "explabs");
		assert.deepEqual(result.answers, {
			complexity: { type: "choice", choice: "complex", probabilities: { simple: 0.15, complex: 0.85 }, confidence: 0.85 },
			ready: { type: "bool", probability: 0.3 },
		});
		assert.ok(Math.abs((result.usage?.cost.input ?? NaN) - 0.0000042) < 1e-15);
	});
});
