import { Link, usePage } from '@inertiajs/react';

import { userCan, viewPermission } from '@admin/lib/admin-permissions';
import { siteBrandLogoAlt, siteBrandLogoSrc } from '@admin/lib/site-brand-logo';
import { cn } from '@admin/lib/utils';

interface NavItem {
    label: string;
    href: string;
    icon: string;
    routeNames?: string[];
    permission?: string;
}

interface NavSubItem {
    label: string;
    href: string;
    routeNames?: string[];
    permission?: string;
}

interface NavSubmenuItem {
    label: string;
    icon: string;
    routeNames?: string[];
    children: NavSubItem[];
}

const mainNav: NavItem[] = [
    {
        label: 'Dashboard',
        href: route('dashboard'),
        icon: 'ri-home-8-line',
        routeNames: ['dashboard'],
    },
];

const contentNav: Array<NavItem | NavSubmenuItem> = [
    {
        label: 'Sliders',
        href: route('admin.sliders'),
        icon: 'ri-slideshow-line',
        routeNames: ['admin.sliders', 'admin.sliders.create'],
        permission: viewPermission('slider'),
    },
    {
        label: 'Services',
        href: route('admin.services'),
        icon: 'ri-service-line',
        routeNames: ['admin.services', 'admin.services.create'],
        permission: viewPermission('service'),
    },
    {
        label: 'Team',
        icon: 'ri-team-line',
        routeNames: [
            'admin.team.positions',
            'admin.team.positions.create',
            'admin.team.members',
            'admin.team.members.create',
        ],
        children: [
            {
                label: 'Positions',
                href: route('admin.team.positions'),
                routeNames: ['admin.team.positions', 'admin.team.positions.create'],
                permission: viewPermission('team-position'),
            },
            {
                label: 'Members',
                href: route('admin.team.members'),
                routeNames: ['admin.team.members', 'admin.team.members.create'],
                permission: viewPermission('team-member'),
            },
        ],
    },
    {
        label: 'Updates',
        href: route('admin.updates'),
        icon: 'ri-newspaper-line',
        routeNames: ['admin.updates', 'admin.updates.create'],
        permission: viewPermission('update'),
    },
    {
        label: 'Portfolio',
        href: route('admin.portfolios'),
        icon: 'ri-briefcase-line',
        routeNames: ['admin.portfolios', 'admin.portfolios.create'],
        permission: viewPermission('portfolio'),
    },
    {
        label: 'Statistics',
        href: route('admin.statistic-counters'),
        icon: 'ri-bar-chart-2-line',
        routeNames: ['admin.statistic-counters', 'admin.statistic-counters.create'],
        permission: viewPermission('statistic-counter'),
    },
    {
        label: 'About us',
        href: route('admin.about'),
        icon: 'ri-information-line',
        routeNames: ['admin.about'],
        permission: viewPermission('about'),
    },
    {
        label: 'Pricing',
        href: route('admin.pricing-plans'),
        icon: 'ri-price-tag-3-line',
        routeNames: ['admin.pricing-plans', 'admin.pricing-plans.create'],
        permission: viewPermission('pricing-plan'),
    },
    {
        label: 'Testimonials',
        href: route('admin.testimonials'),
        icon: 'ri-chat-quote-line',
        routeNames: ['admin.testimonials', 'admin.testimonials.create'],
        permission: viewPermission('testimonial'),
    },
    {
        label: 'Clients',
        href: route('admin.clients'),
        icon: 'ri-building-line',
        routeNames: ['admin.clients', 'admin.clients.create'],
        permission: viewPermission('client'),
    },
    {
        label: 'Contact Messages',
        href: route('admin.contact-messages'),
        icon: 'ri-mail-line',
        routeNames: ['admin.contact-messages'],
        permission: viewPermission('contact-message'),
    },
    {
        label: 'Sections',
        icon: 'ri-layout-grid-line',
        routeNames: [
            'admin.sections.home',
            'admin.sections.service-page',
            'admin.sections.service-faqs',
            'admin.sections.service-faqs.create',
            'admin.sections.service-details',
            'admin.sections.background-images',
            'admin.partners',
            'admin.partners.create',
        ],
        children: [
            {
                label: 'Home page',
                href: route('admin.sections.home'),
                routeNames: ['admin.sections.home'],
                permission: viewPermission('home-section'),
            },
            {
                label: 'Service page',
                href: route('admin.sections.service-page'),
                routeNames: ['admin.sections.service-page'],
                permission: viewPermission('service-page-section'),
            },
            {
                label: 'FAQ',
                href: route('admin.sections.service-faqs'),
                routeNames: ['admin.sections.service-faqs', 'admin.sections.service-faqs.create'],
                permission: viewPermission('service-faq'),
            },
            {
                label: 'Service details',
                href: route('admin.sections.service-details'),
                routeNames: ['admin.sections.service-details'],
                permission: viewPermission('service-details-section'),
            },
            {
                label: 'Background images',
                href: route('admin.sections.background-images'),
                routeNames: ['admin.sections.background-images'],
                permission: viewPermission('background-images-section'),
            },
            {
                label: 'Partners',
                href: route('admin.partners'),
                routeNames: ['admin.partners', 'admin.partners.create'],
                permission: viewPermission('partner'),
            },
        ],
    },
];

const customizationNav: NavItem[] = [
    {
        label: 'Menu background images',
        href: route('admin.customization.menu-background-images'),
        icon: 'ri-image-line',
        routeNames: ['admin.customization.menu-background-images'],
        permission: viewPermission('menu-background-images'),
    },
];

const administrationNav: NavItem[] = [
    {
        label: 'Users',
        href: route('admin.users'),
        icon: 'ri-group-line',
        routeNames: ['admin.users', 'admin.users.create'],
        permission: viewPermission('user'),
    },
    {
        label: 'Roles',
        href: route('admin.roles'),
        icon: 'ri-shield-user-line',
        routeNames: ['admin.roles', 'admin.roles.create'],
        permission: viewPermission('role'),
    },
    {
        label: 'Permission groups',
        href: route('admin.permission-groups'),
        icon: 'ri-list-check-2',
        routeNames: ['admin.permission-groups', 'admin.permission-groups.create'],
        permission: viewPermission('role'),
    },
];

function isActive(routeNames?: string[]): boolean {
    if (!routeNames?.length) {
        return false;
    }

    return routeNames.some((name) => route().current(name));
}

function isNavItem(item: NavItem | NavSubmenuItem): item is NavItem {
    return 'href' in item;
}

function canSeeNavChild(permission: string | undefined, permissions: string[] | undefined): boolean {
    if (!permission) {
        return true;
    }

    return userCan(permissions, permission);
}

function canSeeNavItem(item: NavItem | NavSubmenuItem, permissions: string[] | undefined): boolean {
    if (isNavItem(item)) {
        return canSeeNavChild(item.permission, permissions);
    }

    return item.children.some((child) => canSeeNavChild(child.permission, permissions));
}

function visibleSubmenuChildren(item: NavSubmenuItem, permissions: string[] | undefined): NavSubItem[] {
    return item.children.filter((child) => canSeeNavChild(child.permission, permissions));
}

function filterContentNav(permissions: string[] | undefined): Array<NavItem | NavSubmenuItem> {
    return contentNav.filter((item) => canSeeNavItem(item, permissions));
}

function filterCustomizationNav(permissions: string[] | undefined): NavItem[] {
    return customizationNav.filter((item) => canSeeNavItem(item, permissions));
}

function filterAdminNav(permissions: string[] | undefined): NavItem[] {
    return administrationNav.filter((item) => canSeeNavItem(item, permissions));
}

function NavLink({ item }: { item: NavItem }) {
    const active = isActive(item.routeNames);

    return (
        <li className="slide">
            <Link href={item.href} className={cn('side-menu__item', active && 'active')}>
                <i className={cn(item.icon, 'side-menu__icon')} />
                <span className="side-menu__label">{item.label}</span>
            </Link>
        </li>
    );
}

function NavSubmenu({ item, permissions }: { item: NavSubmenuItem; permissions: string[] | undefined }) {
    const open = isActive(item.routeNames);
    const children = visibleSubmenuChildren(item, permissions);

    return (
        <li className={cn('slide has-sub', open && 'open')}>
            <a href="javascript:void(0);" className="side-menu__item">
                <i className={cn(item.icon, 'side-menu__icon')} />
                <span className="side-menu__label">{item.label}</span>
                <i className="ri ri-arrow-right-s-line side-menu__angle" />
            </a>
            <ul className="slide-menu child1">
                <li className="slide side-menu__label1">
                    <a href="javascript:void(0);">{item.label}</a>
                </li>
                {children.map((child) => {
                    const active = isActive(child.routeNames);

                    return (
                        <li key={child.href} className="slide">
                            <Link href={child.href} className={cn('side-menu__item', active && 'active')}>
                                {child.label}
                            </Link>
                        </li>
                    );
                })}
            </ul>
        </li>
    );
}

function renderNavItem(item: NavItem | NavSubmenuItem, permissions: string[] | undefined) {
    if (isNavItem(item)) {
        return <NavLink key={item.href} item={item} />;
    }

    return <NavSubmenu key={item.label} item={item} permissions={permissions} />;
}

type SharedAuth = {
    auth: {
        user: {
            permissions?: string[];
        } | null;
    };
};

export function Sidebar() {
    const { auth } = usePage<SharedAuth>().props;
    const permissions = auth.user?.permissions;
    const visibleContentNav = filterContentNav(permissions);
    const visibleCustomizationNav = filterCustomizationNav(permissions);
    const visibleAdminNav = filterAdminNav(permissions);

    return (
        <aside className="app-sidebar" id="sidebar">
            <div className="main-sidebar-header">
                <Link href={route('dashboard')} className="header-logo">
                    <img
                        src={siteBrandLogoSrc}
                        alt={siteBrandLogoAlt}
                        className="main-logo desktop-logo site-brand-logo"
                    />
                    <img src={siteBrandLogoSrc} alt={siteBrandLogoAlt} className="main-logo toggle-logo site-brand-logo" />
                    <img
                        src={siteBrandLogoSrc}
                        alt={siteBrandLogoAlt}
                        className="main-logo desktop-dark site-brand-logo"
                    />
                    <img src={siteBrandLogoSrc} alt={siteBrandLogoAlt} className="main-logo toggle-dark site-brand-logo" />
                </Link>
            </div>

            <div className="main-sidebar " id="sidebar-scroll">
                <nav className="main-menu-container nav nav-pills flex-column sub-open">
                    <div className="slide-left" id="slide-left">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="#7b8191" width="24" height="24" viewBox="0 0 24 24">
                            <path d="M13.293 6.293 7.586 12l5.707 5.707 1.414-1.414L10.414 12l4.293-4.293z" />
                        </svg>
                    </div>
                    <ul className="main-menu">
                        <li className="slide__category">
                            <span className="category-name">Main</span>
                        </li>
                        {mainNav.map((item) => (
                            <NavLink key={item.href} item={item} />
                        ))}

                        {visibleContentNav.length > 0 && (
                            <>
                                <li className="slide__category">
                                    <span className="category-name">Content</span>
                                </li>
                                {visibleContentNav.map((item) => renderNavItem(item, permissions))}
                            </>
                        )}

                        {visibleAdminNav.length > 0 && (
                            <>
                                <li className="slide__category">
                                    <span className="category-name">Administration</span>
                                </li>
                                {visibleAdminNav.map((item) => (
                                    <NavLink key={item.href} item={item} />
                                ))}
                            </>
                        )}

                        {visibleCustomizationNav.length > 0 && (
                            <>
                                <li className="slide__category">
                                    <span className="category-name">Customization</span>
                                </li>
                                {visibleCustomizationNav.map((item) => (
                                    <NavLink key={item.href} item={item} />
                                ))}
                            </>
                        )}
                    </ul>
                    <div className="slide-right" id="slide-right">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="#7b8191" width="24" height="24" viewBox="0 0 24 24">
                            <path d="M10.707 17.707 16.414 12l-5.707-5.707-1.414 1.414L13.586 12l-4.293 4.293z" />
                        </svg>
                    </div>
                </nav>
            </div>
        </aside>
    );
}
