import { __assign, __read, __rest } from "tslib";
import React, { useContext, useRef, useState } from "react";
import { IconBrokenArrowRight3, IconBrokenDrag2 } from "@greenatom/icons";
import { useStateProps } from "../../../hooks/useStateProps";
import { TreeWrapper, TreeHeader, IconWrapper, TreeList, Title } from "../../styles";
import { TreeContext } from "../../Tree";
var TreeItem = function (_a) {
    var title = _a.title, children = _a.children, icon = _a.icon, isArrow = _a.isArrow, isActive = _a.isActive, className = _a.className, isDisabled = _a.isDisabled, onClick = _a.onClick, elements = _a.elements, id = _a.id, leadContent = _a.leadContent, setActive = _a.setActive, otherProps = __rest(_a, ["title", "children", "icon", "isArrow", "isActive", "className", "isDisabled", "onClick", "elements", "id", "leadContent", "setActive"]);
    var _b = __read(useStateProps(isArrow), 2), isShown = _b[0], setIsShown = _b[1];
    var _c = __read(useState(false), 2), isHover = _c[0], setIsHover = _c[1];
    var _d = __read(useState(title), 2), titleState = _d[0], setTitleState = _d[1];
    var _e = __read(useState({
        x: 0,
        y: 0
    }), 2), draggedItemPosition = _e[0], setDraggedItemPosition = _e[1];
    var _f = useContext(TreeContext), draggedOverId = _f.draggedOverId, currentlyDraggedId = _f.currentlyDraggedId, isDragAllowed = _f.isDragAllowed, isEditAllowed = _f.isEditAllowed, handleChangeTitle = _f.handleChangeTitle, handleDragStart = _f.handleDragStart, handleDrop = _f.handleDrop, handleDragOver = _f.handleDragOver;
    var dropRef = useRef(handleDrop);
    dropRef.current = handleDrop;
    var dragRef = useRef(false);
    var thisTreeItem = {
        icon: icon,
        className: className,
        children: children,
        id: id,
        isActive: isActive,
        isArrow: isArrow,
        isDisabled: isDisabled,
        title: title
    };
    var isDragging = currentlyDraggedId === id;
    var dragTimer;
    var handleClickShown = function () {
        if (!elements || isDisabled) {
            return;
        }
        setIsShown(!isShown);
    };
    var handleClick = function () {
        onClick === null || onClick === void 0 ? void 0 : onClick(thisTreeItem);
    };
    var handleItemTitleChange = function (newTitle) {
        if (isEditAllowed) {
            setTitleState(newTitle);
        }
    };
    var handleMouseDown = function (e) {
        if (!isDragAllowed) {
            return;
        }
        var target = e.target;
        if (target instanceof HTMLElement) {
            e.preventDefault();
            dragRef.current = true;
            setDraggedItemPosition({ x: e.clientX, y: e.clientY });
            dragTimer = setTimeout(function () {
                if (dragRef.current) {
                    handleDragStart === null || handleDragStart === void 0 ? void 0 : handleDragStart(thisTreeItem);
                }
            }, 200);
            window.addEventListener("mousemove", handleMouseMove);
            window.addEventListener("mouseup", handleMouseUp);
        }
    };
    var handleMouseMove = function (e) {
        if (dragRef.current) {
            setDraggedItemPosition({ x: e.clientX, y: e.clientY });
        }
    };
    var handleMouseUp = function () {
        var _a;
        dragRef.current = false;
        (_a = dropRef.current) === null || _a === void 0 ? void 0 : _a.call(dropRef);
        if (dragTimer) {
            clearTimeout(dragTimer);
        }
        window.removeEventListener("mousemove", handleMouseMove);
        window.removeEventListener("mouseup", handleMouseUp);
    };
    return (React.createElement(TreeWrapper, __assign({ onClick: handleClick, className: className, id: String(id), isDragOver: draggedOverId === id, isDragging: isDragging }, otherProps),
        React.createElement(TreeHeader, { isDisabled: isDisabled, isDragAllowed: isDragAllowed, isAnyDragging: currentlyDraggedId !== undefined, className: "tree_header", isActive: isShown || isActive || false, onClick: handleClickShown, onMouseMove: function () { return !isDisabled && !dragRef.current && setIsHover(true); }, onMouseOut: function () { return !isDisabled && !dragRef.current && setIsHover(false); }, onMouseDown: handleMouseDown, style: isDragging
                ? {
                    left: draggedItemPosition === null || draggedItemPosition === void 0 ? void 0 : draggedItemPosition.x,
                    top: draggedItemPosition === null || draggedItemPosition === void 0 ? void 0 : draggedItemPosition.y
                }
                : undefined, onMouseEnter: function () {
                return !isDisabled && !dragRef.current && (handleDragOver === null || handleDragOver === void 0 ? void 0 : handleDragOver(thisTreeItem));
            } },
            ((elements && (elements === null || elements === void 0 ? void 0 : elements.length) > 0) || isDragging) && (React.createElement(IconWrapper, { isShown: isShown }, isDragging ? (React.createElement(IconBrokenDrag2, { width: 16, height: 16 })) : (React.createElement(IconBrokenArrowRight3, { className: "arrow-icon", width: 16, height: 16 })))),
            !isDragging && leadContent,
            React.createElement(Title, { readOnly: !isEditAllowed || isDragging || currentlyDraggedId !== undefined, disabled: isDisabled, className: "tree-header__title", value: titleState, onClick: function (e) { return e.stopPropagation(); }, onMouseDown: function (e) { return e.stopPropagation(); }, onChange: function (e) { return handleItemTitleChange(e.target.value); }, onBlur: function () { return handleChangeTitle === null || handleChangeTitle === void 0 ? void 0 : handleChangeTitle(thisTreeItem, titleState); } }),
            !isDisabled && icon && (isShown || isHover || isActive) && (React.createElement("div", { className: "tree-header__right-content" }, icon && React.createElement(IconWrapper, null, icon)))),
        isShown && !isDragging && (React.createElement(TreeList, null, elements &&
            elements.length > 0 &&
            elements.map(function (element) { return (React.createElement(TreeItem, { id: element.id, key: element.id || String(element.title), title: element.title, isDisabled: (element === null || element === void 0 ? void 0 : element.isDisabled) === true, isActive: (element === null || element === void 0 ? void 0 : element.isActive) === true || (setActive === null || setActive === void 0 ? void 0 : setActive(element)), isArrow: (element === null || element === void 0 ? void 0 : element.isArrow) === true, leadContent: element === null || element === void 0 ? void 0 : element.leadContent, elements: element === null || element === void 0 ? void 0 : element.elements, icon: element === null || element === void 0 ? void 0 : element.icon, onClick: onClick, setActive: setActive })); })))));
};
export default TreeItem;
