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

import { parseTheme } from "@ax/helpers";
import LanguageMenu from "@ax/components/LanguageMenu";
import globalTheme from "@ax/themes/theme.json";

afterEach(cleanup);

const defaultProps = {
	language: "en_GB",
	availableLanguages: [
		{
			id: 4,
			locale: "en_GB",
			language: "English",
			path: "/gonzalo-h",
			domain: {
				id: 1,
				url: "//cx.dev.griddo.io/pre-griddo",
				slug: "/pre-griddo",
			},
			label: "EN",
			isDefault: true,
			home: "//cx.dev.griddo.io/pre-griddo/gonzalo-h",
		},
		{
			id: 2,
			locale: "es_ES",
			language: "Spanish",
			path: "/gonzalo-h/es",
			domain: {
				id: 1,
				url: "//cx.dev.griddo.io/pre-griddo",
				slug: "/pre-griddo",
			},
			label: "ES",
			isDefault: false,
			home: "//cx.dev.griddo.io/pre-griddo/gonzalo-h/es",
		},
	],
	isInAppBar: true,
};

describe("LanguageMenu component rendering", () => {
	it("should render the component", () => {
		const setLanguage = jest.fn();

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

		const languageMenu = screen.getByTestId("language-menu");
		expect(languageMenu).toBeTruthy();
		const languageMenuItems = screen.getAllByTestId("language-menu-item");
		expect(languageMenuItems.length).toBe(2);
		expect(screen.getByText(/English/i)).toBeTruthy();

		// current selected language
		expect(languageMenuItems[0].querySelector(`div[data-testid="language-icon"]`)).toBeTruthy();
	});

	it("should render the component without props", () => {
		const setLanguage = jest.fn();

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<LanguageMenu setLanguage={setLanguage} />
			</ThemeProvider>,
		);

		const languageMenu = screen.getByTestId("language-menu");
		expect(languageMenu).toBeTruthy();

		const languageMenuItem = screen.queryAllByTestId("language-menu-item");
		expect(languageMenuItem.length).toBe(0);
	});

	it("should render the component with only one language", () => {
		const setLanguage = jest.fn();

		const props = {
			language: "en_GB",
			availableLanguages: [
				{
					id: 4,
					locale: "en_GB",
					language: "English",
					path: "/gonzalo-h",
					domain: {
						id: 1,
						url: "//cx.dev.griddo.io/pre-griddo",
						slug: "/pre-griddo",
					},
					label: "EN",
					isDefault: true,
					home: "//cx.dev.griddo.io/pre-griddo/gonzalo-h",
				},
			],
			isInAppBar: true,
		};

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<LanguageMenu setLanguage={setLanguage} {...props} />
			</ThemeProvider>,
		);

		const languageMenu = screen.getByTestId("language-menu");
		expect(languageMenu).toBeTruthy();

		const languageMenuItem = screen.queryAllByTestId("language-menu-item");
		expect(languageMenuItem.length).toBe(1);
	});

	it("should render the component showing new version language", () => {
		const setLanguage = jest.fn();

		const props = {
			language: "en_GB",
			availableLanguages: defaultProps.availableLanguages,
			isInAppBar: false,
			currentLanguages: [
				{
					id: 4,
					locale: "en_GB",
					language: "English",
					path: "/gonzalo-h",
					domain: {
						id: 1,
						url: "//cx.dev.griddo.io/pre-griddo",
						slug: "/pre-griddo",
					},
					label: "EN",
					isDefault: true,
					home: "//cx.dev.griddo.io/pre-griddo/gonzalo-h",
				},
			],
		};

		render(
			<ThemeProvider theme={parseTheme(globalTheme)}>
				<LanguageMenu setLanguage={setLanguage} {...props} />
			</ThemeProvider>,
		);

		expect(screen.getByText(/Add new version/i)).toBeTruthy();
	});
});

it("should render the component showing an editable language", () => {
	const setLanguage = jest.fn();

	const props = {
		language: "en_GB",
		availableLanguages: defaultProps.availableLanguages,
		isInAppBar: false,
		currentLanguages: [
			{
				id: 2,
				locale: "es_ES",
				language: "Spanish",
				path: "/gonzalo-h/es",
				domain: {
					id: 1,
					url: "//cx.dev.griddo.io/pre-griddo",
					slug: "/pre-griddo",
				},
				label: "ES",
				isDefault: false,
				home: "//cx.dev.griddo.io/pre-griddo/gonzalo-h/es",
			},
			{
				id: 4,
				locale: "en_GB",
				language: "English",
				path: "/gonzalo-h",
				domain: {
					id: 1,
					url: "//cx.dev.griddo.io/pre-griddo",
					slug: "/pre-griddo",
				},
				label: "EN",
				isDefault: true,
				home: "//cx.dev.griddo.io/pre-griddo/gonzalo-h",
			},
		],
	};

	render(
		<ThemeProvider theme={parseTheme(globalTheme)}>
			<LanguageMenu setLanguage={setLanguage} {...props} />
		</ThemeProvider>,
	);

	expect(screen.queryByText(/Add new version/i)).toBeFalsy();
	const languageMenuItems = screen.getAllByTestId("language-menu-item");
	expect(languageMenuItems.length).toBe(2);
	expect(screen.getByText(/Spanish/i)).toBeTruthy();
});

describe("LanguageMenu component events", () => {
	it("should call setLanguage on clicking the second language in the list", () => {
		const setLanguage = jest.fn();

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

		const languageMenuItems = screen.getAllByTestId("language-menu-item");
		fireEvent.click(languageMenuItems[1]);

		expect(setLanguage).toHaveBeenLastCalledWith(defaultProps.availableLanguages[1]);
	});
});
