<template>
    <Dialog v-model:visible="dialogCodeVisible" modal :header="'Class detail: ' + selectionNode.fullyQualifiedClassName" class="change-modal" :style="{ width: '70vw', minHeight: '75vh' }">
        <SingleClassViewer v-if="dialogCodeVisible" :className="selectionNode.fullyQualifiedClassName" />
    </Dialog>

    <div>
        <VueFlow :nodes="nodes" :edges="edges" class="basic-flow" :default-viewport="{ zoom: 1.5 }" :min-zoom="0.2" :max-zoom="4" @nodes-initialized="layoutGraph('LR')">
            <template #node-class-node="props">
                <ClassNode v-bind="props" />
            </template>

            <Background pattern-color="#aaa" :gap="16" />

            <MiniMap />

            <Controls position="top-left"> </Controls>
        </VueFlow>
    </div>
</template>

<script setup>
import { Background } from '@vue-flow/background';
import { Controls } from '@vue-flow/controls';
import { VueFlow, useVueFlow } from '@vue-flow/core';
import { MiniMap } from '@vue-flow/minimap';
import Dialog from 'primevue/dialog';
import { nextTick, onMounted, ref, toRefs, watch } from 'vue';
import ClassNode from './ClassNode.vue';
import { useLayout } from './useLayout';

import axios from 'axios';
import { defineProps } from 'vue';
import 'vue3-markdown/dist/style.css';

const { onInit, onNodeDragStop, onConnect, addEdges, setViewport, toObject, onNodeClick, fitView } = useVueFlow();

const nodes = ref(null);
const edges = ref(null);
const dark = ref(false);
const selectionNode = ref({ fullyQualifiedClassName: '', description: '' });
const { graph, layout, previousDirection } = useLayout();

const dialogCodeVisible = ref(false);
const props = defineProps({ file: { type: String, required: true }, application: { type: String, required: true } });

const { file } = toRefs(props);
const fileDetails = ref(null);

onMounted(() => {
    //defineNodes()
});

watch(
    () => props.file,
    (first, second) => {
        loadFileDetails(first);
    }
);

onInit((vueFlowInstance) => {
    vueFlowInstance.fitView();
});

function loadFileDetails(filename) {
    let fileInfo = { filename: filename, applicationName: props.application };

    axios.post('/source-module/getFileSimpleInfo', fileInfo).then((response) => {
        fileDetails.value = response.data;
        defineNodes();
    });
}

onNodeClick(({ event, nodes, node }) => {
    console.log(node);
    if (node.type == 'class-node') {
        selectionNode.value = node.data.data;
        dialogCodeVisible.value = true;
    }
});

function layoutGraph(direction) {
    nodes.value = layout(nodes.value, edges.value, direction);
    nextTick(() => {
        fitView();
    });
}

function defineNodes() {
    var tmpNode = [];
    var tmpEdges = [];
    var filename = fileDetails.value.filename.split('\\').slice(-1)[0].split('/').slice(-1)[0];

    tmpNode.push({ id: filename, data: { label: filename }, position: { x: 250, y: 0 }, class: 'light' });

    fileDetails.value.classes.forEach((c) => {
        tmpNode.push({ id: c.name, data: { label: c.name.split('.').slice(-1)[0], data: { fullyQualifiedClassName: c.name } }, position: { x: 250, y: 0 }, class: 'light', type: 'class-node' });
        tmpEdges.push({ id: filename + c.name, source: filename, target: c.name });
    });

    nodes.value = tmpNode;
    edges.value = tmpEdges;
    layoutGraph('LR');
}
</script>

<style>
@import '@vue-flow/core/dist/style.css';
@import '@vue-flow/core/dist/theme-default.css';
@import '@vue-flow/controls/dist/style.css';
@import '@vue-flow/minimap/dist/style.css';

.basic-flow {
    height: 90vh;
    width: 100%;
}

.vue-flow__minimap {
    transform: scale(75%);
    transform-origin: bottom right;
}

.basic-flow.dark {
    background: #2d3748;
    color: #fffffb;
}

.basic-flow.dark .vue-flow__node {
    background: #4a5568;
    color: #fffffb;
}

.basic-flow.dark .vue-flow__node.selected {
    background: #333;
    box-shadow: 0 0 0 2px #2563eb;
}

.basic-flow .vue-flow__controls {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
}

.basic-flow.dark .vue-flow__controls {
    border: 1px solid #fffffb;
}

.basic-flow .vue-flow__controls .vue-flow__controls-button {
    border: none;
    border-right: 1px solid #eee;
}

.basic-flow.dark .vue-flow__controls .vue-flow__controls-button:hover {
    background: #4d4d4d;
}

.basic-flow.dark .vue-flow__edge-textbg {
    fill: #292524;
}

.basic-flow.dark .vue-flow__edge-text {
    fill: #fffffb;
}

.vue-flow__node-default {
    border: 1px solid #292524;
    padding: 10px;
    border-radius: 5px;
    background: #f5f5f5;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    max-width: 250px;
    min-width: 200px;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.vue-flow__node-class-node {
    border: 1px solid #a100ff;
    padding: 10px;
    border-radius: 5px;
    background: #f5f5f5;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    max-width: 250px;
    min-width: 200px;
    word-wrap: break-word;
    overflow-wrap: break-word;
}
</style>
