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

afterEach(cleanup);

const settings = {
	cloudinaryName: "cloudinary",
	globalLogoBig: "https://images.dev.griddo.io/logothesaurusextenden-2x-jrexex_6",
	globalLogoMini: "https://images.dev.griddo.io/logothesaurusreduced-2x-cltah3_1",
	siteLogoBig: "https://images.dev.griddo.io/logobs_1",
	siteLogoMini: "https://images.dev.griddo.io/logobs-mini_1",
	welcomeText1: "Welcome back to",
	welcomeText2: "Griddo",
	autoSummary: false,
	autoTranslation: false,
};

describe("Login component rendering", () => {
	it("should render the component", () => {
		const defaultProps: ILoginProps = {
			handleSubmit: jest.fn(),
			email: "hola@secuoyas.com",
			handleEmail: jest.fn(),
			password: "password",
			handlePassword: jest.fn(),
			isLoggingIn: false,
			settings,
			rememberMe: false,
			handleRememberMe: jest.fn(),
		};

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

		const wrapper = screen.getByTestId("login-wrapper");
		expect(wrapper).toBeTruthy();
		const loginButton = screen.getByText("Login");
		expect(loginButton).toBeTruthy();
	});

	it("should render the component with log button disabled", () => {
		const handleSubmitMock = jest.fn();
		const defaultProps: ILoginProps = {
			handleSubmit: handleSubmitMock,
			email: "hola@secuoyas.com",
			handleEmail: jest.fn(),
			password: "password",
			handlePassword: jest.fn(),
			isLoggingIn: true,
			settings,
			rememberMe: false,
			handleRememberMe: jest.fn(),
		};

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

		const loginButton = screen.queryByText("Login");
		expect(loginButton).toBeFalsy();
		const loginButtonSending = screen.getByText("Sending");
		expect(loginButtonSending).toBeTruthy();
		fireEvent.click(loginButtonSending);
		expect(handleSubmitMock).toBeCalledTimes(0);
	});
});

describe("Login component events", () => {
	it("should call submit function on button click", () => {
		const handleSubmitMock = jest.fn((e) => e.preventDefault());
		const defaultProps: ILoginProps = {
			handleSubmit: handleSubmitMock,
			email: "hola@secuoyas.com",
			handleEmail: jest.fn(),
			password: "password",
			handlePassword: jest.fn(),
			isLoggingIn: false,
			settings,
			rememberMe: false,
			handleRememberMe: jest.fn(),
		};

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

		const loginButton = screen.getByText("Login");
		expect(loginButton).toBeTruthy();
		fireEvent.click(loginButton);
		expect(handleSubmitMock).toBeCalledTimes(1);
	});

	it("should call handleEmail function on email change", () => {
		const handleEmailMock = jest.fn();
		const defaultProps: ILoginProps = {
			handleSubmit: jest.fn((e) => e.preventDefault()),
			email: "hola@secuoyas.com",
			handleEmail: handleEmailMock,
			password: "password",
			handlePassword: jest.fn(),
			isLoggingIn: false,
			settings,
			rememberMe: false,
			handleRememberMe: jest.fn(),
		};

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

		const input = screen.getByLabelText("email");
		expect(input).toBeTruthy();
		fireEvent.change(input, { target: { value: "prueba" } });
		expect(handleEmailMock).toBeCalledTimes(1);
	});

	it("should call handlePassword function on password change", () => {
		const handlePasswordMock = jest.fn();
		const defaultProps: ILoginProps = {
			handleSubmit: jest.fn((e) => e.preventDefault()),
			email: "hola@secuoyas.com",
			handleEmail: jest.fn(),
			password: "password",
			handlePassword: handlePasswordMock,
			isLoggingIn: false,
			settings,
			rememberMe: false,
			handleRememberMe: jest.fn(),
		};

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

		const input = screen.getByLabelText("password");
		expect(input).toBeTruthy();
		fireEvent.change(input, { target: { value: "prueba" } });
		expect(handlePasswordMock).toBeCalledTimes(1);
	});

	it("should call handleRememberMe function on input click", () => {
		const handleRememberMeMock = jest.fn();
		const defaultProps: ILoginProps = {
			handleSubmit: jest.fn((e) => e.preventDefault()),
			email: "hola@secuoyas.com",
			handleEmail: jest.fn(),
			password: "password",
			handlePassword: jest.fn(),
			isLoggingIn: false,
			settings,
			rememberMe: false,
			handleRememberMe: handleRememberMeMock,
		};

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

		const input = screen.getByLabelText("rememberMe");
		expect(input).toBeTruthy();
		fireEvent.click(input);
		expect(handleRememberMeMock).toBeCalledTimes(1);
	});

	it("should change input type on button click", () => {
		const defaultProps: ILoginProps = {
			handleSubmit: jest.fn((e) => e.preventDefault()),
			email: "hola@secuoyas.com",
			handleEmail: jest.fn(),
			password: "",
			handlePassword: jest.fn(),
			isLoggingIn: false,
			settings,
			rememberMe: false,
			handleRememberMe: jest.fn(),
		};

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

		const input = screen.getByLabelText("password");
		expect(input).toBeTruthy();
		expect(input).toHaveAttribute("type", "password");

		const button = screen.getByTestId("icon-component-view");
		expect(button).toBeTruthy();
		fireEvent.click(button);

		expect(input).toHaveAttribute("type", "text");
	});
});

describe("Recovery Modal rendering", () => {
	it("should render the recovery modal on button click", () => {
		const defaultProps: ILoginProps = {
			handleSubmit: jest.fn(),
			email: "",
			handleEmail: jest.fn(),
			password: "",
			handlePassword: jest.fn(),
			isLoggingIn: false,
			settings,
			rememberMe: false,
			handleRememberMe: jest.fn(),
		};

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

		const modalClosed = screen.queryByTestId("recovery-modal-content");
		expect(modalClosed).toBeFalsy();

		const button = screen.getByTestId("forgot-button");
		expect(button).toBeTruthy();
		fireEvent.click(button);

		const modal = screen.getByTestId("recovery-modal-content");
		expect(modal).toBeTruthy();
	});
});
