import { Router } from "react-router-dom";

import { parseTheme } from "@ax/helpers";
import Sites, { type ISitesProps } from "@ax/modules/Sites";
import { history } from "@ax/routes";
import globalTheme from "@ax/themes/theme.json";

import axios from "axios";
import { mock } from "jest-mock-extended";
import configureStore from "redux-mock-store";
import thunk from "redux-thunk";
import { ThemeProvider } from "styled-components";

import { act, cleanup, render, screen } from "../../../../config/jest/test-utils";
import { structuredDataResponse } from "./../../../__mocks__/axios/SitesList";
import { sitesDataMock, userDataMock } from "./../../../__mocks__/store/SitesList";

afterEach(cleanup);
jest.mock("axios");
const mockedAxios = axios as jest.MockedFunction<typeof axios>;

const mockStore = configureStore([thunk]);
const defaultProps = mock<ISitesProps>();

const baseStore = {
	app: {
		isLoading: false,
		globalLangs: [
			{ id: 4, locale: "en_GB", language: "English", label: "EN", isDefault: true },
			{ id: 2, locale: "es_ES", language: "Spanish", label: "ES", isDefault: false },
		],
		token: "eyJhbGciOiJIUzI",
	},
	users: userDataMock,
	sites: sitesDataMock,
	structuredData: { global: [], sites: [] },
};

const renderSites = async (storeData = baseStore) => {
	const store = mockStore(storeData);
	await act(async () => {
		render(
			<Router history={history}>
				<ThemeProvider theme={parseTheme(globalTheme)}>
					<Sites {...{ ...storeData, ...defaultProps }} />
				</ThemeProvider>
			</Router>,
			{ store },
		);
	});
};

beforeEach(() => {
	mockedAxios.mockResolvedValue(structuredDataResponse);
});

describe("Sites module rendering", () => {
	it("should render loading component when is loading", async () => {
		await renderSites({
			...baseStore,
			app: { ...baseStore.app, isLoading: true },
			sites: { totalItems: 0, sites: [], recentSites: [], config: sitesDataMock.config },
		});

		expect(screen.getByTestId("loading-wrapper")).toBeTruthy();
	});

	it("should render recent sites list when there are recent sites", async () => {
		await renderSites();

		expect(screen.getByTestId("recent-sites-list")).toBeTruthy();
		expect(screen.getByTestId("recent-sites-header")).toBeTruthy();
		expect(screen.getByTestId("recent-sites-title")).toBeTruthy();
		expect(screen.getByTestId("recent-sites-items-wrapper")).toBeTruthy();
		expect(screen.getByTestId("recent-sites-collapse-button")).toBeTruthy();
		expect(screen.getByTestId("recent-sites-hide-label")).toBeTruthy();
	});

	it("should render default sites list view", async () => {
		await renderSites();

		expect(screen.getByTestId("all-sites-header")).toBeTruthy();
		expect(screen.getByTestId("all-sites-title")).toBeTruthy();
		expect(screen.getByTestId("all-sites-header-icons")).toBeTruthy();
		expect(screen.getByTestId("all-sites-grid-filter")).toBeTruthy();
		expect(screen.getByTestId("all-sites-grid-filter-label")).toBeTruthy();
		expect(screen.getByTestId("sites-grid-list")).toBeTruthy();
	});

	it("should not render recent sites list when recent sites list is empty", async () => {
		await renderSites({
			...baseStore,
			sites: { totalItems: 2, sites: sitesDataMock.sites, recentSites: [], config: sitesDataMock.config },
		});

		expect(screen.queryByTestId("recent-sites-list")).not.toBeTruthy();
	});

	it("should render empty state when no sites", async () => {
		await renderSites({
			...baseStore,
			sites: { totalItems: 0, sites: [], recentSites: [], config: sitesDataMock.config },
		});

		expect(screen.getByTestId("empty-state")).toBeTruthy();
	});
});
