import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import axios from "axios";
import { describe, expect, it, beforeEach, vi } from "vitest";
import { PayrollLaborAllocationsTable } from "./labor-allocations-table.payroll.component.jsx";

const notification = {
  success: vi.fn(),
  error: vi.fn()
};

vi.mock("axios", () => ({
  default: {
    post: vi.fn()
  }
}));

vi.mock("react-i18next", () => ({
  useTranslation: () => ({
    t: (key, values = {}) => {
      const translations = {
        "jobs.labels.laborallocations": "Labor Allocations",
        "timetickets.actions.payall": "Pay All",
        "general.labels.totals": "Totals",
        "jobs.labels.outstandinghours": "Outstanding hours remain."
      };

      if (key === "timetickets.successes.payall") {
        return "All hours paid out successfully.";
      }

      if (key === "timetickets.errors.payall") {
        return `Error flagging hours. ${values.error || ""}`.trim();
      }

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

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

vi.mock("../responsive-table/responsive-table.component", () => {
  function ResponsiveTable({ dataSource = [], summary }) {
    return (
      <div data-testid="responsive-table">
        <div>{`rows:${dataSource.length}`}</div>
        {summary ? <div>{summary()}</div> : null}
      </div>
    );
  }

  ResponsiveTable.Summary = {
    Row: ({ children }) => <div>{children}</div>,
    Cell: ({ children }) => <div>{children}</div>
  };

  return {
    default: ResponsiveTable
  };
});

vi.mock("../feature-wrapper/feature-wrapper.component", () => ({
  HasFeatureAccess: () => true
}));

vi.mock("../upsell/upsell.component", () => ({
  default: () => <div>Upsell</div>,
  upsellEnum: () => ({
    timetickets: {
      allocations: "allocations"
    }
  })
}));

vi.mock("../lock-wrapper/lock-wrapper.component", () => ({
  default: ({ children }) => children
}));

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

  it("shows a success notification after Pay All completes", async () => {
    axios.post
      .mockResolvedValueOnce({
        data: [
          {
            employeeid: "emp-1",
            mod_lbr_ty: "LAA",
            expectedHours: 4,
            claimedHours: 1
          }
        ]
      })
      .mockResolvedValueOnce({
        status: 200,
        data: [{ id: "ticket-1" }]
      });

    const refetch = vi.fn();

    render(
      <PayrollLaborAllocationsTable
        jobId="job-1"
        joblines={[{ id: "line-1", convertedtolbr: false }]}
        timetickets={[]}
        bodyshop={{
          features: {
            timetickets: true
          },
          employees: [{ id: "emp-1", first_name: "Avery", last_name: "Johnson" }]
        }}
        adjustments={[]}
        refetch={refetch}
      />
    );

    await waitFor(() => {
      expect(axios.post).toHaveBeenNthCalledWith(1, "/payroll/calculatelabor", {
        jobid: "job-1"
      });
    });

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

    await waitFor(() => {
      expect(axios.post).toHaveBeenNthCalledWith(2, "/payroll/payall", {
        jobid: "job-1"
      });
    });

    expect(notification.success).toHaveBeenCalledWith({
      title: "All hours paid out successfully."
    });
    expect(refetch).toHaveBeenCalled();
  });

  it("shows the returned pay-all error message when payroll rejects the request", async () => {
    axios.post
      .mockResolvedValueOnce({
        data: [
          {
            employeeid: "emp-1",
            mod_lbr_ty: "LAA",
            expectedHours: 4,
            claimedHours: 1
          }
        ]
      })
      .mockResolvedValueOnce({
        status: 200,
        data: {
          success: false,
          error: "Not all hours have been assigned."
        }
      });

    render(
      <PayrollLaborAllocationsTable
        jobId="job-1"
        joblines={[{ id: "line-1", convertedtolbr: false }]}
        timetickets={[]}
        bodyshop={{
          features: {
            timetickets: true
          },
          employees: [{ id: "emp-1", first_name: "Avery", last_name: "Johnson" }]
        }}
        adjustments={[]}
      />
    );

    await waitFor(() => {
      expect(axios.post).toHaveBeenNthCalledWith(1, "/payroll/calculatelabor", {
        jobid: "job-1"
      });
    });

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

    await waitFor(() => {
      expect(notification.error).toHaveBeenCalledWith({
        title: "Error flagging hours. Not all hours have been assigned."
      });
    });
  });
});
