import * as React from "react";

import { ThemeProvider } from "styled-components";
import { CalledWithMock, mock } from "jest-mock-extended";

import { render, screen, cleanup, fireEvent } from "@testing-library/react";

import { parseTheme } from "@ax/helpers";

import globalTheme from "@ax/themes/theme.json";
import TranslationsFilter, { ITranslationsFilterProps } from "@ax/components/TableFilters/TranslationsFilter";
import { IQueryValue } from "@ax/types";

afterEach(cleanup);
const defaultProps = mock<ITranslationsFilterProps>();
describe("TranslationsFilter component rendering", () => {
	it("should render name filter", () => {
		const onClickMock = jest.fn() as CalledWithMock<void, [pointer: string, filter: IQueryValue[]]> &
			((pointer: string, filter: IQueryValue[]) => void);
		defaultProps.value = [{ value: "all", label: "All" }];
		defaultProps.filterItems = onClickMock;

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

		const translationFilter = screen.getByTestId("translation-filter-header");
		expect(translationFilter).toBeTruthy();
		expect(translationFilter.textContent).toEqual("Trans.");
	});

	it("should render icon's wrapper", () => {
		const onClickMock = jest.fn() as CalledWithMock<void, [pointer: string, filter: IQueryValue[]]> &
			((pointer: string, filter: IQueryValue[]) => void);
		defaultProps.value = [{ value: "all", label: "All" }];
		defaultProps.filterItems = onClickMock;
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<TranslationsFilter {...defaultProps} />
			</ThemeProvider>,
		);

		const interactiveArrow = screen.getByTestId("translation-filter-icons-wrapper");
		expect(interactiveArrow).toBeTruthy();
	});

	it("should render options", async () => {
		const onClickMock = jest.fn() as CalledWithMock<void, [pointer: string, filter: IQueryValue[]]> &
			((pointer: string, filter: IQueryValue[]) => void);
		defaultProps.value = [{ value: "all", label: "All" }];
		defaultProps.filterItems = onClickMock;
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<TranslationsFilter {...defaultProps} />
			</ThemeProvider>,
		);

		const translationFilterButton = screen.getByTestId("floating-menu-button");

		expect(translationFilterButton).toBeTruthy();
		fireEvent.click(translationFilterButton);
		const checksFieldLabels = screen.getAllByTestId("check-field-label");

		expect(checksFieldLabels).toHaveLength(2);
		expect(checksFieldLabels[0].textContent).toEqual("All");
		expect(checksFieldLabels[1].textContent).toEqual("Not translated content");
	});
});

describe("TranslationsFilter events", () => {
	it("should render check group on click", () => {
		const onClickMock = jest.fn() as CalledWithMock<void, [pointer: string, filter: IQueryValue[]]> &
			((pointer: string, filter: IQueryValue[]) => void);
		defaultProps.value = [{ value: "all", label: "All" }];
		defaultProps.filterItems = onClickMock;
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<TranslationsFilter {...defaultProps} />
			</ThemeProvider>,
		);

		const translationFilterButton = screen.getByTestId("floating-menu-button");
		expect(translationFilterButton).toBeTruthy();
		fireEvent.click(translationFilterButton);
		const floatingMenu = screen.getByTestId("floating-menu");
		expect(floatingMenu).toBeTruthy();
		const checkInputs = screen.getAllByTestId("check-field-input");
		expect(checkInputs).toHaveLength(2);
	});

	it("should call filterItems with 'all' on click 'All' option", async () => {
		const onClickMock = jest.fn() as CalledWithMock<void, [pointer: string, filter: IQueryValue[]]> &
			((pointer: string, filter: IQueryValue[]) => void);
		defaultProps.value = [{ value: "all", label: "All" }];
		defaultProps.filterItems = onClickMock;
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<TranslationsFilter {...defaultProps} />
			</ThemeProvider>,
		);

		const translationFilterButton = screen.getByTestId("floating-menu-button");

		expect(translationFilterButton).toBeTruthy();
		fireEvent.click(translationFilterButton);
		const checksFieldInputs = screen.getAllByTestId("check-field-input");

		fireEvent.click(checksFieldInputs[0]);
		expect(onClickMock).toHaveBeenCalledTimes(1);
		expect(onClickMock).toBeCalledWith("translated", [{ label: "All", value: "all" }]);
	});

	it("should call filterItems with 'no' on click 'Not translated content' option", async () => {
		const onClickMock = jest.fn() as CalledWithMock<void, [pointer: string, filter: IQueryValue[]]> &
			((pointer: string, filter: IQueryValue[]) => void);
		defaultProps.value = [{ value: "all", label: "All" }];
		defaultProps.filterItems = onClickMock;
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<TranslationsFilter {...defaultProps} />
			</ThemeProvider>,
		);

		const translationFilterButton = screen.getByTestId("floating-menu-button");

		expect(translationFilterButton).toBeTruthy();
		fireEvent.click(translationFilterButton);
		const checksFieldInputs = screen.getAllByTestId("check-field-input");

		fireEvent.click(checksFieldInputs[1]);
		expect(onClickMock).toHaveBeenCalledTimes(1);
		expect(onClickMock).toBeCalledWith("translated", [{ label: "Not translated content", value: "no" }]);
	});

	it("should close floating menu when option is checked", async () => {
		const onClickMock = jest.fn() as CalledWithMock<void, [pointer: string, filter: IQueryValue[]]> &
			((pointer: string, filter: IQueryValue[]) => void);
		defaultProps.value = [{ value: "all", label: "All" }];
		defaultProps.filterItems = onClickMock;
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<TranslationsFilter {...defaultProps} />
			</ThemeProvider>,
		);

		const translationFilterButton = screen.getByTestId("floating-menu-button");

		expect(translationFilterButton).toBeTruthy();
		fireEvent.click(translationFilterButton);
		const checksFieldInputs = screen.getAllByTestId("check-field-input");
		fireEvent.click(checksFieldInputs[1]);
		expect(onClickMock).toHaveBeenCalledTimes(1);
		const checksWrapper = screen.queryByTestId("translation-filter-checks-wrapper");
		expect(checksWrapper).toBeFalsy();
	});
});
