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

afterEach(cleanup);

jest.mock("react-router-dom", () => ({
	...jest.requireActual("react-router-dom"),
	useLocation: () => ({
		pathname: "localhost:3000/example/path",
	}),
}));

const defaultProps = mock<IPasteModuleProps>();

const mockedFunction = defaultProps.pasteModule as jest.MockedFunction<
	(editorID: number, key: string, modulesToPaste: IModule[]) => Promise<{ error?: INotification }>
>;
const mockedNotification = defaultProps.setNotification as jest.MockedFunction<(notification: INotification) => void>;
defaultProps.editorID = 1;
defaultProps.modulesToPaste = [{ editorID: 1, component: "BasicContent" }];

describe("ComponentArraySelector component rendering", () => {
	test("should render the component", async () => {
		defaultProps.isModuleCopyUnavailable = true;
		defaultProps.setHistoryPush = jest.fn();
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<PasteModuleButton {...defaultProps} />
			</ThemeProvider>,
		);
		const iconButton = screen.getByTestId("icon-action-component");
		expect(iconButton).toBeTruthy();
		await act(async () => {
			fireEvent.click(iconButton);
		});
		expect(mockedNotification).toHaveBeenCalled();
	});
});

describe("ComponentArraySelector trigger events", () => {
	test("should trigger the onClick and resolve promise", async () => {
		defaultProps.isModuleCopyUnavailable = false;
		mockedFunction.mockResolvedValue({
			error: {
				type: "warning",
				text: "This is a warning",
			},
		});

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<PasteModuleButton {...defaultProps} />
			</ThemeProvider>,
		);
		const iconButton = screen.getByTestId("icon-action-component");
		expect(iconButton).toBeTruthy();
		await act(async () => {
			fireEvent.click(iconButton);
		});
		expect(mockedFunction).toHaveBeenCalled();
		await expect(mockedFunction(1, "", [{ editorID: 1, component: "BasicContent" }])).resolves.toEqual({
			error: {
				type: "warning",
				text: "This is a warning",
			},
		});

		expect(screen.getByTestId("tooltip-component")).toHaveTextContent("Paste from clipboard");
	});

	test("should trigger the onClick and resolve promise", async () => {
		defaultProps.isModuleCopyUnavailable = false;
		mockedFunction.mockResolvedValue({});

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<PasteModuleButton {...defaultProps} />
			</ThemeProvider>,
		);
		const iconButton = screen.getByTestId("icon-action-component");
		expect(iconButton).toBeTruthy();
		await act(async () => {
			fireEvent.click(iconButton);
		});
		expect(mockedFunction).toHaveBeenCalled();
		await expect(mockedFunction(1, "", [{ editorID: 1, component: "BasicContent" }])).resolves.toEqual({});
		expect(screen.getByTestId("toast-message")).toHaveTextContent("1 module pasted from clipboard");
	});

	test("should trigger the onClick and resolve promise without error", async () => {
		defaultProps.isModuleCopyUnavailable = false;
		mockedFunction.mockResolvedValue({ error: undefined });

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<PasteModuleButton {...defaultProps} />
			</ThemeProvider>,
		);
		const iconButton = screen.getByTestId("icon-action-component");
		expect(iconButton).toBeTruthy();
		await act(async () => {
			fireEvent.click(iconButton);
		});
		expect(mockedFunction).toHaveBeenCalled();
		await expect(mockedFunction(1, "", [{ editorID: 1, component: "BasicContent" }])).resolves.toEqual({
			error: undefined,
		});
		expect(screen.getByTestId("toast-message")).toHaveTextContent("1 module pasted from clipboard");
	});
});
