import React from "react";
import axios from "axios";
import "@testing-library/jest-dom";
import AsyncSelect, { IAsyncSelectProps } from "@ax/components/Fields/AsyncSelect";
import { ThemeProvider } from "styled-components";
import { parseTheme } from "@ax/helpers";
import globalTheme from "@ax/themes/theme.json";
import { render, screen, cleanup, act } from "@testing-library/react";
import { ISite } from "@ax/types";
import { mock } from "jest-mock-extended";

afterEach(cleanup);

const defaultProps = mock<IAsyncSelectProps>();

const defaultSite = mock<ISite>();
defaultSite.id = 113;

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

describe("AsyncSelect component rendering", () => {
	test("should render the component AsyncSelect", async () => {
		defaultProps.name = "texto de prueba";
		await act(async () => {
			render(
				<ThemeProvider theme={parseTheme(globalTheme)}>
					<AsyncSelect {...defaultProps} />
				</ThemeProvider>,
			);
		});
		expect(screen.getByTestId("asyncSelect")).toBeTruthy();
	});
});

describe("AsyncSelect component events", () => {
	test("should call the api and receive data in pages", async () => {
		defaultProps.site = defaultSite;
		defaultProps.entity = "pages";
		defaultProps.options = {
			excludeDetailPages: true,
		};
		defaultProps.lang = "en_GB";
		defaultProps.selectedContent = { id: 1 };
		defaultProps.value = [3622, 3621];

		const data = {
			data: [
				{
					value: 3622,
					label: "Home",
				},
				{
					value: 3731,
					label: "English child",
				},
				{
					value: 3730,
					label: "English Parent",
				},
				{
					value: 3787,
					label: "English test",
				},
				{
					value: 3745,
					label: "New Page",
				},
				{
					value: 3784,
					label: "Prueba",
				},
			],
			status: 200,
			statusText: "Ok",
			headers: {},
			config: {},
		};

		mockedAxios.mockResolvedValue(data);

		await act(async () => {
			render(
				<ThemeProvider theme={parseTheme(globalTheme)}>
					<AsyncSelect {...defaultProps} />
				</ThemeProvider>,
			);
		});

		expect(screen.getByTestId("asyncSelect")).toHaveTextContent("Home");
	});

	test("should call the api and receive data in pages with no selectedContent", async () => {
		defaultProps.site = defaultSite;
		defaultProps.entity = "pages";
		defaultProps.options = {
			excludeDetailPages: true,
		};
		defaultProps.lang = "en_GB";
		defaultProps.selectedContent = null;
		defaultProps.value = 3622;

		const data = {
			data: [
				{
					value: 3622,
					label: "Home",
				},
				{
					value: 3731,
					label: "English child",
				},
				{
					value: 3730,
					label: "English Parent",
				},
				{
					value: 3787,
					label: "English test",
				},
				{
					value: 3745,
					label: "New Page",
				},
				{
					value: 3784,
					label: "Prueba",
				},
			],
			status: 200,
			statusText: "Ok",
			headers: {},
			config: {},
		};

		mockedAxios.mockResolvedValue(data);

		await act(async () => {
			render(
				<ThemeProvider theme={parseTheme(globalTheme)}>
					<AsyncSelect {...defaultProps} />
				</ThemeProvider>,
			);
		});

		expect(screen.getByTestId("asyncSelect")).toHaveTextContent("Home");
	});

	test("should call the api and receive data in categories", async () => {
		defaultProps.site = defaultSite;
		defaultProps.entity = "categories";
		defaultProps.options = {
			excludeDetailPages: true,
		};
		defaultProps.lang = "en_GB";
		defaultProps.value = 3622;

		const data = {
			data: [
				{
					value: 3622,
					label: "Home",
				},
				{
					value: 3731,
					label: "English child",
				},
				{
					value: 3730,
					label: "English Parent",
				},
				{
					value: 3787,
					label: "English test",
				},
				{
					value: 3745,
					label: "New Page",
				},
				{
					value: 3784,
					label: "Prueba",
				},
			],
			status: 200,
			statusText: "Ok",
			headers: {},
			config: {},
		};

		mockedAxios.mockResolvedValue(data);

		await act(async () => {
			render(
				<ThemeProvider theme={parseTheme(globalTheme)}>
					<AsyncSelect {...defaultProps} />
				</ThemeProvider>,
			);
		});

		expect(screen.getByTestId("asyncSelect")).toHaveTextContent("Home");
	});

	test("should call the api and not receiving data", async () => {
		defaultProps.site = defaultSite;
		defaultProps.entity = "categories";
		defaultProps.options = {
			excludeDetailPages: true,
		};
		defaultProps.lang = "en_GB";

		const data = {
			data: [],
			status: 500,
			statusText: "Ok",
			headers: {},
			config: {},
		};

		mockedAxios.mockResolvedValue(data);

		await act(async () => {
			render(
				<ThemeProvider theme={parseTheme(globalTheme)}>
					<AsyncSelect {...defaultProps} />
				</ThemeProvider>,
			);
		});

		expect(screen.getByTestId("asyncSelect")).not.toHaveTextContent("Home");
	});

	test("should call the api with source", async () => {
		defaultProps.site = defaultSite;
		defaultProps.entity = "categories";
		defaultProps.source = "source";
		defaultProps.options = {
			excludeDetailPages: true,
		};
		defaultProps.lang = "en_GB";
		defaultProps.value = 3787;

		const data = {
			data: [
				{
					value: 3622,
					title: "Home",
				},
				{
					value: 3731,
					title: "English child",
				},
				{
					value: 3730,
					title: "English Parent",
				},
				{
					value: 3787,
					title: "English test",
				},
				{
					value: 3745,
					title: "New Page",
				},
				{
					value: 3784,
					title: "Prueba",
				},
			],
			status: 200,
			statusText: "Ok",
			headers: {},
			config: {},
		};

		mockedAxios.mockResolvedValue(data);

		await act(async () => {
			render(
				<ThemeProvider theme={parseTheme(globalTheme)}>
					<AsyncSelect {...defaultProps} />
				</ThemeProvider>,
			);
		});

		expect(screen.getByTestId("asyncSelect")).toHaveTextContent("English test");
	});
});
