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

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

const helpersModuleId = require.resolve("./rr-job-helpers");
const lookupModuleId = require.resolve("./rr-lookup");
const loggerEventModuleId = require.resolve("./rr-logger-event");
const logXmlModuleId = require.resolve("./rr-log-xml");
const responsibilityCentersModuleId = require.resolve("./rr-responsibility-centers");
const allocationsModuleId = require.resolve("./rr-calculate-allocations");
const jobExportModuleId = require.resolve("./rr-job-export");

const makeBodyshop = (mdFunctionalityToggles) => ({
  rr_configuration: {
    defaults: {
      prefix: "51",
      base: "DOZ",
      suffix: ""
    }
  },
  ...(mdFunctionalityToggles ? { md_functionality_toggles: mdFunctionalityToggles } : {})
});

const makeJob = () => ({
  id: "job-1",
  ro_number: "RO-123",
  v_vin: "1HGBH41JXMN109186",
  joblines: [{ mod_lbr_ty: "LAB", mod_lb_hrs: 2, lbr_amt: 200 }]
});

const loadJobExport = ({
  buildMinimalRolaborFromJob = vi.fn(() => ({ ops: [{ opCode: "51DOZ" }] })),
  createRepairOrder = vi.fn(async () => ({ success: true, data: { dmsRoNo: "12345" } }))
} = {}) => {
  mock.stopAll();
  mock(helpersModuleId, {
    buildRRRepairOrderPayload: vi.fn(),
    buildMinimalRolaborFromJob
  });
  mock(lookupModuleId, {
    buildClientAndOpts: () => ({
      client: { createRepairOrder },
      opts: { envelope: { sender: {} } }
    })
  });
  mock(loggerEventModuleId, vi.fn());
  mock(logXmlModuleId, {
    withRRRequestXml: (response, payload) => payload
  });
  mock(responsibilityCentersModuleId, {
    extractRrResponsibilityCenters: vi.fn(() => [])
  });
  mock(allocationsModuleId, {
    default: vi.fn()
  });

  delete require.cache[jobExportModuleId];
  return {
    ...require(jobExportModuleId),
    buildMinimalRolaborFromJob,
    createRepairOrder
  };
};

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

describe("server/rr/rr-job-export", () => {
  it("sends early RO labor totals by default", async () => {
    const { createMinimalRRRepairOrder, createRepairOrder, buildMinimalRolaborFromJob } = loadJobExport();

    await createMinimalRRRepairOrder({
      bodyshop: makeBodyshop(),
      job: makeJob(),
      advisorNo: "70754",
      selectedCustomer: { custNo: "1134485" },
      txEnvelope: {}
    });

    expect(buildMinimalRolaborFromJob).toHaveBeenCalledWith(makeJob(), {
      opCode: "51DOZ",
      payType: "Cust"
    });
    expect(createRepairOrder.mock.calls[0][0].rolabor).toEqual({ ops: [{ opCode: "51DOZ" }] });
  });

  it("omits early RO labor totals when the shop opts out", async () => {
    const { createMinimalRRRepairOrder, createRepairOrder, buildMinimalRolaborFromJob } = loadJobExport();

    await createMinimalRRRepairOrder({
      bodyshop: makeBodyshop({ enhanced_early_ros: false }),
      job: makeJob(),
      advisorNo: "70754",
      selectedCustomer: { custNo: "1134485" },
      txEnvelope: {}
    });

    expect(buildMinimalRolaborFromJob).not.toHaveBeenCalled();
    expect(createRepairOrder.mock.calls[0][0].rolabor).toBeUndefined();
  });
});
