import React from "react";
import { render, screen, waitFor, fireEvent } from "@testing-library/react";
import "@testing-library/jest-dom";
import { jest } from "@jest/globals";

const mockPostApi = jest.fn();
const mockTogglePopup = jest.fn();
const mockCommonTable = jest.fn(() => <div data-testid="common-table" />);

jest.unstable_mockModule("../services/apiService.js", () => ({
  __esModule: true,
  default: () => ({
    postApi: mockPostApi,
  }),
}));

jest.unstable_mockModule("../constants/apiEndPoints.js", () => ({
  getRunningApplicationDetails: "/api/running-apps",
}));

jest.unstable_mockModule("@mui/material", () => ({
  Button: ({ children }) => <button type="button">{children}</button>,
}));

jest.unstable_mockModule("@mui/icons-material", () => ({
  Close: ({ onClick }) => (
    <button data-testid="close-icon" type="button" onClick={onClick}>
      x
    </button>
  ),
}));

jest.unstable_mockModule("./CommonTable.js", () => ({
  __esModule: true,
  default: (props) => mockCommonTable(props),
}));

jest.unstable_mockModule("./Loader.js", () => ({
  __esModule: true,
  default: () => <div data-testid="loader" />,
}));

const TableDataPopup = (await import("./TableDataPopup.js")).default;

const defaultProps = {
  empId: "EMP-1",
  applicationName: "teams",
  togglePopup: mockTogglePopup,
  summaryFilter: {
    CallDate: { startDate: "2024-01-01", endDate: "2024-01-31" },
    ResultsFor: "User",
  },
  searchText: "query",
  selectedRange: { startDate: "2024-02-01", endDate: "2024-02-28" },
};

describe("TableDataPopup Component", () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it("renders application name and calls API on mount", async () => {
    const apiResponse = [{ description: "App usage" }];
    mockPostApi.mockResolvedValue(apiResponse);

    render(<TableDataPopup {...defaultProps} />);

    expect(screen.getByText("teams")).toBeInTheDocument();

    await waitFor(() => {
      expect(mockPostApi).toHaveBeenCalledWith(
        "/api/running-apps",
        expect.objectContaining({
          SearchText: "query",
          Filter: expect.objectContaining({
            EmpCode: "EMP-1",
            ApplicationName: "teams",
            StartedOn: "2024-01-01",
            EndedOn: "2024-01-31",
            ResultsFor: "User",
          }),
        })
      );
    });

    await waitFor(() => {
      const lastCall = mockCommonTable.mock.calls[mockCommonTable.mock.calls.length - 1];
      expect(lastCall[0].data).toEqual(apiResponse);
    });
  });

  it("invokes togglePopup when close icon is clicked", () => {
    mockPostApi.mockResolvedValue([]);

    render(<TableDataPopup {...defaultProps} />);

    fireEvent.click(screen.getByTestId("close-icon"));

    expect(mockTogglePopup).toHaveBeenCalledTimes(1);
  });

  it("shows loader while request is pending", async () => {
    let resolveRequest;
    const pendingPromise = new Promise((resolve) => {
      resolveRequest = resolve;
    });
    mockPostApi.mockReturnValue(pendingPromise);

    render(<TableDataPopup {...defaultProps} />);

    expect(screen.getByTestId("loader")).toBeInTheDocument();

    resolveRequest([]);

    await waitFor(() => {
      expect(screen.queryByTestId("loader")).not.toBeInTheDocument();
    });
  });
});
