<script lang="ts" setup>
import { computed } from 'vue';
import { Link, usePage } from '@inertiajs/vue3';
import { StyleService } from '@/Stores/style.service';
import { mdiMinus, mdiPlus } from '@mdi/js';
import { getButtonColor } from '@/colors';
import BaseIcon from '@/Components/BaseIcon.vue';
import { stardust } from '@eidellev/adonis-stardust/client';
import type { User } from '@/Dataset';
import { MenuItem } from '@headlessui/vue';

interface MenuItem {
    href?: string;
    route?: string;
    icon?: string;
    label: string;
    target?: string;
    color?: string;
    children?: MenuItem[];
    isOpen?: boolean;
    roles?: string[];
}

const props = defineProps<{
    item: MenuItem;
    parentItem?: MenuItem;
    // isDropdownList?: boolean;
}>();
const emit = defineEmits<{
    (e: 'menu-click', event: Event, item: MenuItem): void;
}>();

// Retrieve authenticated user from page props
const user = computed<User>(() => usePage().props.authUser as User);

// Check if the menu item has children
const hasChildren = computed(() => {
    return Array.isArray(props.item?.children) && props.item.children.length > 0;
});

const itemRoute = computed(() => (props.item && props.item.route ? stardust.route(props.item.route) : ''));
// const isCurrentRoute = computed(() => (props.item && props.item.route ? stardust.isCurrent(props.item.route): false));

// Determine which element to render based on 'href' or 'route'
const isComponent = computed(() => {
    if (props.item.href) {
        return 'a';
    }
    if (props.item.route) {
        return Link;
    }
    return 'div';
});

// Check if any child route is active
const isChildActive = computed(() => {
    if (props.item.children && props.item.children.length > 0) {
        return props.item.children.some(child => child.route && stardust.isCurrent(child.route));
    }
    return false;
});

// Automatically use prop item.isOpen if set from the parent,
// or if one of its children is active then force open state.
const isOpen = computed(() => {
    return props.item.isOpen || isChildActive.value;
});


const styleService = StyleService();

const hasColor = computed(() => props.item && props.item.color);



// const children = computed(() => {
//     return props.item.children || [];
// });

const componentClass = computed(() => [
    hasChildren ? 'py-3 px-6 text-sm font-semibold' : 'py-3 px-6',
    hasColor.value ? getButtonColor(props.item.color, false, true) : styleService.asideMenuItemStyle,
]);


const menuClick = (event: Event) => {
    emit('menu-click', event, props.item);
    if (hasChildren.value) {
        // Toggle open state if the menu has children
        props.item.isOpen = !props.item.isOpen;
    }
};

const activeStyle = computed(() => {
    if (props.item.route && stardust.isCurrent(props.item.route)) {
        // console.log(props.item.route);
        return 'text-sky-600 font-bold';
    } else {
        return null;
    }
});

const hasRoles = computed(() => {
    if (props.item.roles) {
        // Normalize user roles to strings in case roles are objects
        const userRoles = (user.value.roles || []).map(r =>
            typeof r === 'string' ? r : (r as any).name ?? String(r)
        );
        return userRoles.some(role => props.item.roles?.includes(role));
        // return test;
    }
    return true
});

</script>

<!-- :target="props.item.target ?? null" -->
<template>
    <li v-if="hasRoles">
        <component :is="isComponent" :href="props.item.href ? props.item.href : itemRoute"
            class="flex cursor-pointer dark:text-slate-300 dark:hover:text-white menu-item-wrapper"
            :class="componentClass" @click="menuClick" :target="props.item.target || null">
            <BaseIcon v-if="props.item.icon" :path="props.item.icon" class="flex-none menu-item-icon"
                :class="activeStyle" w="w-16" :size="18" />
            <div class="menu-item-label">
                <span class="grow text-ellipsis line-clamp-1" :class="[activeStyle]">
                    {{ props.item.label }}
                </span>
            </div>
            <!-- Display plus or minus icon if there are child items -->
            <BaseIcon v-if="hasChildren" :path="isOpen ? mdiMinus : mdiPlus" class="flex-none"
                :class="[activeStyle]" w="w-12" />
        </component>
        <!-- Render dropdown -->
        <div class="menu-item-dropdown"
            :class="[styleService.asideMenuDropdownStyle, isOpen ? 'block dark:bg-slate-800/50' : 'hidden']"
            v-if="props.item.children && props.item.children.length > 0">
            <ul>

                <AsideMenuItem v-for="(childItem, index) in (props.item.children as any[])" :key="index" :item="childItem"
                    @menu-click="$emit('menu-click', $event, childItem)" />
            </ul>
        </div>        
    </li>    
</template>

<style>
.menu-item-wrapper {
    display: flex;
    align-items: center;
    cursor: pointer;
}

.menu-item-icon {
    font-size: 2.5rem;
    /* margin-right: 10px; */
}

.menu-item-dropdown {
    /* margin-left: 10px; */
    padding-left: 0.75rem;
}
</style>
