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

import { parseTheme } from "@ax/helpers";
import globalTheme from "@ax/themes/theme.json";
import RolesModal, { IRolesModalProps } from "./../../../../../../modules/Users/UserCreate/SiteItem/RolesModal";

const addRolesMock = jest.fn();
const toggleModalMock = jest.fn();
const defaultProps: IRolesModalProps = {
	roles: [
		{
			id: 1,
			name: "Administrator",
			hex: "#C7ECF8",
			description:
				"You can manage all of your site's settings, users and roles. You can create and publish all pages of your site.",
			permissions: { totalPermissions: "78/78", sitePermissions: [], globalPermissions: [] },
			active: true,
			users: [],
		},
		{
			id: 2,
			name: "Constructor",
			hex: "#B5FBFF",
			description:
				"You can edit your website, add pages, modules, modify URLs, menus, colours and themes, html tags. You don't manage users, or manage the site configuration.",
			permissions: { totalPermissions: "49/78", sitePermissions: [], globalPermissions: [] },
			active: true,
			users: [],
		},
		{
			id: 3,
			name: "Editor",
			hex: "#E2EE9F",
			description: "You have permission to view, add and edit site content, such as pages and blocks.",
			permissions: { totalPermissions: "21/78", sitePermissions: [], globalPermissions: [] },
			active: false,
			users: [],
		},
	],
	addRoles: addRolesMock,
	toggleModal: toggleModalMock,
	isOpen: true,
};

afterEach(() => {
	jest.clearAllMocks();
	cleanup();
});

describe("RolesModal module rendering", () => {
	it("should render the componet with active roles", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<RolesModal {...defaultProps} />
			</ThemeProvider>,
		);

		expect(screen.queryByTestId("modal-roles-content")).toBeTruthy();
		expect(screen.queryAllByTestId("roles-modal-item").length).toBe(2);
	});

	it("should render the componet without roles", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<RolesModal {...defaultProps} roles={undefined} />
			</ThemeProvider>,
		);

		expect(screen.queryByTestId("modal-roles-content")).toBeTruthy();
		expect(screen.queryAllByTestId("roles-modal-item").length).toBe(0);
	});

	it("should render the componet with roles selected", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<RolesModal {...defaultProps} selectedRoles={[1]} />
			</ThemeProvider>,
		);

		expect(screen.queryByTestId("modal-roles-content")).toBeTruthy();
		const check = screen.getByLabelText("Administrator");
		expect(check).toBeChecked();
	});
});

describe("RolesModal module events", () => {
	it("should render permisions when role is selected", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<RolesModal {...defaultProps} />
			</ThemeProvider>,
		);

		expect(screen.queryByTestId("permissions-wrapper")).toHaveTextContent("Administrator");
		const roleItems = screen.queryAllByTestId("roles-modal-item-title");
		fireEvent.click(roleItems[1]);

		expect(screen.queryByTestId("permissions-wrapper")).toHaveTextContent("Constructor");
	});

	it("should check item, call addRoles with roles checked and close modal", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<RolesModal {...defaultProps} />
			</ThemeProvider>,
		);

		fireEvent.click(screen.getByLabelText("Administrator"));
		fireEvent.click(screen.getByText("Add User Role"));

		expect(addRolesMock).toBeCalledWith([1]);
		expect(toggleModalMock).toBeCalledTimes(1);
	});

	it("should uncheck item, call addRoles with roles checked and close modal", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<RolesModal {...defaultProps} selectedRoles={[1]} />
			</ThemeProvider>,
		);

		fireEvent.click(screen.getByLabelText("Administrator"));
		fireEvent.click(screen.getByLabelText("Constructor"));
		fireEvent.click(screen.getByText("Add User Role"));

		expect(addRolesMock).toBeCalledWith([2]);
		expect(toggleModalMock).toBeCalledTimes(1);
	});

	it("should call addRoles with empty array", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<RolesModal {...defaultProps} />
			</ThemeProvider>,
		);

		fireEvent.click(screen.getByText("Add User Role"));

		expect(addRolesMock).toBeCalledWith([]);
		expect(toggleModalMock).toBeCalledTimes(1);
	});

	it("should call addRoles with previously selected role", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<RolesModal {...defaultProps} selectedRoles={[2]} />
			</ThemeProvider>,
		);

		fireEvent.click(screen.getByText("Add User Role"));

		expect(addRolesMock).toBeCalledWith([2]);
		expect(toggleModalMock).toBeCalledTimes(1);
	});
});
