import * as redux from "react-redux";
import store from "../../store";
import { Router } from "react-router-dom";
import { mockState } from "../../mockState";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import history from "../../store/utils/history";
import LoginPage from "../../pages/LoginPage/LoginPageMUI";

describe("LoginPage render tests", () => {
  var props = {
    history: {
      replace: jest.fn(),
      push: jest.fn(),
      location: {
        pathname: "/",
      },
    },
  };

  const cont = (
    <redux.Provider store={store}>
      <Router history={history}>
        <LoginPage {...props} />
      </Router>
    </redux.Provider>
  );

  let spyOnUseSelector;
  let spyOnUseDispatch;
  let mockDispatch;

  beforeEach(() => {
    spyOnUseSelector = jest.spyOn(redux, "useSelector");
    spyOnUseSelector.mockReturnValue("some error");

    spyOnUseDispatch = jest.spyOn(redux, "useDispatch");
    mockDispatch = jest.fn();
    spyOnUseDispatch.mockReturnValue(mockDispatch);
  });

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

  it("Should render", () => {
    const { container } = render(cont);
    expect(
      container.getElementsByClassName("c-login-container")[0]
    ).toBeDefined();
  });

  it("Should render login-logo", () => {
    const { container } = render(cont);
    expect(container.getElementsByClassName("login-logo")[0]).toBeDefined();
  });

  it("Should render welcome message", () => {
    const { container } = render(cont);
    expect(
      container
        .getElementsByClassName("c-login-container")[0]
        .querySelector("h")
    ).toBeDefined();
  });

  it("Should render error message because we mocked error message", () => {
    render(cont);
    expect(screen.getByTestId("error-message")).toBeDefined();
  });

  it("Should render username input", () => {
    render(cont);
    expect(screen.getByTestId("username-input")).toBeDefined();
  });

  it("Should render password input", () => {
    render(cont);
    expect(screen.getByTestId("password-input")).toBeDefined();
  });

  it("Should render forgot paswword link", () => {
    const { container } = render(cont);
    expect(container.getElementsByClassName("text-end")[0]).toBeDefined();
  });

  it("Should render submit button", () => {
    const { container } = render(cont);
    expect(container.getElementsByClassName("c-btn")[0]).toBeDefined();
  });

  it("Should render separator container", () => {
    render(cont);
    expect(screen.getByTestId("separator")).toBeDefined();
  });

  it("Should dilig logo", () => {
    render(cont);
    expect(screen.getByTestId("dilig-logo")).toBeDefined();
  });

  it("Should not dispatch functions after clicking submit button because username and password inputs are emtpy", async () => {
    const { container } = render(cont);
    fireEvent.click(container.getElementsByClassName("c-btn")[0]);
    await waitFor(() => expect(mockDispatch).toBeCalledTimes(0));
  });

  it("Should not dispatch functions after clicking submit button because password input is emtpy", async () => {
    const { container } = render(cont);
    fireEvent.change(screen.getByTestId("username-input"), {
      target: { value: "some username" },
    });
    fireEvent.click(container.getElementsByClassName("c-btn")[0]);
    await waitFor(() => expect(mockDispatch).toBeCalledTimes(0));
  });

  it("Should not dispatch functions after clicking submit button because username input is emtpy", async () => {
    const { container } = render(cont);
    fireEvent.change(screen.getByTestId("password-input"), {
      target: { value: "some password" },
    });
    fireEvent.click(container.getElementsByClassName("c-btn")[0]);
    await waitFor(() => expect(mockDispatch).toBeCalledTimes(0));
  });

  it("Should dispatch two functions after clicking submit button", async () => {
    const { container } = render(cont);
    fireEvent.change(screen.getByTestId("username-input"), {
      target: { value: "some username" },
    });
    fireEvent.change(screen.getByTestId("password-input"), {
      target: { value: "some password" },
    });
    fireEvent.click(container.getElementsByClassName("c-btn")[0]);
    await waitFor(() => expect(mockDispatch).toBeCalledTimes(2));
  });

//   it("After clicking submit button we should go to ads page", async () => {
//     const { container } = render(cont);
//     fireEvent.change(screen.getByTestId("username-input"), {
//       target: { value: "some username" },
//     });
//     fireEvent.change(screen.getByTestId("password-input"), {
//       target: { value: "some password" },
//     });
//     fireEvent.click(container.getElementsByClassName("c-btn")[0]);
//     const arg = { pathname: "/ads" };
//     expect(props.history.push).toHaveBeenCalledWith(arg);
//   });
});
