/**
 * dashboard-model-label-ordering.test.ts — Regression test for #2899.
 *
 * The dashboard model label was showing the previous unit's model because
 * updateProgressWidget was called before selectAndApplyModel in phases.ts.
 * This test verifies:
 *   1. updateProgressWidget is called AFTER selectAndApplyModel in phases.ts
 *   2. session.ts has a currentDispatchedModelId field
 *   3. auto.ts exposes getCurrentDispatchedModelId in widgetStateAccessors
 *   4. auto-dashboard.ts reads from a dispatched model accessor, not cmdCtx?.model
 */

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, it } from "vitest";

const phasesPath = join(import.meta.dirname, "..", "auto", "phases.ts");
const sessionPath = join(import.meta.dirname, "..", "auto", "session.ts");
const autoPath = join(import.meta.dirname, "..", "auto.ts");
const dashboardPath = join(import.meta.dirname, "..", "auto-dashboard.ts");

const phasesSrc = readFileSync(phasesPath, "utf-8");
const sessionSrc = readFileSync(sessionPath, "utf-8");
const autoSrc = readFileSync(autoPath, "utf-8");
const dashboardSrc = readFileSync(dashboardPath, "utf-8");

describe("#2899: Dashboard model label shows correct (dispatched) model", () => {
	it("selectAndApplyModel is called BEFORE updateProgressWidget in phases.ts", () => {
		const selectModelPos = phasesSrc.indexOf("deps.selectAndApplyModel(");
		const updateWidgetPos = phasesSrc.indexOf("deps.updateProgressWidget(");

		assert.ok(selectModelPos > 0, "phases.ts contains deps.selectAndApplyModel call");
		assert.ok(updateWidgetPos > 0, "phases.ts contains deps.updateProgressWidget call");
		assert.ok(
			selectModelPos < updateWidgetPos,
			`selectAndApplyModel (pos ${selectModelPos}) must be called BEFORE updateProgressWidget (pos ${updateWidgetPos})`,
		);
	});

	it("session.ts declares currentDispatchedModelId", () => {
		assert.ok(sessionSrc.includes("currentDispatchedModelId"));
	});

	it("auto.ts exposes getCurrentDispatchedModelId in widgetStateAccessors", () => {
		assert.ok(autoSrc.includes("getCurrentDispatchedModelId"));

		const accessorsBlock = autoSrc.slice(
			autoSrc.indexOf("const widgetStateAccessors"),
			autoSrc.indexOf("};", autoSrc.indexOf("const widgetStateAccessors")) + 2,
		);
		assert.ok(accessorsBlock.includes("getCurrentDispatchedModelId"));
	});

	it("auto-dashboard.ts references getCurrentDispatchedModelId", () => {
		assert.ok(dashboardSrc.includes("getCurrentDispatchedModelId"));
	});

	it("Model display section reads from dispatched model accessor", () => {
		const modelDisplaySection = dashboardSrc.slice(
			dashboardSrc.indexOf("// Model display"),
			dashboardSrc.indexOf("// Model display") + 500,
		);
		assert.ok(
			modelDisplaySection.includes("getCurrentDispatchedModelId") ||
				modelDisplaySection.includes("getDispatchedModelId"),
		);
	});

	it("phases.ts stores currentDispatchedModelId after model selection", () => {
		assert.ok(phasesSrc.includes("currentDispatchedModelId"));
	});
});
