import React, { useCallback, useRef } from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { ItemTypes } from '../ItemTypes';
import { __ } from '@wordpress/i18n';
import { head } from 'ramda';
import { klona } from 'klona';

// store
import { storeSet, useStoreValue } from '../../../../store';

// tools
import uniqid from '../../../../helpers/uniqid';

// components
import { Button } from 'primereact/button';
import BuilderElementMeta from './components/BuilderElementMeta';

const BuilderElement = ({ id, name, label, index, bandoStatus }) => {
    const draggingElementId = useStoreValue('draggingElementId');
    const selectedElement = useStoreValue('selectedElement');
    const ref = useRef(null);
    const elements = useStoreValue('formElements');

    const [{ handlerId }, drop] = useDrop({
        accept: ItemTypes.FIELD,
        collect(monitor) {
            return {
                handlerId: monitor.getHandlerId(),
            }
        },
        drop(item, monitor) {
            storeSet('draggingElementId', 0);
            return item;
        },
        hover(item, monitor) {
            if (!ref.current) {
                return
            }
            const dragIndex = item.index

            if (dragIndex > -1) {
                const hoverIndex = index

                if (dragIndex === hoverIndex) {
                    return
                }

                const hoverBoundingRect = ref.current?.getBoundingClientRect()
                const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2
                const clientOffset = monitor.getClientOffset()
                const hoverClientY = clientOffset.y - hoverBoundingRect.top

                if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
                    return
                }

                if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
                    return
                }

                move(dragIndex, hoverIndex, item)
                item.index = hoverIndex
            } else {
                let hoverIndex = index

                const hoverBoundingRect = ref.current?.getBoundingClientRect()
                const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2
                const clientOffset = monitor.getClientOffset()
                const hoverClientY = clientOffset.y - hoverBoundingRect.top;

                if (hoverClientY > hoverMiddleY) {
                    hoverIndex = hoverIndex + 1;
                }

                move(dragIndex, hoverIndex, item)
                item.index = hoverIndex;
            }
        },
    });

    const [{ isDragging }, drag] = useDrag({
        type: ItemTypes.FIELD,
        item: () => {
            return { id, name, index }
        },
        collect: (monitor) => ({
            isDragging: monitor.isDragging(),
        }),
    });

    const move = (dragIndex, hoverIndex, item) => {
        storeSet('moveElement', dragIndex, hoverIndex, item);
    }

    const openSettings = () => {
        storeSet('activeElement', id);
    }

    const selectElement = () => {
        storeSet('selectedElement', id);
    }

    const duplicateElement = useCallback(() => {
        const duplicatedElement = head(elements.filter(o => o.id === id));

        if (duplicatedElement) {
            const copyElement = klona(duplicatedElement);
            copyElement.settings = copyElement.settings.map((o) => {
                if (o.name === 'label') {
                    o.value = `Copy - ${o.value}`
                }
                return o;
            })
            copyElement.id = uniqid();
            const originalIndex = elements.map(o => o.id).indexOf(id);
            const newElements = [...elements].toSpliced(originalIndex + 1, 0, copyElement);
            storeSet('formElements', newElements);
        }
    }, [elements]);

    const remove = () => {
        storeSet('removeElement', id);
    }

    const opacity = isDragging ? 0 : 1;
    drag(drop(ref));

    return (
        draggingElementId === id
            ? <div ref={ref} className="formBuilder__elementNew">
                {__('lascia qui', 'gepafin')}
            </div>
            : <div ref={ref}
                   className={`formBuilder__element${selectedElement === id ? ' selected' : ''}`}
                   style={{ opacity }}
                   onClick={selectElement}
                   data-handler-id={handlerId}>
                <BuilderElementMeta id={id} name={name} label={label}/>
                <div className="actions">
                    <Button icon="pi pi-clone" onClick={duplicateElement} outlined severity="success"/>
                    <Button icon="pi pi-cog" onClick={openSettings} outlined severity="info"/>
                    <Button icon="pi pi-trash" disabled={bandoStatus === 'PUBLISH'} onClick={remove} outlined severity="danger"/>
                </div>
            </div>
    )
}

export default BuilderElement;