import React, { useState } from "react";
import { connect } from "react-redux";
import { AnimateLayoutChanges, useSortable } from "@dnd-kit/sortable";

import { menuActions } from "@ax/containers/Navigation";
import { useModal, usePermission } from "@ax/hooks";
import { IMenuItem } from "@ax/types";
import { Icon, IconAction, Tooltip } from "@ax/components";

import SidePanel from "./../SidePanel";
import ConfigPanel from "./../ConfigPanel";
import { RemoveModal } from "./atoms";

import * as S from "./style";

const Item = (props: IItemProps): JSX.Element => {
	const {
		item,
		deleteMenuItem,
		resetItemValues,
		setItemValue,
		updateFormValue,
		depth,
		indentationWidth,
		collapsed,
		onCollapse,
	} = props;

	const deleteItem = (item: IMenuItem, deleteChildren?: boolean) => deleteMenuItem(item.id, deleteChildren);
	const hasChildren = !!item.children.length;

	const isAllowedToMangageMenus = usePermission("navigation.manageSiteMenu");

	const removeItemAction = () => (hasChildren ? toggleRemoveModal() : deleteItem(item));

	const actionMenuOptions = [
		{
			label: "Delete",
			icon: "delete",
			action: removeItemAction,
		},
	];

	const { isOpen, toggleModal } = useModal(false);
	const { isOpen: isRemoveOpen, toggleModal: toggleRemoveModal } = useModal(false);
	const [isOpenedSecond, setIsOpenedSecond] = useState(false);
	const { isOpen: isConfigOpen, toggleModal: toggleConfigModal } = useModal(false);

	const animateLayoutChanges: AnimateLayoutChanges = ({ isSorting, wasDragging }) =>
		isSorting || wasDragging ? false : true;

	const { attributes, isDragging, listeners, setDraggableNodeRef, setDroppableNodeRef, transform, transition } =
		useSortable({
			id: item.id,
			animateLayoutChanges,
		});

	const handleIconClick = (e: React.MouseEvent<HTMLDivElement>) => e.stopPropagation();

	const toggleSecondaryPanel = () => setIsOpenedSecond(!isOpenedSecond);
	const resetValues = () => resetItemValues();

	const setItem = (item: IMenuItem) => {
		const { config, ...rest } = item;
		const type = config ? config.type : "link";
		const headerStyle = config ? config.headerStyle : "";
		const footerStyle = config ? config.footerStyle : "";
		setItemValue(item);
		updateFormValue({ type });
		updateFormValue({ headerStyle });
		updateFormValue({ footerStyle });
		updateFormValue(rest);
	};

	const openModal = () => {
		if (!isDragging) {
			resetValues();
			setItem(item);
			setIsOpenedSecond(false);
			toggleModal();
		}
	};

	const openConfigModal = () => {
		resetValues();
		setItem(item);
		toggleConfigModal();
	};

	const isGroupingElement = item.config !== null && item.config.type === "group";

	return (
		<>
			<S.Container
				disabled={!isAllowedToMangageMenus}
				identationWidth={isDragging ? indentationWidth : indentationWidth * depth}
				ref={setDroppableNodeRef}
			>
				<S.Component
					onClick={openModal}
					isGroup={isGroupingElement}
					ref={setDraggableNodeRef}
					cssTransform={transform}
					transition={transition}
					{...listeners}
					{...attributes}
				>
					<S.FlexWrapper>
						<S.IconWrapperDrag>
							<Icon name="drag" size="16" />
						</S.IconWrapperDrag>
						{isGroupingElement && (
							<S.GroupIcon>
								<Icon name="unlink" size="16" />
							</S.GroupIcon>
						)}
						{item.label}
					</S.FlexWrapper>
					<S.FlexWrapper>
						{onCollapse && (
							<S.IconWrapper onClick={handleIconClick}>
								{collapsed ? (
									<IconAction icon="UpArrow" size="m" onClick={onCollapse} />
								) : (
									<IconAction icon="DownArrow" size="m" onClick={onCollapse} />
								)}
							</S.IconWrapper>
						)}
						{depth === 1 && hasChildren && isAllowedToMangageMenus && (
							<S.IconWrapper>
								<Tooltip content="Options view">
									<IconAction icon="settings" size="m" onClick={openConfigModal} />
								</Tooltip>
							</S.IconWrapper>
						)}
						{isAllowedToMangageMenus && <S.StyledActionMenu options={actionMenuOptions} icon="more" />}
					</S.FlexWrapper>
				</S.Component>
				{isOpen && (
					<SidePanel
						isOpen={isOpen}
						isOpenedSecond={isOpenedSecond}
						toggleModal={toggleModal}
						toggleSecondaryPanel={toggleSecondaryPanel}
						edit={true}
					/>
				)}
				{isConfigOpen && <ConfigPanel isOpen={isConfigOpen} toggleModal={toggleConfigModal} />}
			</S.Container>
			<RemoveModal isOpen={isRemoveOpen} toggleModal={toggleRemoveModal} deleteItem={deleteItem} item={item} />
		</>
	);
};

interface IProps {
	item: IMenuItem;
	depth: number;
	indentationWidth: number;
	collapsed: boolean;
	onCollapse?: () => void;
}

interface IDispatchProps {
	deleteMenuItem(itemId: number, deleteChildren?: boolean): void;
	resetItemValues(): void;
	setItemValue(value: IMenuItem): void;
	updateFormValue(value: any): void;
}

const mapDispatchToProps = {
	deleteMenuItem: menuActions.deleteMenuItem,
	resetItemValues: menuActions.resetItemValues,
	setItemValue: menuActions.setItemValue,
	updateFormValue: menuActions.updateFormValue,
};

type IItemProps = IProps & IDispatchProps;

const ConnectedItem = connect(null, mapDispatchToProps)(Item);

export default ConnectedItem;
