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

describe("AdsPage render tests", () => {
  var props = {
    history: {
      replace: jest.fn(),

      push: jest.fn(),

      location: {
        pathname: "/ads",
      },
    },
  };

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

  let spyOnUseSelector;

  beforeEach(() => {
    spyOnUseSelector = jest.spyOn(redux, "useSelector");
    spyOnUseSelector
      .mockReturnValueOnce(mockState.ads.ads)
      .mockReturnValueOnce([
        {
          name: ".NET",
          technologyId: 1,
          technologyType: "Backend",
          isChecked: false,
        },
      ])
  });

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

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

  it("Should be rendered button which is used for showing input responsible for searching by name", () => {
    const { container } = render(cont);
    expect(container.getElementsByClassName("ads-page-btn")[0]).toBeDefined();
  });

  it("Should be rendered button for toggling filters modal", () => {
    const { container } = render(cont);
    expect(container.getElementsByClassName("ads-page-btn")[1]).toBeDefined();
  });

  it("Should be rendered button for adding new ad", () => {
    const { container } = render(cont);
    expect(container.getElementsByClassName("ads-page-btn")[2]).toBeDefined();
  });

  it("Should render CreateAdPage when click Add Ad button", () => {
    const { container } = render(cont);
    fireEvent.click(container.getElementsByClassName("ads-page-btn")[2]);

    expect(props.history.push).toHaveBeenCalledWith("/create-ad");
  });

  it("Input for searching by title should not be shown when component is initialy rendered", () => {
    const { container } = render(cont);
    expect(
      container.getElementsByClassName("ads-page-search-by-title")[0].style
        .visibility
    ).toBe("hidden");
  });

  it("Should be rendered ad cards", () => {
    const { container } = render(cont);
    expect(container.getElementsByClassName("ad-card").length).toBeGreaterThan(
      0
    );
  });

  it("Should be rendered archive ad cards", () => {
    const { container } = render(cont);
    expect(container.getElementsByClassName("archive-ad").length).toBe(0);
  });

  it("Should render filter drawer after click filter button", () => {
    const { container } = render(cont);

    fireEvent.click(container.getElementsByClassName("fltr-btn")[0]);
    expect(screen.getByTestId("ad-filters-drawer")).toBeDefined();
  });

  it("Should render arrow buttons for active ads slider", () => {
    const { container } = render(cont);
    expect(
      container.getElementsByClassName("active-ads-ads-arrows")
    ).toBeDefined();
  });

  it("Should render arrow buttons for archived ads slider", () => {
    const { container } = render(cont);
    expect(
      container.getElementsByClassName("archived-ads-ads-arrows")
    ).toBeDefined();
  });

  it("Should filter ads when click search button", async () => {
    const { container } = render(cont);

    waitFor(() => {
      fireEvent.click(container.getElementsByClassName("fltr-btn")[0]);

      fireEvent.click(
        container.getElementsByClassName("ad-filters-checkbox")[0]
      );

      fireEvent.click(container.getByTestId("ad-filters-submit")[0]);

      expect(
        container.getElementsByClassName("ad-card").length
      ).toBeGreaterThan(0);
    });
  });

  it("Should render Ads", async () => {
    const { container } = render(cont);
    waitFor(() =>
      expect(
        container.getElementsByClassName("ad-card").length
      ).toBeGreaterThan(0)
    );
  });

  it("Should navigate to ad details when click on ad card", async () => {
    const { container } = render(cont);
    fireEvent.click(container.getElementsByClassName("ad-card")[0]);

    expect(props.history.push).toHaveBeenCalledWith("/ads/1");
  });
});
