<script setup>
import { onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useState } from 'src/composables/useState';
import { useQuasar } from 'quasar';
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
import CreateDepartmentChild from '../CreateDepartmentChild.vue';
import axios from 'axios';
import useNotify from 'src/composables/useNotify.js';
import { useRouter } from 'vue-router';

const quasar = useQuasar();
const { t } = useI18n();
const { notify } = useNotify();
const state = useState();
const router = useRouter();

const treeRef = ref();
const showCreateNodeFormVal = ref(false);
const creationNodeSelectedId = ref(null);
const expanded = ref([]);

const nodes = ref([{ id: null, name: t('Departments'), sons: true, children: [{}] }]);

const fetchedChildrensSet = ref(new Set());

const onNodeExpanded = (nodeKeysArray) => {
    if (!fetchedChildrensSet.value.has(nodeKeysArray.at(-1))) {
        fetchedChildrensSet.value.add(nodeKeysArray.at(-1));
        fetchNodeLeaves(nodeKeysArray.at(-1));
    }

    state.set('Tree', nodeKeysArray);
};

const fetchNodeLeaves = async (nodeKey) => {
    try {
        const node = treeRef.value?.getNodeByKey(nodeKey);

        if (!node || node.sons === 0) return;

        const params = { parentId: node.id };
        const response = await axios.get('/departments/getLeaves', { params });
        if (response.data) {
            node.children = response.data.map((n) => {
                const hasChildrens = n.sons > 0;

                n.children = hasChildrens ? [{}] : null;
                n.clickable = true;
                return n;
            });
        }

        state.set('Tree', node);
    } catch (err) {
        console.error('Error fetching department leaves', err);
        throw new Error();
    }
};

const removeNode = (node) => {
    const { id, parentFk } = node;
    quasar
        .dialog({
            title: t('Are you sure you want to delete it?'),
            message: t('Delete department'),
            ok: {
                push: true,
                color: 'primary',
            },
            cancel: true,
        })
        .onOk(async () => {
            try {
                await axios.post(`/Departments/${id}/removeChild`, id);
                notify(t('department.departmentRemoved'), 'positive');
                await fetchNodeLeaves(parentFk);
            } catch (err) {
                console.error('Error removing department');
            }
        });
};

const showCreateNodeForm = (nodeId) => {
    showCreateNodeFormVal.value = true;
    creationNodeSelectedId.value = nodeId;
};

const onNodeCreated = async () => {
    await fetchNodeLeaves(creationNodeSelectedId.value);
};

onMounted(async (n) => {
    const tree = [...state.get('Tree'), 1];
    const lastStateTree = state.get('TreeState');
    if (tree) {
        for (let n of tree) {
            await fetchNodeLeaves(n);
        }
        expanded.value = tree;

        if (lastStateTree) {
            tree.push(lastStateTree);
            await fetchNodeLeaves(lastStateTree);
        }
    }
    setTimeout(() => {
        if (lastStateTree) {
            document.getElementById(lastStateTree).scrollIntoView();
        }
    }, 1000);
});

function handleEvent(type, event, node) {
    const isParent = node.sons > 0;
    const lastId = isParent ? node.id : node.parentFk;

    switch (type) {
        case 'path':
            state.set('TreeState', lastId);
            node.id && router.push({ path: `/department/department/${node.id}/summary` });
            break;

        case 'tab':
            state.set('TreeState', lastId);
            node.id &&
                window.open(`#/department/department/${node.id}/summary`, '_blank');
            break;

        default:
            node.id &&
                router.push({ path: `#/department/department/${node.id}/summary` });
            break;
    }
}
</script>

<template>
    <QCard class="full-width" style="max-width: 800px">
        <QTree
            ref="treeRef"
            :nodes="nodes"
            node-key="id"
            label-key="name"
            v-model:expanded="expanded"
            @update:expanded="onNodeExpanded($event)"
            :default-expand-all="true"
        >
            <template #default-header="{ node }">
                <div
                    :id="node.id"
                    class="qtr row justify-between full-width q-pr-md cursor-pointer"
                >
                    <div>
                        <span
                            @click="handleEvent('row', $event, node)"
                            class="cursor-pointer"
                        >
                            {{ node.name }}
                            <DepartmentDescriptorProxy :id="node.id" />
                        </span>
                    </div>
                    <div
                        @click.stop.exact="handleEvent('path', $event, node)"
                        @click.ctrl.stop="handleEvent('tab', $event, node)"
                        style="flex-grow: 1; width: 10px"
                    ></div>
                    <div class="row justify-between" style="max-width: max-content">
                        <QIcon
                            v-if="node.id"
                            name="delete"
                            color="primary"
                            size="sm"
                            class="q-pr-xs cursor-pointer"
                            @click.stop="removeNode(node)"
                        >
                            <QTooltip>
                                {{ t('Remove') }}
                            </QTooltip>
                        </QIcon>
                        <QIcon
                            name="add"
                            color="primary"
                            size="sm"
                            class="cursor-pointer"
                            @click.stop="showCreateNodeForm(node.id)"
                        >
                            <QTooltip>
                                {{ t('Create') }}
                            </QTooltip>
                        </QIcon>
                    </div>
                </div>
            </template>
        </QTree>
        <QDialog
            v-model="showCreateNodeFormVal"
            transition-show="scale"
            transition-hide="scale"
        >
            <CreateDepartmentChild
                :parent-id="creationNodeSelectedId"
                @on-data-saved="onNodeCreated()"
            />
        </QDialog>
    </QCard>
</template>

<style lang="scss" scoped>
span {
    color: $primary;
}
</style>
<i18n>
    es:
        Departments: Departamentos
        Remove: Quitar
        Create: Crear
        Are you sure you want to delete it?: ¿Seguro que quieres eliminarlo?
        Delete department: Eliminar departamento
</i18n>