import * as React from "react";

import { ThemeProvider } from "styled-components";
import { render, cleanup, screen, fireEvent } from "@testing-library/react";
import { mock } from "jest-mock-extended";
import "@testing-library/jest-dom";

import { parseTheme } from "@ax/helpers";
import DragAndDrop, { IDragAndDropProps } from "@ax/components/DragAndDrop";
import globalTheme from "@ax/themes/theme.json";

afterEach(cleanup);

const defaultProps = mock<IDragAndDropProps>();
const onDropMock = defaultProps.onDrop as jest.MockedFunction<(e: React.DragEvent<HTMLDivElement>) => void>;
const onDragOverMock = defaultProps.onDragOver as jest.MockedFunction<(e: React.DragEvent<HTMLDivElement>) => void>;
const onDragEnterMock = defaultProps.onDragEnter as jest.MockedFunction<(e: React.DragEvent<HTMLDivElement>) => void>;
const onDragLeaveMock = defaultProps.onDragLeave as jest.MockedFunction<(e: React.DragEvent<HTMLDivElement>) => void>;
defaultProps.children = React.createElement("button", null, "back button");

describe("ErrorCenter component rendering", () => {
	it("should render the component", () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<DragAndDrop {...defaultProps} />
			</ThemeProvider>,
		);

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

	it("should call the onDrop", () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<DragAndDrop {...defaultProps} />
			</ThemeProvider>,
		);

		const dragDropWrapper = screen.getByTestId("drag-drop-wrapper");
		fireEvent.drop(dragDropWrapper);
		expect(onDropMock).toBeCalled();
	});

	it("should call the onDragOver", () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<DragAndDrop {...defaultProps} />
			</ThemeProvider>,
		);

		const dragDropWrapper = screen.getByTestId("drag-drop-wrapper");
		fireEvent.dragOver(dragDropWrapper);
		expect(onDragOverMock).toBeCalled();
	});

	it("should call the onDragEnter", () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<DragAndDrop {...defaultProps} />
			</ThemeProvider>,
		);

		const dragDropWrapper = screen.getByTestId("drag-drop-wrapper");
		fireEvent.dragEnter(dragDropWrapper);
		expect(onDragEnterMock).toBeCalled();
	});

	it("should call the onDragLeave", () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<DragAndDrop {...defaultProps} />
			</ThemeProvider>,
		);

		const dragDropWrapper = screen.getByTestId("drag-drop-wrapper");
		fireEvent.dragLeave(dragDropWrapper);
		expect(onDragLeaveMock).toBeCalled();
	});

	it("should render the children", () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<DragAndDrop {...defaultProps} />
			</ThemeProvider>,
		);

		const buttonText = screen.getByText("back button");
		expect(buttonText).toBeInTheDocument();
	});
});
