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 CustomizeFilters, { ICustomizeFiltersProps } from "@ax/components/TableFilters/CustomizeFilters";
import globalTheme from "@ax/themes/theme.json";

afterEach(cleanup);

const defaultProps = mock<ICustomizeFiltersProps>();

describe("CustomizeFilters component rendering", () => {
	it("should render customize filter", () => {
		defaultProps.columns = [
			{ id: "live", title: "Live", show: true },
			{ id: "profile", title: "Profile", show: true },
			{ id: "site", title: "Site", show: true },
			{ id: "status", title: "Status", show: true },
			{ id: "translation", title: "Trans.", show: true },
		];
		defaultProps.value = ["site", "profile", "live", "status", "translation"];
		defaultProps.limit = { value: 5, text: "five" };
		defaultProps.setColumns = jest.fn() as CalledWithMock<void, [newValue: any]> & ((newValue: any) => void);

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

		const customizeFilters = screen.getByTestId("customize-filters-wrapper");
		expect(customizeFilters).toBeTruthy();
	});
});

describe("CustomizeFilters events", () => {
	it("should render check group on click floating menu button", () => {
		defaultProps.columns = [
			{ id: "live", title: "Live", show: true },
			{ id: "profile", title: "Profile", show: true },
			{ id: "site", title: "Site", show: true },
			{ id: "status", title: "Status", show: true },
			{ id: "translation", title: "Trans.", show: true },
		];
		defaultProps.value = ["site", "profile", "live", "status", "translation"];
		defaultProps.limit = { value: 5, text: "five" };
		defaultProps.setColumns = jest.fn() as CalledWithMock<void, [newValue: any]> & ((newValue: any) => void);

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

		const customizeFilterButton = screen.getByTestId("floating-menu-button");
		expect(customizeFilterButton).toBeTruthy();
		fireEvent.click(customizeFilterButton);
		const floatingMenu = screen.getByTestId("floating-menu");
		expect(floatingMenu).toBeTruthy();
		const checkGroupFieldGroup = screen.getByTestId("check-group-field-group");
		expect(checkGroupFieldGroup).toBeTruthy();
		const checkFieldLabels = screen.getAllByTestId("check-field-label");
		expect(checkFieldLabels).toHaveLength(5);
	});

	it("should check option on click", () => {
		defaultProps.columns = [
			{ id: "live", title: "Live", show: true },
			{ id: "profile", title: "Profile", show: true },
			{ id: "site", title: "Site", show: true },
			{ id: "status", title: "Status", show: true },
			{ id: "translation", title: "Trans.", show: true },
		];
		defaultProps.value = ["site", "profile", "live", "status", "translation"];
		defaultProps.limit = { value: 5, text: "five" };
		defaultProps.setColumns = jest.fn() as CalledWithMock<void, [newValue: any]> & ((newValue: any) => void);

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

		const customizeFilterButton = screen.getByTestId("floating-menu-button");
		expect(customizeFilterButton).toBeTruthy();
		fireEvent.click(customizeFilterButton);
		const floatingMenu = screen.getByTestId("floating-menu");
		expect(floatingMenu).toBeTruthy();
		const checkGroupFieldGroup = screen.getByTestId("check-group-field-group");
		expect(checkGroupFieldGroup).toBeTruthy();
		const checkFieldInputs = screen.getAllByTestId<HTMLInputElement>("check-field-input");
		expect(checkFieldInputs).toHaveLength(5);
		fireEvent.change(checkFieldInputs[0], { target: { checked: false, value: "site" } });
		expect(checkFieldInputs[0].checked).toBe(false);
	});

	it("should call setColumns action on change", async () => {
		defaultProps.columns = [
			{ id: "live", title: "Live", show: true },
			{ id: "profile", title: "Profile", show: true },
			{ id: "site", title: "Site", show: true },
			{ id: "status", title: "Status", show: true },
			{ id: "translation", title: "Trans.", show: true },
		];
		defaultProps.value = ["site", "profile", "live", "status", "translation"];
		defaultProps.limit = { value: 5, text: "five" };
		const onChangeMock = jest.fn() as CalledWithMock<void, [newValue: any]> & ((newValue: any) => void);
		defaultProps.setColumns = onChangeMock;

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

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

		expect(customizeFilterButton).toBeTruthy();
		fireEvent.click(customizeFilterButton);
		const checkFieldInputs = screen.queryAllByTestId("check-field-input");
		fireEvent.click(checkFieldInputs[0]);
		expect(onChangeMock).toHaveBeenCalledTimes(1);
		expect(onChangeMock).toBeCalledWith([
			{ id: "live", title: "Live", show: false },
			{ id: "profile", title: "Profile", show: true },
			{ id: "site", title: "Site", show: true },
			{ id: "status", title: "Status", show: true },
			{ id: "translation", title: "Trans.", show: true },
		]);
	});
});
