import { describe, expect, it } from "vitest";
import {
  buildEstimateDemandLineRows,
  buildEffortRuleCreateManyRows,
  buildEffortRuleNestedCreateRows,
  buildEffortRuleSetCreateData,
  buildEffortRuleSetUpdateData,
  effortRuleInclude,
  toEffortRuleEngineInputs,
  toScopeItemInputs,
} from "../router/effort-rule-support.js";

describe("effort rule support", () => {
  it("exposes the rule include ordering", () => {
    expect(effortRuleInclude).toEqual({
      rules: { orderBy: { sortOrder: "asc" } },
    });
  });

  it("builds rule rows and preserves fallback sort order", () => {
    expect(buildEffortRuleCreateManyRows([
      {
        scopeType: "shot",
        discipline: "Compositing",
        chapter: "VFX",
        unitMode: "per_frame",
        hoursPerUnit: 0.08,
      },
      {
        scopeType: "asset",
        discipline: "Modeling",
        unitMode: "per_item",
        hoursPerUnit: 8,
        description: "Hero asset",
        sortOrder: 5,
      },
    ], "ers_1")).toEqual([
      {
        ruleSetId: "ers_1",
        scopeType: "shot",
        discipline: "Compositing",
        chapter: "VFX",
        unitMode: "per_frame",
        hoursPerUnit: 0.08,
        sortOrder: 0,
      },
      {
        ruleSetId: "ers_1",
        scopeType: "asset",
        discipline: "Modeling",
        unitMode: "per_item",
        hoursPerUnit: 8,
        description: "Hero asset",
        sortOrder: 5,
      },
    ]);

    expect(buildEffortRuleNestedCreateRows([
      {
        scopeType: "shot",
        discipline: "Compositing",
        unitMode: "per_frame",
        hoursPerUnit: 0.08,
      },
    ])).toEqual([
      {
        scopeType: "shot",
        discipline: "Compositing",
        unitMode: "per_frame",
        hoursPerUnit: 0.08,
        sortOrder: 0,
      },
    ]);
  });

  it("builds create and sparse update payloads", () => {
    expect(buildEffortRuleSetCreateData({
      name: "VFX Standard",
      description: "Default effort rules",
      isDefault: true,
      rules: [
        {
          scopeType: "shot",
          discipline: "Compositing",
          unitMode: "per_frame",
          hoursPerUnit: 0.08,
          sortOrder: 0,
        },
      ],
    })).toEqual({
      name: "VFX Standard",
      description: "Default effort rules",
      isDefault: true,
      rules: {
        create: [
          {
            scopeType: "shot",
            discipline: "Compositing",
            unitMode: "per_frame",
            hoursPerUnit: 0.08,
            sortOrder: 0,
          },
        ],
      },
    });

    expect(buildEffortRuleSetUpdateData({
      description: null,
      isDefault: false,
    })).toEqual({
      description: null,
      isDefault: false,
    });
  });

  it("maps scope items and rules into engine inputs", () => {
    expect(toScopeItemInputs([
      {
        name: "Shot_001",
        scopeType: "shot",
        frameCount: 100,
        itemCount: null,
        unitMode: "per_frame",
      },
    ])).toEqual([
      {
        name: "Shot_001",
        scopeType: "shot",
        frameCount: 100,
        itemCount: null,
        unitMode: "per_frame",
      },
    ]);

    expect(toEffortRuleEngineInputs([
      {
        scopeType: "shot",
        discipline: "Compositing",
        chapter: null,
        unitMode: "per_frame",
        hoursPerUnit: 0.08,
        sortOrder: 0,
      },
    ])).toEqual([
      {
        scopeType: "shot",
        discipline: "Compositing",
        chapter: null,
        unitMode: "per_frame",
        hoursPerUnit: 0.08,
        sortOrder: 0,
      },
    ]);
  });

  it("builds estimate demand line rows with the current optional chapter semantics", () => {
    expect(buildEstimateDemandLineRows({
      estimateVersionId: "ver_1",
      currency: "EUR",
      ruleSet: { id: "ers_1", name: "VFX Standard" },
      lines: [
        {
          scopeItemName: "Shot_001",
          scopeType: "shot",
          discipline: "Compositing",
          chapter: "",
          hours: 16,
          unitMode: "per_frame",
          unitCount: 200,
          hoursPerUnit: 0.08,
        },
      ],
    })).toEqual([
      {
        estimateVersionId: "ver_1",
        lineType: "LABOR",
        name: "Compositing — Shot_001",
        hours: 16,
        costRateCents: 0,
        billRateCents: 0,
        currency: "EUR",
        costTotalCents: 0,
        priceTotalCents: 0,
        monthlySpread: {},
        staffingAttributes: {},
        metadata: {
          effortRule: {
            ruleSetId: "ers_1",
            ruleSetName: "VFX Standard",
            discipline: "Compositing",
            unitMode: "per_frame",
            unitCount: 200,
            hoursPerUnit: 0.08,
          },
        },
      },
    ]);
  });
});
