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

import { defaultStore } from "./../../../../__mocks__/store/GenericStore";

afterEach(cleanup);

const defaultProps = mock<IFileFieldProps>();

const initialStore = {
	...defaultStore,
	fileDrive: {
		currentFolderContent: null,
		currentFolderID: null,
		breadcrumb: [],
		foldersTree: [],
		isUploading: false,
		isSuccess: false,
		isError: false,
		errorMsg: "",
		displayMode: "grid",
	},
};

const middlewares = [thunk];
const mockStore = configureStore(middlewares);

const store = mockStore(initialStore);

describe("FileField component rendering", () => {
	it("should render the component", () => {
		defaultProps.value.url = "google.es";

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<FileField {...defaultProps} />
			</ThemeProvider>,
			{ store },
		);

		const fileDataWrapper = screen.getByTestId("file-data-wrapper");

		expect(fileDataWrapper).toBeTruthy();
	});

	it("should render the component when there is not value", () => {
		defaultProps.value = undefined;

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<FileField {...defaultProps} />
			</ThemeProvider>,
			{ store },
		);

		const fileDataWrapper = screen.getByTestId("file-data-wrapper");

		expect(fileDataWrapper).toBeTruthy();
	});
});

describe("onClick events", () => {
	it("should open FileDragAndDrop when clicking the file button", () => {
		const Component = (
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<FileField {...defaultProps} />
			</ThemeProvider>
		);

		const { rerender } = render(Component, { store });

		const fileButton = screen.getByTestId("field-icon-wrapper");
		act(() => fileButton.click());

		rerender(Component);

		const fileDragAndDropWrapper = screen.queryByTestId("file-drag-and-drop-wrapper");
		expect(fileDragAndDropWrapper).toBeTruthy();
	});

	it("should not open FileDragAndDrop when clicking the file button", () => {
		const Component = (
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<FileField {...defaultProps} disabled />
			</ThemeProvider>
		);

		const { rerender } = render(Component, { store });

		const fileButton = screen.getByTestId("field-icon-wrapper");
		act(() => fileButton.click());

		rerender(Component);

		const fileDragAndDropWrapper = screen.queryByTestId("file-gallery-wrapper");
		expect(fileDragAndDropWrapper).toBeFalsy();
	});

	it("should call handleOnClickUrl when clicking the url button", () => {
		defaultProps.value = { url: "google.es", uploadDate: "1/1/2022", sizeBytes: "123" };

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

		const windowOpen = window.open;
		(window as any).open = () => ({ focus: () => null });

		const { rerender } = render(Component, { store });

		const spyWindowOpen = jest.spyOn(window, "open");

		const urlButton = screen.getAllByTestId("icon-action-component");
		act(() => urlButton[0].click());

		expect(spyWindowOpen).toBeCalled();

		(window as any).open = () => null;
		rerender(Component);

		act(() => urlButton[0].click());

		expect(spyWindowOpen).toBeCalled();

		window.open = windowOpen;
	});

	it("should call onChange when clicking the delete action", () => {
		defaultProps.value = { url: "google.es", uploadDate: "1/1/2022", sizeBytes: "123" };
		const onChange = jest.fn();

		const Component = (
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<FileField {...defaultProps} onChange={onChange} />
			</ThemeProvider>
		);

		const { rerender } = render(Component, { store });

		const floatingMenu = screen.getAllByTestId("icon-action-component");

		act(() => floatingMenu[1].click());

		rerender(Component);

		const actionMenuItem = screen.getAllByTestId("action-menu-item");
		act(() => actionMenuItem[1].click());

		expect(onChange).toBeCalledTimes(1);
	});
});
