import { afterEach, describe, expect, it } from "vitest";
import { createRequire } from "node:module";

const require = createRequire(import.meta.url);
const mock = require("mock-require");

const graphClientModuleId = require.resolve("../graphql-client/graphql-client");
const queriesModuleId = require.resolve("../graphql-client/queries");
const helpersModuleId = require.resolve("./rr-job-helpers");

const loadHelpers = () => {
  mock.stopAll();
  mock(graphClientModuleId, { client: { request: async () => ({}) } });
  mock(queriesModuleId, { GET_JOB_BY_PK: "GET_JOB_BY_PK" });
  delete require.cache[helpersModuleId];
  return require(helpersModuleId);
};

afterEach(() => {
  mock.stopAll();
  delete require.cache[helpersModuleId];
});

describe("server/rr/rr-job-helpers", () => {
  it("builds a single early-RO labor row from aggregated job labor", () => {
    const { buildMinimalRolaborFromJob } = loadHelpers();

    const rolabor = buildMinimalRolaborFromJob(
      {
        tax_lbr_rt: 13,
        joblines: [
          { mod_lbr_ty: "LAB", mod_lb_hrs: 2, lbr_amt: 200 },
          { mod_lbr_ty: "LAD", mod_lb_hrs: 1.5, lbr_amt: 180 }
        ]
      },
      { opCode: "51DOZ" }
    );

    expect(rolabor).toEqual({
      ops: [
        {
          opCode: "51DOZ",
          jobNo: "1",
          custPayTypeFlag: "C",
          custTxblNtxblFlag: "T",
          bill: {
            payType: "Cust",
            jobTotalHrs: "3.5",
            billTime: "3.5",
            billRate: "108.57"
          },
          amount: {
            payType: "Cust",
            amtType: "Job",
            custPrice: "380.00",
            totalAmt: "380.00"
          }
        }
      ]
    });
  });

  it("populates labor bill fields from allocation hours on the full RR payload", () => {
    const { buildRRRepairOrderPayload } = loadHelpers();

    const payload = buildRRRepairOrderPayload({
      job: {
        id: "job-1",
        ro_number: "RO-123",
        v_vin: "1HGBH41JXMN109186"
      },
      selectedCustomer: { customerNo: "1134485" },
      advisorNo: "70754",
      allocations: [
        {
          center: "Body Labor",
          partsSale: { amount: 0, precision: 2 },
          laborTaxableSale: { amount: 24000, precision: 2 },
          laborNonTaxableSale: { amount: 0, precision: 2 },
          extrasSale: { amount: 0, precision: 2 },
          totalSale: { amount: 24000, precision: 2 },
          cost: { amount: 12000, precision: 2 },
          laborTaxableHours: 2,
          laborNonTaxableHours: 0,
          profitCenter: {
            rr_gogcode: "BL",
            rr_item_type: "G",
            accountdesc: "BODY LABOR"
          }
        }
      ],
      opCode: "51DOZ"
    });

    expect(payload.rolabor).toEqual({
      ops: [
        {
          opCode: "51DOZ",
          jobNo: "1",
          custPayTypeFlag: "C",
          custTxblNtxblFlag: "T",
          bill: {
            payType: "Cust",
            jobTotalHrs: "2",
            billTime: "2",
            billRate: "120.00"
          },
          amount: {
            payType: "Cust",
            amtType: "Job",
            custPrice: "240.00",
            totalAmt: "240.00"
          }
        }
      ]
    });
  });

  it("mirrors parts assigned to a labor-side RR profit center into ROLABOR", () => {
    const { buildRRRepairOrderPayload } = loadHelpers();

    const payload = buildRRRepairOrderPayload({
      job: {
        id: "job-2",
        ro_number: "RO-456",
        v_vin: "3GCUKHEL3TG292014"
      },
      selectedCustomer: { customerNo: "411588" },
      advisorNo: "70754",
      allocations: [
        {
          center: "Customer Pay CV Labor",
          partsSale: { amount: 15000, precision: 2 },
          partsTaxableSale: { amount: 0, precision: 2 },
          partsNonTaxableSale: { amount: 15000, precision: 2 },
          laborTaxableSale: { amount: 0, precision: 2 },
          laborNonTaxableSale: { amount: 0, precision: 2 },
          extrasSale: { amount: 0, precision: 2 },
          extrasTaxableSale: { amount: 0, precision: 2 },
          extrasNonTaxableSale: { amount: 0, precision: 2 },
          totalSale: { amount: 15000, precision: 2 },
          cost: { amount: 0, precision: 2 },
          profitCenter: {
            rr_gogcode: "VL",
            rr_item_type: "P",
            accountdesc: "Customer Pay CV Labor"
          }
        }
      ],
      opCode: "30CVZBDY"
    });

    expect(payload.rogg.ops[0]).toMatchObject({
      opCode: "30CVZBDY",
      jobNo: "1",
      segmentKind: "partsNonTaxable",
      rolaborRequired: true,
      lines: [
        {
          breakOut: "VL",
          itemType: "P",
          itemDesc: "Customer Pay CV Labor",
          custTxblNtxblFlag: "N",
          amount: {
            custPrice: "150.00",
            dlrCost: "0.00"
          }
        }
      ]
    });

    expect(payload.rolabor).toEqual({
      ops: [
        {
          opCode: "30CVZBDY",
          jobNo: "1",
          custPayTypeFlag: "C",
          custTxblNtxblFlag: "N",
          bill: {
            payType: "Cust",
            jobTotalHrs: "0",
            billTime: "0",
            billRate: "0"
          },
          amount: {
            payType: "Cust",
            amtType: "Job",
            custPrice: "150.00",
            totalAmt: "150.00"
          }
        }
      ]
    });
  });

  it("mirrors regular ROGOG parts into ROLABOR so Reynolds can find the JobNo", () => {
    const { buildRRRepairOrderPayload } = loadHelpers();

    const payload = buildRRRepairOrderPayload({
      job: {
        id: "job-3",
        ro_number: "CDK10131",
        v_vin: "3TMLU4EN1AM044343"
      },
      selectedCustomer: { customerNo: "69158" },
      advisorNo: "6224",
      allocations: [
        {
          center: "B/S PARTS",
          partsSale: { amount: 15000, precision: 2 },
          partsTaxableSale: { amount: 15000, precision: 2 },
          partsNonTaxableSale: { amount: 0, precision: 2 },
          laborTaxableSale: { amount: 0, precision: 2 },
          laborNonTaxableSale: { amount: 0, precision: 2 },
          extrasSale: { amount: 0, precision: 2 },
          extrasTaxableSale: { amount: 0, precision: 2 },
          extrasNonTaxableSale: { amount: 0, precision: 2 },
          totalSale: { amount: 15000, precision: 2 },
          cost: { amount: 0, precision: 2 },
          profitCenter: {
            rr_gogcode: "FR",
            rr_item_type: "G",
            accountdesc: "B/S PARTS"
          }
        }
      ],
      opCode: "60GMZ"
    });

    expect(payload.rogg.ops[0]).toMatchObject({
      opCode: "60GMZ",
      jobNo: "1",
      segmentKind: "partsTaxable",
      rolaborRequired: false
    });

    expect(payload.rolabor).toEqual({
      ops: [
        {
          opCode: "60GMZ",
          jobNo: "1",
          custPayTypeFlag: "C",
          custTxblNtxblFlag: "T",
          bill: {
            payType: "Cust",
            jobTotalHrs: "0",
            billTime: "0",
            billRate: "0"
          },
          amount: {
            payType: "Cust",
            amtType: "Job",
            custPrice: "150.00",
            totalAmt: "150.00"
          }
        }
      ]
    });
  });
});
