<script setup lang="ts">
const rect = useSelectionRect();
const warrenStore = useWarrenStore();

const left = computed(() => Math.min(rect.a.x, rect.b.x));
const top = computed(() => Math.min(rect.a.y, rect.b.y));
const width = computed(() => Math.abs(rect.a.x - rect.b.x));
const height = computed(() => Math.abs(rect.a.y - rect.b.y));

function onDocumentPointerDown(e: MouseEvent) {
    if (e.button !== 0) {
        return;
    }

    const point = { x: e.x, y: e.y };
    rect.set(
        point,
        point,
        !e.shiftKey ? 'set' : e.ctrlKey ? 'subtract' : 'add'
    );
}

function onDocumentPointerMove(e: MouseEvent) {
    if (!rect.enabled) {
        return;
    }

    rect.updateB(e.x, e.y);

    if (
        rect.mode !== 'set' ||
        warrenStore.selection.size === 0 ||
        !rect.isMinSize()
    ) {
        return;
    }

    warrenStore.clearSelection();
}

function onDocumentPointerUp(e: MouseEvent) {
    if (e.button !== 0 || !rect.enabled) {
        return;
    }

    const left = Math.min(rect.a.x, rect.b.x);
    const top = Math.min(rect.a.y, rect.b.y);
    const width = Math.abs(rect.a.x - rect.b.x);
    const height = Math.abs(rect.a.y - rect.b.y);
    const selectionRect = new DOMRect(left, top, width, height);

    const isMinSize = rect.isMinSize();

    rect.disable();

    if (warrenStore.current == null || warrenStore.current.dir == null) {
        return;
    }

    if (!isMinSize) {
        warrenStore.clearSelection();
        return;
    }

    const entryElements = document.querySelectorAll('[data-entry-index]');

    const targetEntries = [];

    for (const entry of entryElements) {
        const attributeValue = entry.getAttribute('data-entry-index');
        if (attributeValue == null) {
            continue;
        }

        const index = parseInt(attributeValue);
        if (isNaN(index)) {
            continue;
        }

        const entryRect = entry.getBoundingClientRect();
        if (intersectRect(selectionRect, entryRect)) {
            targetEntries.push(warrenStore.current.dir.entries[index]);
        }
    }

    if (rect.mode === 'set') {
        warrenStore.setSelection(targetEntries);
    } else if (rect.mode === 'add') {
        warrenStore.addMultipleToSelection(targetEntries);
    } else if (rect.mode === 'subtract') {
        warrenStore.removeMultipleFromSelection(targetEntries);
    }
}

onMounted(() => {
    document.addEventListener('pointerdown', onDocumentPointerDown);
    document.addEventListener('pointermove', onDocumentPointerMove);
    document.addEventListener('pointerup', onDocumentPointerUp);
});
onBeforeUnmount(() => {
    document.removeEventListener('pointerdown', onDocumentPointerDown);
    document.removeEventListener('pointermove', onDocumentPointerMove);
    document.removeEventListener('pointerup', onDocumentPointerUp);
});
</script>

<template>
    <div
        v-if="rect.enabled && rect.isMinSize()"
        :class="[
            'pointer-events-none absolute z-50',
            rect.mode === 'set' && 'bg-primary/20',
            rect.mode === 'add' && 'bg-green-300/20',
            rect.mode === 'subtract' && 'bg-destructive/20',
        ]"
        :style="`left: ${left}px; top: ${top}px; width: ${width}px; height: ${height}px;`"
    ></div>
</template>
