<script>
import { deepFlat } from "@daybrush/utils";
import Selecto from "vue3-selecto";
import Moveable, { MoveableTargetGroupsType } from "vue3-moveable";
import { GroupManager, TargetList } from "@moveable/helper";
import { ref, onMounted } from "vue";

export default {
    components: { Moveable, Selecto },
    setup() {
        const groupManager = new GroupManager([]);
        const targets = ref([]);
        const moveableRef = ref(null);
        const selectoRef = ref(null);
        const cubes = [];
        for (let i = 0; i < 30; ++i) {
            cubes.push(i);
        }
        const setSelectedTargets = (nextTargetes) => {
            selectoRef.value.setSelectedTargets(deepFlat(nextTargetes));
            targets.value = nextTargetes;
        };
        const onClick = () => {
            const nextGroup = groupManager.group(targets.value, true);
            if (nextGroup) {
                targets.value = nextGroup;
            }
        };
        const onClick$0 = () => {
            const nextGroup = groupManager.ungroup(targets.value);
            if (nextGroup) {
                targets.value = nextGroup;
            }
        };
        const onDrag = e => {
            e.target.style.transform = e.transform;
        };
        const onRenderGroup = e => {
            e.events.forEach(ev => {
                ev.target.style.cssText += ev.cssText;
            });
        };
        const onClickGroup = e => {
            if (!e.moveableTarget) {
                setSelectedTargets([]);
                return;
            }
            if (e.isDouble) {
                const childs = groupManager.selectSubChilds(
                    targets.value,
                    e.moveableTarget
                );
                setSelectedTargets(childs.targets());
                return;
            }
            if (e.isTrusted) {
                selectoRef.value.clickTarget(e.inputEvent, e.moveableTarget);
            }
        };
        const onDragStart = e => {
            const moveable = moveableRef.value;
            const target = e.inputEvent.target;
            const flatted = deepFlat(targets.value);
            if (target.tagName === "BUTTON" || moveable.isMoveableElement(target)
                || flatted.some(t => t === target || t.contains(target))
            ) {
                e.stop();
            }
            e.data.startTargets = targets.value;
        };
        const onSelect = e => {
            const { startAdded, startRemoved, isDragStartEnd } = e;
            if (isDragStartEnd) {
                return;
            }
            const nextChilds = groupManager.selectSameDepthChilds(
                e.data.startTargets,
                startAdded,
                startRemoved
            );
            setSelectedTargets(nextChilds.targets());
        };
        const onSelectEnd = e => {
            const {
                isDragStartEnd,
                isClick,
                added,
                removed,
                inputEvent,
            } = e;
            const moveable = moveableRef.value;
            if (isDragStartEnd) {
                inputEvent.preventDefault();
                moveable.waitToChangeTarget().then(() => {
                    moveable.dragStart(inputEvent);
                });
            }
            let nextChilds;
            if (isDragStartEnd || isClick) {
                nextChilds = groupManager.selectCompletedChilds(
                    e.data.startTargets,
                    added,
                    removed
                );
            } else {
                nextChilds = groupManager.selectSameDepthChilds(
                    e.data.startTargets,
                    added,
                    removed
                );
            }
            e.currentTarget.setSelectedTargets(nextChilds.flatten());
            setSelectedTargets(nextChilds.targets());
        };
        onMounted(() => {
            const elements = selectoRef.value.getSelectableElements();
            groupManager.set([], elements);
        });
        return {
            onClick,
            onClick$0,
            moveableRef,
            targets,
            onDrag,
            onRenderGroup,
            onClickGroup,
            selectoRef,
            window,
            onDragStart,
            onSelect,
            onSelectEnd,
            cubes
        };
    }
};
</script>
<template>
    <div class="root">
        <div class="container">
            <button @click="onClick">Group</button>
            &nbsp;
            <button @click="onClick$0">Ungroup</button>
            <Moveable
                ref="moveableRef"
                :draggable="true"
                :rotatable="true"
                :scalable="true"
                :target="targets"
                @drag="onDrag"
                @renderGroup="onRenderGroup"
                @clickGroup="onClickGroup"
            ></Moveable>
            <Selecto
                ref="selectoRef"
                :dragContainer="window"
                :selectableTargets="['.selecto-area .cube']"
                :hitRate="0"
                :selectByClick="true"
                :selectFromInside="false"
                :toggleContinueSelect="['shift']"
                :ratio="0"
                @dragStart="onDragStart"
                @select="onSelect"
                @selectEnd="onSelectEnd"
            ></Selecto>
            <div class="elements selecto-area">
                <div
                    class="cube"
                    :key="i"
                    v-for="i in cubes"
                >{{i}}</div>
            </div>
            <div class="empty elements"></div>
        </div>
    </div>
</template>