<script setup>
import axios from 'axios';
import { onMounted, ref, reactive } from 'vue';
import { useI18n } from 'vue-i18n';
import { QSeparator, useQuasar } from 'quasar';
import { useRoute } from 'vue-router';
import { useNavigationStore } from 'src/stores/useNavigationStore';
import { toLowerCamel } from 'src/filters';
import routes from 'src/router/modules';
import LeftMenuItem from './LeftMenuItem.vue';
import LeftMenuItemGroup from './LeftMenuItemGroup.vue';

const { t } = useI18n();
const route = useRoute();
const quasar = useQuasar();
const navigation = useNavigationStore();

const props = defineProps({
    source: {
        type: String,
        default: 'main',
    },
});

const expansionItemElements = reactive({});

onMounted(async () => {
    await navigation.fetchPinned();
    getRoutes();
});

function findMatches(search, item) {
    const matches = [];
    function findRoute(search, item) {
        for (const child of item.children) {
            if (search?.indexOf(child.name) > -1) {
                matches.push(child);
            } else if (child.children) {
                findRoute(search, child);
            }
        }
    }

    findRoute(search, item);

    return matches;
}

function addChildren(module, route, parent) {
    if (route.menus) {
        const mainMenus = route.menus[props.source];
        const matches = findMatches(mainMenus, route);

        for (const child of matches) {
            navigation.addMenuItem(module, child, parent);
        }
    }
}

const items = ref([]);

function getRoutes() {
    if (props.source === 'main') {
        const modules = Object.assign([], navigation.getModules().value);

        for (const item of modules) {
            const moduleDef = routes.find(
                (route) => toLowerCamel(route.name) === item.module
            );
            if (!moduleDef) continue;
            item.children = [];

            addChildren(item.module, moduleDef, item.children);
        }

        items.value = modules;
    }

    if (props.source === 'card') {
        const currentRoute = route.matched[1];
        const currentModule = toLowerCamel(currentRoute.name);
        const moduleDef = routes.find(
            (route) => toLowerCamel(route.name) === currentModule
        );

        if (!moduleDef) return;

        addChildren(currentModule, moduleDef, items.value);
    }
}

async function togglePinned(item, event) {
    if (event.defaultPrevented) return;
    event.preventDefault();
    event.stopPropagation();

    const data = { moduleName: item.module };
    const response = await axios.post('StarredModules/toggleStarredModule', data);

    item.isPinned = false;

    if (response.data && response.data.id) {
        item.isPinned = true;
    }

    navigation.togglePinned(item.module);

    quasar.notify({
        message: t('globals.dataSaved'),
        type: 'positive',
    });
}

const handleItemExpansion = (itemName) => {
    expansionItemElements[itemName].scrollToLastElement();
};
</script>

<template>
    <QList padding class="column-max-width">
        <template v-if="$props.source === 'main'">
            <template v-if="$route?.matched[1]?.name === 'Dashboard'">
                <QItem class="header">
                    <QItemSection avatar>
                        <QIcon name="view_module" />
                    </QItemSection>
                    <QItemSection> {{ t('globals.modules') }}</QItemSection>
                </QItem>
                <QSeparator />
                <template v-for="item in items" :key="item.name">
                    <template v-if="item.children">
                        <LeftMenuItem :item="item" group="modules">
                            <template #side>
                                <QBtn
                                    v-if="item.isPinned === true"
                                    @click="togglePinned(item, $event)"
                                    icon="remove_circle"
                                    size="xs"
                                    flat
                                    round
                                >
                                    <QTooltip>
                                        {{ t('components.leftMenu.removeFromPinned') }}
                                    </QTooltip>
                                </QBtn>
                                <QBtn
                                    v-if="item.isPinned === false"
                                    @click="togglePinned(item, $event)"
                                    icon="push_pin"
                                    size="xs"
                                    flat
                                    round
                                >
                                    <QTooltip>
                                        {{ t('components.leftMenu.addToPinned') }}
                                    </QTooltip>
                                </QBtn>
                            </template>
                        </LeftMenuItem>
                    </template>
                </template>
            </template>

            <template v-for="item in items" :key="item.name">
                <template v-if="item.name === $route?.matched[1]?.name">
                    <QItem class="header">
                        <QItemSection avatar v-if="item.icon">
                            <QIcon :name="item.icon" />
                        </QItemSection>
                        <QItemSection avatar v-if="!item.icon">
                            <QIcon name="disabled_by_default" />
                        </QItemSection>
                        <QItemSection>{{ t(item.title) }}</QItemSection>
                        <QItemSection side>
                            <slot name="side" :item="item" />
                        </QItemSection>
                    </QItem>
                    <QSeparator />
                    <template v-if="item.children">
                        <LeftMenuItemGroup :item="item" group="modules">
                            <template #side>
                                <QBtn
                                    v-if="item.isPinned === true"
                                    @click="togglePinned(item, $event)"
                                    icon="remove_circle"
                                    size="xs"
                                    flat
                                    round
                                >
                                    <QTooltip>
                                        {{ t('components.leftMenu.removeFromPinned') }}
                                    </QTooltip>
                                </QBtn>
                                <QBtn
                                    v-if="item.isPinned === false"
                                    @click="togglePinned(item, $event)"
                                    icon="push_pin"
                                    size="xs"
                                    flat
                                    round
                                >
                                    <QTooltip>
                                        {{ t('components.leftMenu.addToPinned') }}
                                    </QTooltip>
                                </QBtn>
                            </template>
                        </LeftMenuItemGroup>
                    </template>
                </template>
            </template>
        </template>
        <template v-if="$props.source === 'card'">
            <template v-for="item in items" :key="item.name">
                <LeftMenuItem v-if="!item.children" :item="item" />
                <QList v-else>
                    <QExpansionItem
                        v-ripple
                        clickable
                        :icon="item.icon"
                        :label="t(item.title)"
                        :content-inset-level="0.5"
                        @after-show="handleItemExpansion(item.name)"
                    >
                        <LeftMenuItemGroup
                            :ref="(el) => (expansionItemElements[item.name] = el)"
                            :item="item"
                        />
                    </QExpansionItem>
                </QList>
            </template>
        </template>
    </QList>
</template>

<style scoped>
.pinned .q-btn {
    visibility: hidden;
}

.pinned:hover .q-btn {
    visibility: visible;
}
.column-max-width {
    max-width: 256px;
}
.header {
    color: var(--vn-label-color);
}
</style>
