import { PermissionKey } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { describe, expect, it } from "vitest";
import {
  buildChargeabilityReportDetail,
  getChargeabilityReportDetail,
} from "../router/chargeability-report-procedure-support.js";

describe("chargeability report procedure support", () => {
  it("builds a filtered detailed report with rounded percentages", () => {
    const result = buildChargeabilityReportDetail(
      {
        monthKeys: ["2026-03"],
        groupTotals: [
          {
            monthKey: "2026-03",
            totalFte: 1.234,
            chg: 0.456,
            target: 0.8,
            gap: -0.344,
            chargeabilityRatio: 0.456,
            targetRatio: 0.8,
            gapRatio: -0.344,
          },
        ],
        resources: [
          {
            id: "resource_1",
            eid: "E-001",
            displayName: "Alice",
            fte: 1.234,
            country: "ES",
            federalState: null,
            city: "Barcelona",
            orgUnit: "CGI",
            mgmtGroup: "Senior",
            mgmtLevel: "L7",
            targetPct: 0.8,
            months: [
              {
                monthKey: "2026-03",
                sah: 120.44,
                sahHours: 120.44,
                chg: 0.456,
                bd: 0.1,
                mdi: 0.05,
                mo: 0.07,
                pdr: 0.08,
                absence: 0.09,
                unassigned: 0.154,
                chargeabilityRatio: 0.456,
                businessDevelopmentRatio: 0.1,
                marketDevelopmentInnovationRatio: 0.05,
                managementOverheadRatio: 0.07,
                peopleDevelopmentRecruitingRatio: 0.08,
                plannedAbsenceRatio: 0.09,
                unassignedRatio: 0.154,
                chargeabilityHours: 54.9,
                businessDevelopmentHours: 12,
                marketDevelopmentInnovationHours: 6,
                managementOverheadHours: 8.4,
                peopleDevelopmentRecruitingHours: 9.6,
                plannedAbsenceHours: 10.8,
                unassignedHours: 18.5,
                targetRatio: 0.8,
                targetHours: 96.4,
                gapRatio: -0.344,
                gapHours: -41.4,
                derivation: {
                  baseAvailableHours: 128,
                  publicHolidayCount: 1,
                  publicHolidayWorkdayCount: 1,
                  publicHolidayHoursDeduction: 8,
                  absenceDayEquivalent: 0.5,
                  absenceHoursDeduction: 4,
                  effectiveAvailableHours: 120,
                },
              },
            ],
          },
          {
            id: "resource_2",
            eid: "E-002",
            displayName: "Bob",
            fte: 1,
            country: "DE",
            federalState: "BY",
            city: "Munich",
            orgUnit: "CGI",
            mgmtGroup: "Senior",
            mgmtLevel: "L7",
            targetPct: 0.75,
            months: [],
          },
        ],
      },
      {
        startMonth: "2026-03",
        endMonth: "2026-03",
        resourceQuery: "ali",
        resourceLimit: 1,
        includeProposed: false,
      },
    );

    expect(result.filters).toEqual({
      startMonth: "2026-03",
      endMonth: "2026-03",
      orgUnitId: null,
      managementLevelGroupId: null,
      countryId: null,
      includeProposed: false,
      resourceQuery: "ali",
    });
    expect(result.groupTotals).toEqual([
      {
        monthKey: "2026-03",
        totalFte: 1.2,
        chargeabilityPct: 45.6,
        targetPct: 80,
        gapPct: -34.4,
      },
    ]);
    expect(result.resourceCount).toBe(1);
    expect(result.returnedResourceCount).toBe(1);
    expect(result.truncated).toBe(false);
    expect(result.resources[0]).toEqual(
      expect.objectContaining({
        displayName: "Alice",
        targetPct: 80,
        managementLevelGroup: "Senior",
        managementLevel: "L7",
        months: [
          expect.objectContaining({
            monthKey: "2026-03",
            sah: 120.4,
            chargeabilityPct: 45.6,
            targetPct: 80,
            gapPct: -34.4,
          }),
        ],
      }),
    );
  });

  it("rejects detailed reports without the cost-view permission", async () => {
    await expect(
      getChargeabilityReportDetail(
        {
          db: {
            resource: { findMany: async () => [] },
          } as never,
          permissions: new Set(),
        },
        {
          startMonth: "2026-03",
          endMonth: "2026-03",
          includeProposed: false,
        },
      ),
    ).rejects.toEqual(
      expect.objectContaining<Partial<TRPCError>>({
        code: "FORBIDDEN",
        message: `Permission required: ${PermissionKey.VIEW_COSTS}`,
      }),
    );
  });
});
