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

import {
  ModelConfigurationError,
  modelIds,
  validateModelConfigurationCandidateSet,
  type ModelConfigCandidate,
} from "../../apps/api/src/model-configuration.js";

function candidateSet(): ModelConfigCandidate[] {
  return modelIds.map((modelId, index) => ({
    model_id: modelId,
    display_name: modelId,
    enabled: true,
    is_default: index === 0,
    recommendation_priority: index + 1,
    route_profile: { endpoint: "https://mock.invalid/v1/images" },
    gateway_account_ref: "mock-gateway",
    error_mapping_profile: { timeout: "upstream_timeout" },
    credit_cost: 1,
    supported_ratios: ["3:4", "1:1", "4:3", "9:16"],
    reference_limits: { max_file_bytes: 1_024, max_files: 2, max_total_bytes: 2_048 },
    prompt_max_length: 1_000,
    safety_source: "provider",
  }));
}

describe("TDD-WP3-MDL-002 invalid full configuration sets", () => {
  it.each([
    ["missing", undefined],
    ["fractional", 1.5],
    ["zero", 0],
    ["negative", -1],
  ])("rejects a %s recommendation priority", (_name, value) => {
    const models = candidateSet();
    models[1].recommendation_priority = value as number;
    expect(() => validateModelConfigurationCandidateSet(models)).toThrowError(
      expect.objectContaining({ code: "MODEL_RECOMMENDATION_PRIORITY_INVALID" }),
    );
  });

  it("rejects duplicate priorities", () => {
    const models = candidateSet();
    models[1].recommendation_priority = models[0].recommendation_priority;
    expect(() => validateModelConfigurationCandidateSet(models)).toThrowError(
      expect.objectContaining({ code: "MODEL_RECOMMENDATION_PRIORITY_CONFLICT" }),
    );
  });

  it.each(["missing model", "unknown model"])("rejects a candidate with a %s", (scenario) => {
    const models = candidateSet();
    if (scenario === "missing model") models.pop();
    else models[2].model_id = "unknown-model";
    expect(() => validateModelConfigurationCandidateSet(models)).toThrowError(ModelConfigurationError);
  });
});
