<template>
    <div class="absolute overflow-visible h-px w-px">
        <div v-if="edge.label" :style="{ transform: labelPos }" class="relative bg-light-20 dark:bg-dark-20 border border-light-35 dark:border-dark-35 px-4 py-2 -translate-x-[50%] -translate-y-[50%]">{{ edge.label }}</div>
        <input v-else-if="editing" @click="e => e.stopImmediatePropagation()" :style="{ transform: `${labelPos} translate(-50%, -50%)` }" class="relative bg-light-20 dark:bg-dark-20 border border-light-35 dark:border-dark-35 px-4 py-2 z-20" :v-model="edge.label" />
        <svg ref="dom" class="absolute top-0 overflow-visible h-px w-px" @click="select" @dblclick="edit">
            <g :style="{'--canvas-color': edge.color?.hex}" class="z-0">
                <path :style="`stroke-linecap: butt; stroke-width: calc(3px * var(--zoom-multiplier));`" :class="[edge.color?.class ? `stroke-light-${edge.color.class} dark:stroke-dark-${edge.color.class}` : ((edge.color && edge.color?.hex !== undefined) ? 'stroke-[color:var(--canvas-color)]' : 'stroke-light-40 dark:stroke-dark-40'), { 'outline-4': focusing }]" class="fill-none stroke-[4px]" :d="path!.path"></path>
                <g :style="`transform: translate(${path!.to.x}px, ${path!.to.y}px) scale(var(--zoom-multiplier)) rotate(${rotation[path!.side]}deg);`">
                    <polygon :class="edge.color?.class ? `fill-light-${edge.color.class} dark:fill-dark-${edge.color.class}` : ((edge.color && edge.color?.hex !== undefined) ? 'fill-[color:var(--canvas-color)]' : 'fill-light-40 dark:fill-dark-40')" points="0,0 6.5,10.4 -6.5,10.4"></polygon>
                </g>
            </g>
        </svg>                    
    </div>
</template>

<script setup lang="ts">
import { getPath, labelCenter, type Direction } from '#shared/canvas.util';
import type { Element } from '../CanvasEditor.vue';
import type { CanvasEdge, CanvasNode } from '~/types/canvas';

const rotation: Record<Direction, string> = {
    top: "180",
    bottom: "0",
    left: "90",
    right: "270"
};

const { edge, nodes } = defineProps<{
    edge: CanvasEdge
    nodes: CanvasNode[]
}>();

const emit = defineEmits<{
    (e: 'select', id: Element): void,
    (e: 'edit', id: Element): void,
    (e: 'move', id: string, from: string, to: string): void,
}>();

const dom = useTemplateRef('dom');
const focusing = ref(false), editing = ref(false);

const from = computed(() => nodes!.find(f => f.id === edge.fromNode))
const to = computed(() => nodes!.find(f => f.id === edge.toNode));
const path = computed(() => getPath(from.value!, edge.fromSide, to.value!, edge.toSide));
const labelPos = computed(() => labelCenter(from.value!, edge.fromSide, to.value!, edge.toSide));

function select(e: Event) {
    if(editing.value)
        return;

    focusing.value = true;
    emit('select', { type: 'edge', id: edge.id });
}
function edit(e: Event) {
    focusing.value = true;
    editing.value = true;

    e.stopImmediatePropagation();
    emit('edit', { type: 'edge', id: edge.id });
}
function unselect() {
    focusing.value = false;
    editing.value = false;
}

defineExpose({ unselect, dom, id: edge.id });
</script>