import { describe, it, expect } from "vitest";
import {
  getCapabilityApplicability,
  readActivationProfile,
} from "../activation-profile";
import { ALL_ARCHETYPES } from "./index";

describe("archetype catalog", () => {
  it("has at least 30 archetypes", () => {
    expect(ALL_ARCHETYPES.length).toBeGreaterThanOrEqual(30);
  });

  it("every archetype has required fields", () => {
    for (const a of ALL_ARCHETYPES) {
      expect(a.archetypeId, `${a.archetypeId} missing archetypeId`).toBeTruthy();
      expect(a.name, `${a.archetypeId} missing name`).toBeTruthy();
      expect(a.ctaType, `${a.archetypeId} missing ctaType`).toBeTruthy();
      expect(a.itemTemplates.length, `${a.archetypeId} needs items`).toBeGreaterThan(0);
      expect(a.sectionTemplates.length, `${a.archetypeId} needs sections`).toBeGreaterThan(0);
    }
  });

  it("every archetype has unique archetypeId", () => {
    const ids = ALL_ARCHETYPES.map((a) => a.archetypeId);
    const unique = new Set(ids);
    expect(unique.size).toBe(ids.length);
  });

  it("hero section always comes first", () => {
    for (const a of ALL_ARCHETYPES) {
      const sorted = [...a.sectionTemplates].sort((x, y) => x.sortOrder - y.sortOrder);
      expect(sorted[0].type, `${a.archetypeId} hero should be first section`).toBe("hero");
    }
  });

  it("all booking-type archetypes have schedulingDefaults", () => {
    const bookingArchetypes = ALL_ARCHETYPES.filter((a) => a.ctaType === "booking");
    for (const a of bookingArchetypes) {
      expect(a.schedulingDefaults, `${a.archetypeId} missing schedulingDefaults`).toBeDefined();
    }
  });

  it("it-managed-services carries a strong activation profile", () => {
    const msp = ALL_ARCHETYPES.find((a) => a.archetypeId === "it-managed-services");
    expect(msp).toBeDefined();
    expect(msp?.activationProfile?.profileType).toBe("managed-service-provider");
    expect(msp?.activationProfile?.axes).toMatchObject({
      form: "services",
      delivery: "hybrid",
      primaryConsumer: "business",
      consumptionChannel: "onsite-plus-portal",
      commercialModel: "recurring-agreement",
      provisioning: "account-and-entitlement",
      platform: "no",
    });
    expect(msp?.activationProfile?.portfolios?.manufactureAndDeliver).toMatchObject({
      scope: "primary",
      it4itStages: ["detect-to-correct", "deploy-to-operate", "request-to-fulfill"],
    });
    expect(msp?.activationProfile?.capabilityOverrides).toEqual([
      {
        capabilityKey: "remote-support",
        applicability: "recommended",
        reason: "Consent gating is not yet automated.",
      },
    ]);
    expect(msp?.activationProfile?.modules).toContain("customer-estate");
    expect(msp?.activationProfile?.modules).toContain("service-agreements");
    expect(msp?.activationProfile?.modules).toContain("service-operations");
    expect(msp?.activationProfile?.customerGraph).toBe("separate-customer-projection");
    expect(msp?.activationProfile?.estateSeparation).toBe("strict");
    expect(msp?.activationProfile?.seededConfigurationItemTypes?.some((item) => item.key === "endpoint-security-license")).toBe(true);
    expect(msp?.activationProfile?.seededChargeModels?.some((model) => model.key === "pass_through")).toBe(true);

    const normalized = readActivationProfile(msp?.activationProfile);
    expect(getCapabilityApplicability(normalized, "customer-estate")).toBe("required");
    expect(getCapabilityApplicability(normalized, "remote-support")).toBe("recommended");
  });

  it("hair salon uses appointment checkout without customer-estate activation", () => {
    const salon = ALL_ARCHETYPES.find((a) => a.archetypeId === "hair-salon");
    expect(salon).toBeDefined();
    expect(salon?.activationProfile?.axes).toMatchObject({
      form: "services",
      delivery: "physical",
      primaryConsumer: "individual",
      consumptionChannel: "physical",
      commercialModel: "appointment-checkout",
      provisioning: "account-with-billing",
      platform: "no",
    });

    const normalized = readActivationProfile(salon?.activationProfile);
    expect(getCapabilityApplicability(normalized, "appointment-checkout")).toBe("required");
    expect(getCapabilityApplicability(normalized, "point-of-sale")).toBe("required");
    expect(getCapabilityApplicability(normalized, "customer-estate")).toBe("not-applicable");
  });

  it("includes a software-platform archetype for DPF-style product sellers", () => {
    const softwarePlatform = ALL_ARCHETYPES.find((a) => a.archetypeId === "software-platform");
    expect(softwarePlatform).toBeDefined();
    expect(softwarePlatform?.category).toBe("software-platform");
    expect(softwarePlatform?.ctaType).toBe("inquiry");
    expect(softwarePlatform?.itemTemplates.some((item) => item.name === "Open Digital Product Factory")).toBe(true);
  });
});
