import React from "react";
import configureStore from "redux-mock-store";
import ArrayFieldGroup, { IProps } from "@ax/components/Fields/ArrayFieldGroup";
import { ThemeProvider } from "styled-components";
import { parseTheme } from "@ax/helpers";
import globalTheme from "@ax/themes/theme.json";
import { render, cleanup, screen, fireEvent, act } from "../../../../../config/jest/test-utils";
import { mock } from "jest-mock-extended";
import FieldsBehavior from "@ax/components/FieldsBehavior";

afterEach(cleanup);

const defaultProps = mock<IProps>();

defaultProps.selectedContent = { component: "" };

const middlewares: any = [];
const mockStore = configureStore(middlewares);

const initialStore = {};
const store = mockStore(initialStore);

describe("ArrayFieldGroup component rendering", () => {
	it("should render the component with no items and button", async () => {
		await act(async () => {
			render(
				<ThemeProvider theme={parseTheme(globalTheme)}>
					<ArrayFieldGroup {...defaultProps} />
				</ThemeProvider>,
				{ store },
			);
		});

		expect(screen.getByTestId("button-line-inverse")).toBeTruthy();
	});

	it("should render the component with ArrayFieldInline", async () => {
		defaultProps.value = [
			{
				id: "b71c3180-1cf2-4f69-8248-5fcb6e579377",
				semTitle: "dsa",
				subjects: [
					{
						id: "3ae4be00-9216-422d-a841-0448e305af08",
						subjTeachers: {
							mode: "manual",
							fixed: [4476, 4425],
						},
						subjTitle: "as",
						subjType: "das",
					},
				],
			},
		];
		const fieldProps = {
			objKey: "semTitle",
			fieldType: "TextField",
			innerFields: [],
			field: {
				title: "Title",
				type: "TextField",
				key: "semTitle",
				mandatory: "true",
				isTitle: true,
			},
			title: "Title",
			type: "TextField",
			mandatory: "true",
			isTitle: true,
			theme: "default-theme",
		};
		defaultProps.innerFields = [<FieldsBehavior {...fieldProps} key={1} />];
		defaultProps.arrayType = "inline";

		// rendering with innerFields in props
		await act(async () => {
			render(
				<ThemeProvider theme={parseTheme(globalTheme)}>
					<ArrayFieldGroup {...defaultProps} />
				</ThemeProvider>,
				{ store },
			);
		});

		expect(screen.getByTestId("button-line-inverse")).toBeTruthy();
		expect(screen.getByTestId("arrayFieldInline")).toBeTruthy();

		const fieldProps2 = {
			objKey: "semTitle",
			fieldType: "TextField",
			field: {
				title: "Title",
				type: "TextField",
				key: "semTitle",
				mandatory: "true",
				isTitle: true,
			},
			title: "Title",
			type: "TextField",
			mandatory: "true",
			isTitle: true,
			theme: "default-theme",
		};
		defaultProps.innerFields = [<FieldsBehavior {...fieldProps2} key={1} />];

		// rendering without innerFields in props
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<ArrayFieldGroup {...defaultProps} />
			</ThemeProvider>,
			{ store },
		);
	});

	it("should render the component with ArrayFieldItem", async () => {
		defaultProps.value = [
			{
				id: "b71c3180-1cf2-4f69-8248-5fcb6e579377",
				semTitle: "dsa",
				subjects: [
					{
						id: "3ae4be00-9216-422d-a841-0448e305af08",
						subjTeachers: {
							mode: "manual",
							fixed: [4476, 4425],
						},
						subjTitle: "as",
						subjType: "das",
					},
				],
			},
		];
		const fieldProps = {
			objKey: "semTitle",
			fieldType: "TextField",
			innerFields: [],
			field: {
				title: "Title",
				type: "TextField",
				key: "semTitle",
				mandatory: "true",
				isTitle: false,
			},
			title: "Title",
			type: "TextField",
			mandatory: "true",
			isTitle: false,
			theme: "default-theme",
		};

		defaultProps.innerFields = [<FieldsBehavior {...fieldProps} key={1} />];
		defaultProps.arrayType = "item";

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

		expect(screen.getByTestId("button-line-inverse")).toBeTruthy();
		expect(screen.getByTestId("arrayFieldItem")).toBeTruthy();

		const fieldProps2 = {
			objKey: "semTitle",
			fieldType: "TextField",
			field: {
				title: "A Title",
				type: "TextField",
				key: "semTitle",
				mandatory: "true",
				isTitle: true,
			},
			title: "A Title",
			type: "TextField",
			mandatory: "true",
			isTitle: true,
			theme: "default-theme",
		};
		defaultProps.innerFields = [<FieldsBehavior {...fieldProps2} key={1} />];

		// rendering with isTitle true
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<ArrayFieldGroup {...defaultProps} />
			</ThemeProvider>,
			{ store },
		);

		expect(screen.getByText("A Title")).toBeTruthy();
	});
});

describe("ArrayFieldGroup component events", () => {
	it("should call the onclick of the button", async () => {
		defaultProps.value = [
			{
				id: "b71c3180-1cf2-4f69-8248-5fcb6e579377",
				semTitle: "dsa",
				subjects: [
					{
						id: "3ae4be00-9216-422d-a841-0448e305af08",
						subjTeachers: {
							mode: "manual",
							fixed: [4476, 4425],
						},
						subjTitle: "as",
						subjType: "das",
					},
				],
			},
		];

		const onChangeMock = defaultProps.onChange as jest.MockedFunction<(value: Record<string, unknown>[]) => void>;

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

		expect(screen.getByTestId("button-line-inverse")).toBeTruthy();
		fireEvent.click(screen.getByTestId("button-line-inverse"));
		expect(onChangeMock).toHaveBeenCalled();
	});

	it("should call the handleDelete with the button", async () => {
		defaultProps.value = [
			{
				id: "b71c3180-1cf2-4f69-8248-5fcb6e579377",
				semTitle: "dsa",
				subjects: [
					{
						id: "3ae4be00-9216-422d-a841-0448e305af08",
						subjTeachers: {
							mode: "manual",
							fixed: [4476, 4425],
						},
						subjTitle: "as",
						subjType: "das",
					},
				],
			},
		];
		const fieldProps = {
			objKey: "semTitle",
			fieldType: "TextField",
			innerFields: [],
			field: {
				title: "Title",
				type: "TextField",
				key: "semTitle",
				mandatory: "true",
				isTitle: true,
			},
			title: "Title",
			type: "TextField",
			mandatory: "true",
			isTitle: true,
			theme: "default-theme",
		};
		defaultProps.innerFields = [<FieldsBehavior {...fieldProps} key={1} />];
		defaultProps.arrayType = "inline";
		const onChangeMock = defaultProps.onChange as jest.MockedFunction<(value: Record<string, unknown>[]) => void>;

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

		expect(screen.getByTestId("arrayFieldInline")).toBeTruthy();
		fireEvent.click(screen.getByTestId("icon-action-component"));
		expect(onChangeMock).toHaveBeenCalled();
	});
});
