import { runSaga } from "redux-saga";
import * as api from "../../request/applicantRequest";
import * as redux from "react-redux";
import * as helper from "../../util/helpers/rejectErrorCodeHelper";
import { applyForAd, applyForAdError } from "../../store/actions/applyForAd/applyForAdActions";
import { applyForAdSaga } from "../../store/saga/applicantsSaga";

describe("applicants tests saga tests", () => {
  let spyOnUseSelector;
  let spyOnUseDispatch;
  let mockDispatch;

  beforeEach(() => {
    // Mock useSelector hook
    spyOnUseSelector = jest.spyOn(redux, "useSelector");
    spyOnUseSelector.mockReturnValueOnce("anything");

    // Mock useDispatch hook
    spyOnUseDispatch = jest.spyOn(redux, "useDispatch");

    // Mock dispatch function returned from useDispatch
    mockDispatch = jest.fn();
    spyOnUseDispatch.mockReturnValue(mockDispatch);
  });

  afterEach(() => {
    jest.restoreAllMocks();
  });

  it("Should handle applyForAdSaga saga with actions", async () => {
    const dispatchedActions = [];

    const mockedCall = { data: "Data" };
    api.applyForAdRequest = jest.fn(() => Promise.resolve(mockedCall));

    const fakeStore = {
      getState: () => mockState.users,
      dispatch: (action) => dispatchedActions.push(action),
    };

    const mockfn = jest.fn()

    await runSaga(fakeStore, applyForAdSaga, {
        payload: {
          adId: "",
          firstName: "",
          lastName: "",
          gender: "",
          dateOfBirth: "",
          phoneNumber: "",
          professionalQualification: "",
          technologiesIds: "",
          experience: "",
          linkedinLink: "",
          githubLink: "",
          bitBucketLink: "",
          email: "",
          coverLetter: "",
          pdfFile: "",
          handleApiResponseSuccess: mockfn
        },
      }).done;
      expect(api.applyForAdRequest.mock.calls.length).toBe(1);
      expect(dispatchedActions).toContainEqual(applyForAd(mockedCall.data));
      expect(mockfn).toHaveBeenCalled();
    });

  it("Should handle apply for ad saga with errors", async () => {
    const dispatchedActions = [];

    helper.rejectErrorCodeHelper = jest.fn(() => "Error");

    const mockedCall = { response: { data: { message: "Error" } } };
    api.applyForAdRequest = jest.fn(() => Promise.reject(mockedCall));

    const fakeStore = {
      getState: () => mockState.users,
      dispatch: (action) => dispatchedActions.push(action),
    };

    await runSaga(fakeStore, applyForAdSaga, {
      payload: {
        adId: "",
        firstName: "",
        lastName: "",
        gender: "",
        dateOfBirth: "",
        phoneNumber: "",
        professionalQualification: "",
        technologiesIds: "",
        experience: "",
        linkedinLink: "",
        githubLink: "",
        bitBucketLink: "",
        email: "",
        coverLetter: "",
        pdfFile: "",
      },
    }).done;
    expect(api.applyForAdRequest.mock.calls.length).toBe(1);
    expect(dispatchedActions).toContainEqual(applyForAdError("Error"));
  });
});
