import { useState } from "react";
import { connect } from "react-redux";

import type { ICheck, ILanguage, INavigationLanguage, INavigation } from "@ax/types";
import { useModal, usePermission } from "@ax/hooks";
import { appActions } from "@ax/containers/App";
import { navigationActions, menuActions } from "@ax/containers/Navigation";
import { CheckField, FieldsBehavior, Modal } from "@ax/components";

import { Translations } from "./atoms";

import * as S from "./style";

const DefaultItem = (props: IProps): JSX.Element => {
	const {
		defaultContent,
		lang,
		languages,
		updateNavigation,
		deleteNavigation,
		setDefaultNavigation,
		handleClick,
		setHistoryPush,
		setLanguage,
		createNewTranslation,
		setHeader,
		setFooter,
		toggleToast,
		setDeletedNav,
		onChange,
		isSelected,
		toggleReplaceModal,
		getMenus,
		hoverCheck,
	} = props;

	const [inputValue, setInputValue] = useState("");

	const { isOpen: isRenameOpened, toggleModal: toggleRenameModal } = useModal();
	const { isOpen: isDefaultOpened, toggleModal: toggleDefaultModal } = useModal();

	const { locale } = lang;
	const { navigationLanguages, type } = defaultContent;

	const isAllowedToEditHeaders = usePermission("navigation.editSiteHeaders") && type === "header";
	const isAllowedToEditFooters = usePermission("navigation.editSiteFooters") && type === "footer";
	const isAllowedToCreateHeaders = usePermission("navigation.createSiteHeaders") && type === "header";
	const isAllowedToCreateFooters = usePermission("navigation.createSiteFooters") && type === "footer";
	const isAllowedToDeleteHeaders = usePermission("navigation.deleteSiteHeaders") && type === "header";
	const isAllowedToDeleteFooters = usePermission("navigation.deleteSiteFooters") && type === "footer";

	const goToEditor = () => {
		handleClick(defaultContent);
		setHistoryPush("/sites/navigations/editor", true);
	};

	const handleOnChange = (value: ICheck) => onChange(value);

	const handleRenameItem = () => {
		const updatedItem = { ...defaultContent, title: inputValue };
		updateNavigation(defaultContent.id!, updatedItem);
	};

	const handleSetDefault = () => setDefaultNavigation(defaultContent.id!, defaultContent.type);

	const handleErrorAction = () => toggleReplaceModal();

	const removeItem = async () => {
		const deleted = await deleteNavigation(defaultContent.id!, defaultContent.type, handleErrorAction);
		setDeletedNav(defaultContent.id!);
		if (deleted) {
			toggleToast();
		}
	};

	const renameOption =
		isAllowedToEditFooters || isAllowedToEditHeaders
			? {
					label: "Rename",
					icon: "edit",
					action: toggleRenameModal,
				}
			: undefined;

	const deleteOption =
		isAllowedToDeleteFooters || isAllowedToDeleteHeaders
			? {
					label: "Delete",
					icon: "delete",
					action: removeItem,
				}
			: undefined;

	const setAsDefaultOption =
		!defaultContent.setAsDefault && (isAllowedToEditHeaders || isAllowedToEditFooters)
			? {
					label: "Set as default",
					icon: "modules",
					action: toggleDefaultModal,
				}
			: undefined;

	const menuOptions = [setAsDefaultOption, renameOption, deleteOption];

	const getCurrentLanguages = () => {
		const availables: ILanguage[] = [];
		navigationLanguages.forEach((navLang) => {
			languages?.forEach((siteLang) => {
				if (siteLang.id === navLang.languageId) {
					availables.push(siteLang);
				}
			});
		});

		return availables;
	};

	const currentLanguages = getCurrentLanguages();

	const handleCloseModal = () => {
		setInputValue("");
		toggleRenameModal();
	};

	const mainRenameModalAction = { title: "Rename", onClick: handleRenameItem, disabled: !inputValue.trim() };
	const secondaryRenameModalAction = { title: "Cancel", onClick: handleCloseModal };

	const mainDefaultModalAction = { title: "Yes, set as default", onClick: handleSetDefault };
	const secondaryDefaultModalAction = { title: "Cancel", onClick: toggleDefaultModal };

	const getSelectedNavLanguage = (navLanguages: INavigationLanguage[], language: ILanguage) =>
		navLanguages.find((navLang) => navLang.languageId === language.id);

	const handleLanguage = async (language: ILanguage) => {
		await setLanguage({ locale: language.locale, id: language.id });

		const isHeader = type === "header";
		const setNav = (id: number) => (isHeader ? setHeader(id) : setFooter(id));
		const selectedNavLanguage = getSelectedNavLanguage(navigationLanguages, language);

		setNav(selectedNavLanguage?.navigationId ?? defaultContent.id!);

		if (!selectedNavLanguage) {
			createNewTranslation(true);
		}

		await getMenus();
		setHistoryPush("/sites/navigations/editor", true);
	};

	const availableLanguages = isAllowedToCreateFooters || isAllowedToCreateHeaders ? languages : currentLanguages;

	return (
		<>
			<S.DefaultRow role="rowgroup" selected={isSelected} clickable={isAllowedToEditHeaders || isAllowedToEditFooters}>
				<S.CheckCell role="cell">
					<CheckField
						name="check"
						value={defaultContent.id!}
						checked={isSelected || hoverCheck}
						onChange={handleOnChange}
					/>
				</S.CheckCell>
				<S.NameCell role="cell" onClick={goToEditor}>
					{defaultContent.title}
				</S.NameCell>
				<S.TransCell role="cell">
					<Translations
						handleLanguage={handleLanguage}
						currentLanguages={currentLanguages}
						locale={locale}
						languages={availableLanguages}
					/>
				</S.TransCell>
				<S.DefaultCell role="cell" onClick={goToEditor}>
					{defaultContent.setAsDefault && "Default"}
				</S.DefaultCell>
				<S.ActionCell role="cell">
					<S.StyledActionMenu icon="more" options={menuOptions} />
				</S.ActionCell>
			</S.DefaultRow>
			<Modal
				isOpen={isRenameOpened}
				hide={handleCloseModal}
				title={`Rename ${defaultContent.component}`}
				secondaryAction={secondaryRenameModalAction}
				mainAction={mainRenameModalAction}
				size="S"
			>
				{isRenameOpened ? (
					<S.ModalContent>
						<FieldsBehavior
							fieldType="TextField"
							name="name"
							title="Name"
							mandatory={true}
							value={inputValue}
							onChange={setInputValue}
							placeholder={`Type a new name for the ${defaultContent.type}`}
						/>
					</S.ModalContent>
				) : null}
			</Modal>
			<Modal
				isOpen={isDefaultOpened}
				hide={toggleDefaultModal}
				title={`Default ${defaultContent.component}`}
				secondaryAction={secondaryDefaultModalAction}
				mainAction={mainDefaultModalAction}
				size="S"
			>
				{isDefaultOpened ? (
					<S.ModalContent>
						<p>
							There is already a header defined as default. If you change it to this one, it will be shown on all the
							pages on this site. Are you sure your want to make this change?
						</p>
					</S.ModalContent>
				) : null}
			</Modal>
		</>
	);
};

interface IProps {
	defaultContent: INavigation;
	languages: ILanguage[];
	lang: { locale: string; id: number | null };
	handleClick: (e: any) => void;
	setHistoryPush(path: string, isEditor?: boolean): any;
	updateNavigation(navID: number, data: INavigation): void;
	isSelected: boolean;
	toggleToast(): void;
	onChange: (e: any) => void;
	setDeletedNav(item: number): void;
	deleteNavigation(navID: number, type: string, errorAction: () => void): Promise<boolean>;
	setDefaultNavigation(navID: number, type: string): void;
	setLanguage(lang: { locale: string; id: number | null }): void;
	createNewTranslation(isNewTranslation: boolean): void;
	setHeader(id: number | null): void;
	setFooter(id: number | null): void;
	toggleReplaceModal: () => void;
	getMenus(): Promise<void>;
	hoverCheck: boolean;
}

const mapDispatchToProps = {
	updateNavigation: navigationActions.updateNavigation,
	deleteNavigation: navigationActions.deleteNavigation,
	setDefaultNavigation: navigationActions.setDefaultNavigation,
	setLanguage: appActions.setLanguage,
	createNewTranslation: navigationActions.createNewTranslation,
	setHeader: navigationActions.setHeader,
	setFooter: navigationActions.setFooter,
	getMenus: menuActions.getMenus,
};

export default connect(null, mapDispatchToProps)(DefaultItem);
