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 SiteItem, { ISiteItemProps } from "./../../../../../modules/Users/UserCreate/SiteItem";

const itemOnChangeMock = jest.fn();
const addRolesMock = jest.fn();
const defaultProps: ISiteItemProps = {
	item: { id: 1, name: "Site 1", onChange: itemOnChangeMock },
	sites: [1, 2, 3],
	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: [],
		},
	],
	addRoles: addRolesMock,
};

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

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

		expect(screen.getByTestId("user-site-item")).toBeTruthy();
		expect(screen.getByTestId("check-cell")).toBeTruthy();
		expect(screen.getByTestId("action-cell")).toBeTruthy();
		expect(screen.getByText("Add Roles")).toBeTruthy();
		expect(screen.queryByTestId("wrapper-cell-featured")).toBeFalsy();
		expect(screen.getByText(defaultProps.item.name)).toBeInTheDocument();
	});

	it("should render the componet readonly", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<SiteItem {...defaultProps} readOnly={true} />
			</ThemeProvider>,
		);

		expect(screen.getByTestId("user-site-item")).toBeTruthy();
		expect(screen.queryByTestId("check-cell")).toBeFalsy();
		expect(screen.queryByTestId("action-cell")).toBeFalsy();
	});

	it("should render the componet disabled", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<SiteItem {...defaultProps} disabled={true} />
			</ThemeProvider>,
		);

		expect(screen.getByTestId("user-site-item")).toBeTruthy();
		const check = screen.getByLabelText(defaultProps.item.name);
		expect(check).toBeTruthy();
		expect(check).toBeDisabled();
	});

	it("should render the componet featured", async () => {
		const itemProps = { ...defaultProps, featured: true, description: "descripción del item" };
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<SiteItem {...itemProps} />
			</ThemeProvider>,
		);

		expect(screen.getByTestId("user-site-item")).toBeTruthy();
		expect(screen.getByTestId("wrapper-cell-featured")).toBeTruthy();
		expect(screen.getByTestId("check-cell")).toBeTruthy();
		expect(screen.queryByTestId("action-cell")).toBeFalsy();
		expect(screen.getByText(itemProps.description)).toBeInTheDocument();
		expect(screen.getByText("Add Roles")).toBeTruthy();
	});

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

		expect(screen.getByTestId("user-site-item")).toBeTruthy();
		expect(screen.queryByText("Add Roles")).toBeFalsy();
		expect(screen.getByText("Edit Roles")).toBeTruthy();
		expect(screen.getByText("Administrator")).toBeTruthy();
	});
});

describe("SiteItem module events", () => {
	it("should call onChange", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<SiteItem {...defaultProps} />
			</ThemeProvider>,
		);

		const checkCell = screen.getByTestId("check-cell");
		expect(checkCell).toBeTruthy();
		fireEvent.click(checkCell);
		expect(itemOnChangeMock).toBeCalledTimes(1);
	});

	it("should not call onChange if readOnly", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<SiteItem {...defaultProps} readOnly={true} />
			</ThemeProvider>,
		);

		const nameCell = screen.getByTestId("name-cell");
		expect(nameCell).toBeTruthy();
		fireEvent.click(nameCell);
		expect(itemOnChangeMock).toBeCalledTimes(0);
	});

	it("should open modal onClick", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<SiteItem {...defaultProps} />
			</ThemeProvider>,
		);

		expect(screen.queryByTestId("modal-roles-content")).toBeFalsy();
		const button = screen.getByText("Add Roles");
		fireEvent.click(button);

		expect(screen.queryByTestId("modal-roles-content")).toBeTruthy();
	});

	it("should call add roles with site and roles selected", async () => {
		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<SiteItem {...defaultProps} />
			</ThemeProvider>,
		);

		expect(screen.queryByTestId("modal-roles-content")).toBeFalsy();
		const button = screen.getByText("Add Roles");
		fireEvent.click(button);

		expect(screen.queryByTestId("modal-roles-content")).toBeTruthy();
		fireEvent.click(screen.getByLabelText("Administrator"));
		fireEvent.click(screen.getByText("Add User Role"));

		expect(addRolesMock).toBeCalledWith({ siteId: 1, roles: [1] });
	});
});
