import { BlueprintTarget, type BlueprintFieldDefinition, FieldType } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { describe, expect, it, vi } from "vitest";
import {
  buildBlueprintCreateData,
  buildBlueprintRolePresetsUpdateData,
  buildBlueprintUpdateData,
  expandGlobalBlueprintFieldDefs,
  findBlueprintByIdentifier,
} from "../router/blueprint-support.js";

describe("blueprint support", () => {
  it("resolves blueprints by exact then fuzzy name", async () => {
    const db = {
      blueprint: {
        findUnique: vi.fn().mockResolvedValue(null),
        findFirst: vi.fn()
          .mockResolvedValueOnce(null)
          .mockResolvedValueOnce({ id: "bp_1", name: "Consulting Blueprint" }),
      },
    } as never;

    const result = await findBlueprintByIdentifier<{ id: string; name: string }>(
      db,
      " consulting ",
      { select: { id: true, name: true } },
    );

    expect(result).toEqual({ id: "bp_1", name: "Consulting Blueprint" });
    expect(db.blueprint.findFirst).toHaveBeenNthCalledWith(2, {
      where: { name: { contains: "consulting", mode: "insensitive" } },
      select: { id: true, name: true },
    });
  });

  it("throws when the blueprint cannot be resolved", async () => {
    const db = {
      blueprint: {
        findUnique: vi.fn().mockResolvedValue(null),
        findFirst: vi.fn().mockResolvedValue(null),
      },
    } as never;

    await expect(findBlueprintByIdentifier(db, "missing", { select: { id: true } })).rejects.toBeInstanceOf(TRPCError);
  });

  it("builds create, update, and role preset payloads", () => {
    expect(buildBlueprintCreateData({
      name: "Consulting Blueprint",
      target: BlueprintTarget.PROJECT,
      description: "Default setup",
      fieldDefs: [],
      defaults: { market: "EU" },
      validationRules: [],
    })).toEqual({
      name: "Consulting Blueprint",
      target: BlueprintTarget.PROJECT,
      description: "Default setup",
      fieldDefs: [],
      defaults: { market: "EU" },
      validationRules: [],
    });

    expect(buildBlueprintUpdateData({
      description: "Updated",
      fieldDefs: [{ key: "market", type: FieldType.TEXT }],
    })).toEqual({
      description: "Updated",
      fieldDefs: [{ key: "market", type: FieldType.TEXT }],
    });

    expect(buildBlueprintRolePresetsUpdateData([{ roleId: "role_1" }])).toEqual({
      rolePresets: [{ roleId: "role_1" }],
    });
  });

  it("expands global field definitions with blueprint metadata", () => {
    const fieldDefs: BlueprintFieldDefinition[] = [
      {
        id: "field_market",
        key: "market",
        label: "Market",
        order: 0,
        type: FieldType.TEXT,
        required: false,
      },
    ];

    expect(expandGlobalBlueprintFieldDefs([
      {
        id: "bp_project_global",
        name: "Global Project Blueprint",
        fieldDefs,
      },
    ])).toEqual([
      {
        id: "field_market",
        key: "market",
        label: "Market",
        order: 0,
        type: FieldType.TEXT,
        required: false,
        blueprintId: "bp_project_global",
        blueprintName: "Global Project Blueprint",
      },
    ]);
  });
});
