import * as React from "react";
import MixableComponentArray, {
	IMixableComponentArrayProps,
} from "@ax/components/Fields/ComponentArray/MixableComponentArray";
import { ThemeProvider } from "styled-components";
import { parseTheme } from "@ax/helpers";
import globalTheme from "@ax/themes/theme.json";
import { IModule } from "@ax/types";
import { render, screen, cleanup, fireEvent } from "@testing-library/react";
import { mock } from "jest-mock-extended";

afterEach(cleanup);

const mixableProps = mock<IMixableComponentArrayProps>();
const mixableModule = mock<IModule>();
const otherMixableModule = mock<IModule>();
// default values for MixableComponentArray
mixableModule.editorID = 1;
mixableModule.component = "HeroCard";
mixableModule.title = "Cards";
mixableModule.modules = [];
otherMixableModule.editorID = 2;
otherMixableModule.component = "HeroCard";
otherMixableModule.title = "Hero Section";
otherMixableModule.modules = [];
mixableProps.field = { type: "components", title: "", key: "elements" };
const testModule = {
	value: {
		editorID: 1,
		component: "HeroCard",
		title: "Cards",
		modules: [],
	},
};
// test for old value prop (it wasn't an array)
// biome-ignore lint/suspicious/noTsIgnore: TODO: fix this
// @ts-ignore
mixableProps.value = testModule;
mixableProps.activatedModules = ["HeroSection"];
mixableProps.whiteList = ["Module1"];
mixableProps.moduleCopy = null;

describe("ComponentArraySelector component rendering", () => {
	test("should render the component with MixableComponentArray", () => {
		mixableProps.disabled = true;
		mixableProps.editorID = 1;
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<MixableComponentArray {...mixableProps} />
			</ThemeProvider>,
		);

		expect(screen.getAllByTestId("mixableComponentWrapper")).toBeTruthy();
	});

	test("should render the AddItemButton", () => {
		otherMixableModule.editorID = 5;
		otherMixableModule.component = "HeroCard";
		otherMixableModule.title = "Hero Section";
		otherMixableModule.modules = [];
		mixableProps.value = [mixableModule, otherMixableModule];
		mixableProps.field = { contentType: "modules", title: "", key: "elements", type: "" };
		mixableProps.objKey = "elements";
		mixableProps.disabled = false;
		mixableProps.maxItems = 10;
		mixableProps.actions = {
			addModuleAction: jest.fn(),
			addComponentAction: jest.fn(),
			deleteModuleAction: jest.fn(),
			replaceElementsInCollectionAction: jest.fn(),
			duplicateModuleAction: jest.fn(),
			copyModuleAction: jest.fn(),
			moveModuleAction: jest.fn(),
			pasteModuleAction: jest.fn(),
			setNotificationAction: jest.fn(),
			replaceModuleAction: jest.fn(),
		};

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<MixableComponentArray {...mixableProps} />
			</ThemeProvider>,
		);

		expect(screen.getAllByTestId("icon-action-component")).toBeTruthy();
	});

	// Test incompleto. Lo dejo por si lo podemos reaprovechar más adelante
	/*
  test("should render the SideModal", () => {
    otherMixableModule.editorID = 5;
    otherMixableModule.component = "HeroCard";
    otherMixableModule.title = "Hero Section";
    otherMixableModule.modules = [];
    mixableProps.value = [];
    mixableProps.field = { contentType: "modules" };
    mixableProps.objKey = "elements";
    mixableProps.disabled = false;
    mixableProps.maxItems = 1;
    mixableProps.actions = {
      addModuleAction: jest.fn(),
      addComponentAction: jest.fn(),
      deleteModuleAction: jest.fn(),
      replaceElementsInCollectionAction: jest.fn(),
    };
    mixableProps.whiteList = ["BasicContent", "CardCollection"];

    const Component = (
      <ThemeProvider theme={parseTheme(globalTheme)}>
        <MixableComponentArray {...mixableProps} />
      </ThemeProvider>
    );

    const { rerender } = render(Component);
    const addItemButton = screen.getAllByTestId<HTMLElement>("icon-action-component");
    expect(addItemButton).toBeTruthy();
    fireEvent.click(addItemButton[0]);
    rerender(Component);
  });
  */
	test("should render with moduleCopy available", () => {
		otherMixableModule.editorID = 5;
		otherMixableModule.component = "HeroCard";
		otherMixableModule.title = "Hero Section";
		otherMixableModule.modules = [];
		mixableProps.whiteList = ["Module1"];
		mixableProps.value = [mixableModule, otherMixableModule];
		mixableProps.field = {
			contentType: "modules",
			key: "mainContent",
			title: "",
			type: "",
		};
		mixableProps.objKey = "elements";
		mixableProps.disabled = false;
		mixableProps.maxItems = 10;
		mixableProps.actions = {
			addModuleAction: jest.fn(),
			addComponentAction: jest.fn(),
			deleteModuleAction: jest.fn(),
			replaceElementsInCollectionAction: jest.fn(),
			duplicateModuleAction: jest.fn(),
			copyModuleAction: jest.fn(),
			moveModuleAction: jest.fn(),
			pasteModuleAction: jest.fn(),
			setNotificationAction: jest.fn(),
			replaceModuleAction: jest.fn(),
		};
		mixableProps.template = { component: "BasicTemplate" };
		mixableProps.availableDataPacks = [
			{
				id: "ARTICLES",
				title: "Articles",
				category: {
					id: "ARTICLES",
					label: "Articles",
				},
				description: "Allows you to hightlight articles",
				image:
					"https://res.cloudinary.com/thesaurus-cms/image/upload/griddo-components/data-packs-thumbnails/articles.png",
				templates: [
					{
						id: "ArticlesList",
						title: "Articles List",
						thumbnails: {
							"1x": "https://res.cloudinary.com/thesaurus-cms/image/upload/griddo-components/thumbnails/ArticlesList",
							"2x": "https://res.cloudinary.com/thesaurus-cms/image/upload/griddo-components/thumbnails/ArticlesList@2x",
						},
						dataPacks: ["ARTICLES"],
						type: {
							label: "Articles",
							value: "articles",
							mode: "list",
						},
					},
				],
				modules: [
					{
						id: "ArticlesDistributor",
						title: "Articles Distributor",
						category: "articlesAndEvents",
						thumbnails: {
							"1x": "https://res.cloudinary.com/thesaurus-cms/image/upload/griddo-components/thumbnails/ArticlesDistributor",
							"2x": "https://res.cloudinary.com/thesaurus-cms/image/upload/griddo-components/thumbnails/ArticlesDistributor@2x",
						},
						dataPacks: ["ARTICLES"],
						type: {},
						sectionList: {
							BasicTemplate: ["mainContent"],
							NewsDetail: ["closureContent"],
							NewsList: ["relatedContent"],
							SitemapTemplate: ["relatedContent", "closureContent"],
							StoryDetail: ["mainContent", "relatedContent"],
						},
					},
				],
				categories: [],
				structuredData: [
					{
						id: "ARTICLES",
						title: "Articles",
						dataPacks: ["ARTICLES"],
						local: false,
						fromPage: false,
						relatedCategories: [],
					},
				],
				activated: false,
				config: null,
			},
		];
		const actualDate = new Date();
		mixableProps.moduleCopy = {
			date: actualDate,
			elements: [
				{
					editorID: 1,
					component: "ArticlesDistributor",
					anchorID: null,
					verticalSpacing: "medium",
					hasDistributorData: true,
					data: {
						mode: "auto",
						source: ["ARTICLES"],
						order: "alpha",
						quantity: 2,
					},
					layout: "L001",
					title: {
						content: "Title",
						tag: "h2",
					},
					subtitle: "subtitle",
					detail: "detail",
					primaryLinkStyle: "primary",
					groupingLink: {
						component: "Link",
						text: "View all",
						style: "secondary",
						editorID: 40,
						parentEditorID: 39,
					},
				},
			],
		};
		mixableProps.mandatory = true;

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<MixableComponentArray {...mixableProps} />
			</ThemeProvider>,
		);

		expect(screen.getAllByTestId("tooltip-component")).toBeTruthy();
	});
});

describe("ComponentArraySelector component events trigger", () => {
	test("should handle the AddItemButton onClick", () => {
		otherMixableModule.editorID = 5;
		otherMixableModule.component = "HeroCard";
		otherMixableModule.title = "Hero Section";
		otherMixableModule.modules = [];
		mixableProps.value = [mixableModule, otherMixableModule];
		mixableProps.field = { contentType: "modules", title: "", key: "elements", type: "" };
		mixableProps.objKey = "elements";
		mixableProps.disabled = false;
		mixableProps.maxItems = 10;
		mixableProps.actions = {
			addModuleAction: jest.fn(),
			addComponentAction: jest.fn(),
			deleteModuleAction: jest.fn(),
			replaceElementsInCollectionAction: jest.fn(),
			duplicateModuleAction: jest.fn(),
			copyModuleAction: jest.fn(),
			moveModuleAction: jest.fn(),
			pasteModuleAction: jest.fn(),
			setNotificationAction: jest.fn(),
			replaceModuleAction: jest.fn(),
		};

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<MixableComponentArray {...mixableProps} />
			</ThemeProvider>,
		);

		expect(screen.getAllByTestId("icon-action-component")).toBeTruthy();
		fireEvent.click(screen.getAllByTestId("icon-action-component")[0]);
		expect(mixableProps.actions.addModuleAction).toBeCalled();
	});

	test("should handle the PasteModuleButton onClick", () => {
		mixableModule.editorID = 1;
		mixableModule.component = "HeroCard";
		mixableModule.title = "Cards";
		mixableModule.modules = [];
		otherMixableModule.editorID = 2;
		otherMixableModule.component = "HeroCard";
		otherMixableModule.title = "Hero Section";
		otherMixableModule.modules = [];
		mixableProps.field = { type: "components", title: "", key: "elements" };
		mixableProps.value = [mixableModule];
		mixableProps.activatedModules = ["HeroSection"];
		mixableProps.whiteList = ["Module1"];
		mixableProps.moduleCopy = null;
		mixableProps.actions = {
			addModuleAction: jest.fn(),
			addComponentAction: jest.fn(),
			deleteModuleAction: jest.fn(),
			replaceElementsInCollectionAction: jest.fn(),
			duplicateModuleAction: jest.fn(),
			copyModuleAction: jest.fn(),
			moveModuleAction: jest.fn(),
			pasteModuleAction: jest.fn(),
			setNotificationAction: jest.fn(),
			replaceModuleAction: jest.fn(),
		};

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<MixableComponentArray {...mixableProps} />
			</ThemeProvider>,
		);

		expect(screen.getAllByTestId("icon-action-component")).toBeTruthy();
		fireEvent.click(screen.getAllByTestId("icon-action-component")[0]);
		expect(mixableProps.actions.addComponentAction).toBeCalled();
	});
});
