import React from "react";
import axios from "axios";
import "@testing-library/jest-dom";
import configureStore from "redux-mock-store";
import { ThemeProvider } from "styled-components";
import { mock } from "jest-mock-extended";
import thunk from "redux-thunk";

import { render, screen, cleanup, fireEvent, act } from "../../../../../config/jest/test-utils";

import ImageField, { IImageFieldProps } from "@ax/components/Fields/ImageField";
import { parseTheme } from "@ax/helpers";
import globalTheme from "@ax/themes/theme.json";
import { defaultStore } from "./../../../../__mocks__/store/GenericStore";

afterEach(() => {
	cleanup();
});

jest.mock("axios");
const mockedAxios = axios as jest.MockedFunction<typeof axios>;

const data = {
	data: [],
	status: 500,
	statusText: "Internal Server Error",
	headers: {},
	config: {},
};

mockedAxios.mockResolvedValue(data);

const defaultProps = mock<IImageFieldProps>();

const initialStore = {
	...defaultStore,
	gallery: {
		isLoading: {
			init: false,
			more: false,
		},
		isSaving: {
			save: false,
			saveAdd: false,
			delete: false,
		},
		isUploading: false,
		isSuccess: false,
		isError: false,
		errorMsg: "",
		currentFolderContent: null,
		currentFolderID: null,
		breadcrumb: [],
		foldersTree: [],
		displayMode: "grid",
		selectedTab: "site",
	},
};

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

const store = mockStore(initialStore);

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

		expect(screen.getByTestId("fieldWrapper")).toBeTruthy();
		expect(screen.getByTestId("previewDiv")).not.toBeVisible();
	});

	it("should render the component with linkableImage", () => {
		defaultProps.value = {
			id: 857,
			name: ".png",
			title: "",
			description: "",
			alt: "",
			tags: [],
			url: "kjkajsf",
			thumb: "jasd",
			publicId: "thesaurus",
			damId: "screenshot",
			published: new Date("2022-04-18T08:52:48.334Z"),
			size: 1123589,
			width: 1444,
			height: 640,
			orientation: "L",
			site: null,
			folderId: null,
		};

		defaultProps.selectedContent = {
			component: "LinkableImage",
			editorID: 7,
			parentEditorID: 4,
			title: "",
			alt: "",
			veil: 0,
			file: {
				id: 1001,
				name: "Imagen_Interior_fullstack.png",
				title: "",
				description: "",
				alt: "",
				tags: [],
				url: "https://images.dev.griddo.io/imagen-interior-fullstack",
				thumb: "https://images.dev.griddo.io/w/215/h/161/imagen-interior-fullstack",
				publicId: "thesaurus-dev/Imagen_Interior_fullstack_6c908d9f-b493-4c93-b4d2-a0439bc00820",
				damId: "imagen-interior-fullstack",
				published: "2022-06-30T07:06:54.352Z",
				size: 55286,
				width: 680,
				height: 353,
				orientation: "L",
				site: 113,
				folderId: null,
			},
		};

		defaultProps.cropPreview = true;

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

		expect(screen.getByTestId("fieldWrapper")).toBeTruthy();
		expect(screen.getByTestId("imageDataWrapper")).toBeTruthy();
		expect(screen.getByTestId("previewDiv")).toBeVisible();
	});

	it("should render the component with image with no url attr", async () => {
		defaultProps.value = "image.png";

		defaultProps.selectedContent = {
			component: "LinkableImage",
			editorID: 7,
			parentEditorID: 4,
			title: "",
			alt: "",
			veil: 0,
			file: {
				id: 1001,
				name: "Imagen_Interior_fullstack.png",
				title: "",
				description: "",
				alt: "",
				tags: [],
				url: "https://images.dev.griddo.io/imagen-interior-fullstack",
				thumb: "https://images.dev.griddo.io/w/215/h/161/imagen-interior-fullstack",
				publicId: "thesaurus-dev/Imagen_Interior_fullstack_6c908d9f-b493-4c93-b4d2-a0439bc00820",
				damId: "imagen-interior-fullstack",
				published: "2022-06-30T07:06:54.352Z",
				size: 55286,
				width: 680,
				height: 353,
				orientation: "L",
				site: 113,
				folderId: null,
			},
		};

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

		expect(screen.getByTestId("fieldWrapper")).toBeTruthy();
		expect(screen.queryByTestId("imageDataWrapper")).not.toBeTruthy();
		expect(screen.getByTestId("previewDiv")).toBeVisible();
	});

	it("should render the component with no image", async () => {
		defaultProps.value = null;

		defaultProps.selectedContent = {
			component: "LinkableImage",
			editorID: 7,
			parentEditorID: 4,
			title: "",
			alt: "",
			veil: 0,
			file: {
				id: 1001,
				name: "Imagen_Interior_fullstack.png",
				title: "",
				description: "",
				alt: "",
				tags: [],
				url: "https://images.dev.griddo.io/imagen-interior-fullstack",
				thumb: "https://images.dev.griddo.io/w/215/h/161/imagen-interior-fullstack",
				publicId: "thesaurus-dev/Imagen_Interior_fullstack_6c908d9f-b493-4c93-b4d2-a0439bc00820",
				damId: "imagen-interior-fullstack",
				published: "2022-06-30T07:06:54.352Z",
				size: 55286,
				width: 680,
				height: 353,
				orientation: "L",
				site: 113,
				folderId: null,
			},
		};

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

		expect(screen.getByTestId("fieldWrapper")).toBeTruthy();
		expect(screen.queryByTestId("imageDataWrapper")).not.toBeTruthy();
		expect(screen.getByTestId("previewDiv")).not.toBeVisible();
	});

	it("should render the component with image with undefined", async () => {
		// biome-ignore lint/suspicious/noTsIgnore: TODO: fix this
		// @ts-ignore
		defaultProps.value = undefined;

		defaultProps.selectedContent = {
			component: "LinkableImage",
			editorID: 7,
			parentEditorID: 4,
			title: "",
			alt: "",
			veil: 0,
			file: {
				id: 1001,
				name: "Imagen_Interior_fullstack.png",
				title: "",
				description: "",
				alt: "",
				tags: [],
				url: "https://images.dev.griddo.io/imagen-interior-fullstack",
				thumb: "https://images.dev.griddo.io/w/215/h/161/imagen-interior-fullstack",
				publicId: "thesaurus-dev/Imagen_Interior_fullstack_6c908d9f-b493-4c93-b4d2-a0439bc00820",
				damId: "imagen-interior-fullstack",
				published: "2022-06-30T07:06:54.352Z",
				size: 55286,
				width: 680,
				height: 353,
				orientation: "L",
				site: 113,
				folderId: null,
			},
		};

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

		expect(screen.getByTestId("fieldWrapper")).toBeTruthy();
		expect(screen.queryByTestId("imageDataWrapper")).not.toBeTruthy();
		expect(screen.getByTestId("previewDiv")).not.toBeVisible();
	});
});

describe("ImageField triggers", () => {
	it("should handle the onClick", async () => {
		defaultProps.value = {
			id: 857,
			name: ".png",
			title: "",
			description: "",
			alt: "",
			tags: [],
			url: "https://images.dev.griddo.io/screenshot-2022-04-13-at-164915",
			thumb: "https://images.dev.griddo.io/w/215/h/161/screenshot-2022-04-13-at-164915",
			publicId: "thesaurus-dev/Screenshot_2022-04-13_at_16.49.15_927293bf-d163-402f-b216-4dc8656ea8c1",
			damId: "screenshot-2022-04-13-at-164915",
			published: new Date("2022-04-18T08:52:48.334Z"),
			size: 1123589,
			width: 1444,
			height: 640,
			orientation: "L",
			site: null,
			folderId: null,
		};

		defaultProps.selectedContent = {
			component: "LinkableImage",
			editorID: 7,
			parentEditorID: 4,
			title: "",
			alt: "",
			veil: 0,
			file: {
				id: 1001,
				name: "Imagen_Interior_fullstack.png",
				title: "",
				description: "",
				alt: "",
				tags: [],
				url: "https://images.dev.griddo.io/imagen-interior-fullstack",
				thumb: "https://images.dev.griddo.io/w/215/h/161/imagen-interior-fullstack",
				publicId: "thesaurus-dev/Imagen_Interior_fullstack_6c908d9f-b493-4c93-b4d2-a0439bc00820",
				damId: "imagen-interior-fullstack",
				published: "2022-06-30T07:06:54.352Z",
				size: 55286,
				width: 680,
				height: 353,
				orientation: "L",
				site: 113,
				folderId: null,
			},
		};
		const setIsGalleryMock = defaultProps.setIsGalleryOpened as jest.MockedFunction<() => void>;
		defaultProps.disabled = false;

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

		const fieldWrapperAction = screen.getByTestId("fieldWrapper");
		expect(fieldWrapperAction).toBeTruthy();

		await act(async () => fireEvent.click(fieldWrapperAction));

		expect(setIsGalleryMock).toBeCalled();
	});

	it("should handle the delete action", () => {
		defaultProps.value = {
			id: 857,
			name: ".png",
			title: "",
			description: "",
			alt: "",
			tags: [],
			url: "https://images.dev.griddo.io/screenshot-2022-04-13-at-164915",
			thumb: "https://images.dev.griddo.io/w/215/h/161/screenshot-2022-04-13-at-164915",
			publicId: "thesaurus-dev/Screenshot_2022-04-13_at_16.49.15_927293bf-d163-402f-b216-4dc8656ea8c1",
			damId: "screenshot-2022-04-13-at-164915",
			published: new Date("2022-04-18T08:52:48.334Z"),
			size: 1123589,
			width: 1444,
			height: 640,
			orientation: "L",
			site: null,
			folderId: null,
		};

		defaultProps.selectedContent = {
			component: "LinkableImage",
			editorID: 7,
			parentEditorID: 4,
			title: "",
			alt: "",
			veil: 0,
			file: {
				id: 1001,
				name: "Imagen_Interior_fullstack.png",
				title: "",
				description: "",
				alt: "",
				tags: [],
				url: "https://images.dev.griddo.io/imagen-interior-fullstack",
				thumb: "https://images.dev.griddo.io/w/215/h/161/imagen-interior-fullstack",
				publicId: "thesaurus-dev/Imagen_Interior_fullstack_6c908d9f-b493-4c93-b4d2-a0439bc00820",
				damId: "imagen-interior-fullstack",
				published: "2022-06-30T07:06:54.352Z",
				size: 55286,
				width: 680,
				height: 353,
				orientation: "L",
				site: 113,
				folderId: null,
			},
		};
		const onChangeMock = defaultProps.onChange as jest.MockedFunction<(value: any) => void>;
		defaultProps.disabled = false;
		const { rerender } = render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<ImageField {...defaultProps} />
			</ThemeProvider>,
			{ store },
		);

		const iconActions = screen.getAllByTestId("icon-action-component");
		expect(iconActions).toHaveLength(2);

		fireEvent.click(iconActions[1]);
		expect(onChangeMock).toBeCalled();

		rerender(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<ImageField {...defaultProps} />
			</ThemeProvider>,
		);
		const fieldWrapperAction = screen.getByTestId("fieldWrapper");
		const previewDiv = screen.getByTestId("previewDiv");
		expect(fieldWrapperAction).toBeVisible();
		expect(previewDiv).not.toBeVisible();
	});

	it("should handle the change action", async () => {
		defaultProps.value = {
			id: 857,
			name: ".png",
			title: "",
			description: "",
			alt: "",
			tags: [],
			url: "https://images.dev.griddo.io/screenshot-2022-04-13-at-164915",
			thumb: "https://images.dev.griddo.io/w/215/h/161/screenshot-2022-04-13-at-164915",
			publicId: "thesaurus-dev/Screenshot_2022-04-13_at_16.49.15_927293bf-d163-402f-b216-4dc8656ea8c1",
			damId: "screenshot-2022-04-13-at-164915",
			published: new Date("2022-04-18T08:52:48.334Z"),
			size: 1123589,
			width: 1444,
			height: 640,
			orientation: "L",
			site: null,
			folderId: null,
		};

		defaultProps.selectedContent = {
			component: "LinkableImage",
			editorID: 7,
			parentEditorID: 4,
			title: "",
			alt: "",
			veil: 0,
			file: {
				id: 1001,
				name: "Imagen_Interior_fullstack.png",
				title: "",
				description: "",
				alt: "",
				tags: [],
				url: "https://images.dev.griddo.io/imagen-interior-fullstack",
				thumb: "https://images.dev.griddo.io/w/215/h/161/imagen-interior-fullstack",
				publicId: "thesaurus-dev/Imagen_Interior_fullstack_6c908d9f-b493-4c93-b4d2-a0439bc00820",
				damId: "imagen-interior-fullstack",
				published: "2022-06-30T07:06:54.352Z",
				size: 55286,
				width: 680,
				height: 353,
				orientation: "L",
				site: 113,
				folderId: null,
			},
		};
		const setIsGalleryMock = defaultProps.setIsGalleryOpened as jest.MockedFunction<() => void>;
		defaultProps.disabled = false;
		const { rerender } = render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<ImageField {...defaultProps} />
			</ThemeProvider>,
			{ store },
		);

		const iconActions = screen.getAllByTestId("icon-action-component");
		expect(iconActions).toHaveLength(2);

		await act(async () => fireEvent.click(iconActions[0]));
		expect(setIsGalleryMock).toBeCalled();

		rerender(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<ImageField {...defaultProps} />
			</ThemeProvider>,
		);

		expect(screen.getByTestId("previewDiv")).toBeVisible();
	});
});
