import {Dispatch, ReactElement, RefObject, SetStateAction, useRef} from "react";
import Draggable from "react-draggable";

export interface RackInput {
    id: string,
    objects: [ReactElement[], Dispatch<SetStateAction<ReactElement[]>>],
    canDetach: (ref: RefObject<HTMLDivElement>) => boolean,
    onElementDetached: (ref: RefObject<HTMLDivElement>, el: ReactElement) => void,
}

interface RackItemInput {
    item: ReactElement,
    onTryDetach: (ref: RefObject<HTMLDivElement>, el: ReactElement) => void
}

/**
 * A container of draggable objects
 * */
export function Rack({id, objects, canDetach, onElementDetached}: RackInput) {

    const [rackObjects, setRackObjects] = objects

    return (
        <div id={id} style={{
            display: "flex"
        }}>
            {rackObjects.map(element => (
                <RackItem key={element.key}
                          item={element}
                          onTryDetach={(ref, element) => {
                              if (!canDetach(ref))
                                  return

                              setRackObjects(objects => {
                                  const index = objects.findIndex(o => o.key === element.key)
                                  return objects.toSpliced(index, 1);
                              })

                              onElementDetached(ref, element)
                          }}/>
            ))}
        </div>
    )
}

function RackItem({item, onTryDetach}: RackItemInput) {
    const divRef = useRef<HTMLDivElement>(null);

    return (
        <Draggable
            position={{x: 0, y: 0}}
            nodeRef={divRef}
            onStop={() => onTryDetach(divRef, item)}>
            <div ref={divRef}>
                {item}
            </div>
        </Draggable>
    )
}