import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { LaborAllocationsAdjustmentEdit } from "./labor-allocations-adjustment-edit.component.jsx";

const updateAdjustmentsMock = vi.fn();
const useMutationMock = vi.fn();
const notification = {
  success: vi.fn(),
  error: vi.fn()
};
const insertAuditTrailMock = vi.fn();
const jobmodifylbradjMock = vi.fn(() => "audit-entry");

vi.mock("@apollo/client/react", () => ({
  useMutation: (...args) => useMutationMock(...args)
}));

vi.mock("react-i18next", () => ({
  useTranslation: () => ({
    t: (key) => {
      const translations = {
        "joblines.fields.mod_lbr_ty": "Labor Type",
        "joblines.fields.lbr_types.LAA": "LAA",
        "jobs.fields.adjustmenthours": "Adjustment Hours",
        "general.actions.save": "Save",
        "jobs.successes.save": "Saved"
      };

      return translations[key] || key;
    }
  })
}));

vi.mock("../../contexts/Notifications/notificationContext.jsx", () => ({
  useNotification: () => notification
}));

vi.mock("../../utils/AuditTrailMappings", () => ({
  default: {
    jobmodifylbradj: (...args) => jobmodifylbradjMock(...args)
  }
}));

describe("LaborAllocationsAdjustmentEdit", () => {
  beforeEach(() => {
    vi.clearAllMocks();

    useMutationMock.mockImplementation((mutation) => {
      if (mutation === UPDATE_JOB) {
        return [updateAdjustmentsMock];
      }

      return [vi.fn()];
    });

    updateAdjustmentsMock.mockResolvedValue({});
  });

  it("saves merged labor adjustments and records the adjustment delta", async () => {
    render(
      <LaborAllocationsAdjustmentEdit
        insertAuditTrail={insertAuditTrailMock}
        jobId="job-1"
        mod_lbr_ty="LAA"
        adjustments={{
          LAA: 1.2,
          LAB: 0.5
        }}
        refetchQueryNames={["QUERY_JOB"]}
      >
        <button type="button">Edit Adjustment</button>
      </LaborAllocationsAdjustmentEdit>
    );

    fireEvent.click(screen.getByRole("button", { name: "Edit Adjustment" }));

    fireEvent.change(screen.getByRole("spinbutton"), {
      target: { value: "3.7" }
    });

    fireEvent.click(screen.getByRole("button", { name: "Save" }));

    await waitFor(() => {
      expect(updateAdjustmentsMock).toHaveBeenCalledWith({
        variables: {
          jobId: "job-1",
          job: {
            lbr_adjustments: {
              LAA: 3.7,
              LAB: 0.5
            }
          }
        },
        refetchQueries: ["QUERY_JOB"]
      });
    });

    expect(jobmodifylbradjMock).toHaveBeenCalledWith({
      mod_lbr_ty: "LAA",
      hours: 2.5
    });
    expect(insertAuditTrailMock).toHaveBeenCalledWith({
      jobid: "job-1",
      operation: "audit-entry",
      type: "jobmodifylbradj"
    });
    expect(notification.success).toHaveBeenCalledWith({
      title: "Saved"
    });
  });
});
