import * as redux from "react-redux";
import store from "../../store";
import { Router } from "react-router-dom";
import history from "../../store/utils/history";
import { mockState } from "../../mockState";
import * as api from "../../request/registerRequest";
import { render } from "@testing-library/react";
import UserDetails from "../../pages/UsersPage/UserDetails";
import ColorModeProvider from "../../context/ColorModeContext";
import { USER_DETAILS_REQ } from "../../store/actions/users/usersActionConstants";
import {
  registerError,
  registerSuccess,
} from "../../store/actions/register/registerActions";
import { runSaga } from "redux-saga";
import { userDetails } from "../../store/saga/usersSaga";
import { registerUser } from "../../store/saga/registerSaga";
import * as helper from "../../util/helpers/rejectErrorCodeHelper";

describe("UserDetails reducer tests", () => {
  let spyOnUseSelector;
  let spyOnUseDispatch;
  let mockDispatch;

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

    // 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 run register saga function with actions", async () => {
    const dispatchedActions = [];

    api.register = jest.fn(() => Promise.resolve());

    const fakeStore = {
      getState: () => ({
        isSuccess: false,
        errorMessage: "",
      }),
      dispatch: (action) => dispatchedActions.push(action),
    };

    await runSaga(fakeStore, registerUser, {
      payload: {
        model: {
          password: "",
          email: "",
          confirm: "",
          position: "",
          linkedIn: "",
          phone: "",
          token: "",
        },
      },
    }).done;

    expect(api.register.mock.calls.length).toBe(1);
    expect(dispatchedActions).toContainEqual(registerSuccess());
  });

  it("should call handleApiResponseSuccess", async () => {
    const dispatchedActions = [];

    api.register = jest.fn(() => Promise.resolve());

    const fakeStore = {
      getState: () => ({
        isSuccess: false,
        errorMessage: "",
      }),
      dispatch: (action) => dispatchedActions.push(action),
    };

    const mockFn = jest.fn()

    await runSaga(fakeStore, registerUser, {
      payload: {
        model: {
          password: "",
          email: "",
          confirm: "",
          position: "",
          linkedIn: "",
          phone: "",
          token: "",
        },
        handleApiResponseSuccess: mockFn
      },
    }).done;

    expect(mockFn).toHaveBeenCalled();
  });

  it("should handle register error", async () => {
    const dispatchedActions = [];

    const error = { response: { data: { message: "Error" } } };
    helper.rejectErrorCodeHelper = jest.fn(() => "Error")
    api.register = jest.fn(() => Promise.reject(error));

    const fakeStore = {
      getState: () => ({
        isSuccess: false,
        errorMessage: "",
      }),
      dispatch: (action) => dispatchedActions.push(action),
    };

    await runSaga(fakeStore, registerUser, {
      payload: {
        password: "",
        email: "",
        confirm: "",
        position: "",
        linkedIn: "",
        phone: "",
        token: "",
      },
    }).done;

    expect(api.register.mock.calls.length).toBe(1);
    expect(dispatchedActions).toContainEqual(registerError("Error"));
  });
});
