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

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

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

interface NavSubItem {
    label: string;
    href: string;
    routeNames?: string[];
    routeParams?: Record<string, string>;
    permission?: string;
    anyPermissions?: 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: 'Beach & Recreation',
        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: 'Experiences',
        href: route('admin.updates'),
        icon: 'ri-newspaper-line',
        routeNames: ['admin.updates', 'admin.updates.create'],
        permission: viewPermission('update'),
    },
    {
        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: 'Offers',
        href: route('admin.offers'),
        icon: 'ri-price-tag-2-line',
        routeNames: ['admin.offers', 'admin.offers.create'],
        permission: viewPermission('offer'),
    },
    {
        label: 'Rooms',
        href: route('admin.rooms'),
        icon: 'ri-hotel-bed-line',
        routeNames: ['admin.rooms', 'admin.rooms.create'],
        permission: viewPermission('room'),
    },
    {
        label: 'Bookings',
        href: route('admin.bookings'),
        icon: 'ri-calendar-check-line',
        routeNames: ['admin.bookings'],
        permission: viewPermission('booking'),
    },
    {
        label: 'Room reviews',
        href: route('admin.room-reviews'),
        icon: 'ri-chat-quote-line',
        routeNames: ['admin.room-reviews'],
        permission: viewPermission('room-review'),
    },
    {
        label: 'Facilities',
        href: route('admin.facilities'),
        icon: 'ri-hotel-line',
        routeNames: ['admin.facilities', 'admin.facilities.create'],
        permission: viewPermission('facility'),
    },
    {
        label: 'FAQs',
        href: route('admin.faqs'),
        icon: 'ri-question-answer-line',
        routeNames: ['admin.faqs', 'admin.faqs.create'],
        permission: viewPermission('faq'),
    },
    {
        label: 'Marquee',
        href: route('admin.marquee-phrases'),
        icon: 'ri-text',
        routeNames: ['admin.marquee-phrases', 'admin.marquee-phrases.create'],
        permission: viewPermission('marquee-phrase'),
    },
    {
        label: 'Gallery',
        href: route('admin.gallery-photos'),
        icon: 'ri-gallery-line',
        routeNames: ['admin.gallery-photos', 'admin.gallery-photos.create'],
        permission: viewPermission('gallery-photo'),
    },
    {
        label: 'Dining',
        icon: 'ri-restaurant-line',
        routeNames: ['admin.menu-categories', 'admin.menu-categories.create', 'admin.menu-items', 'admin.menu-items.create', 'admin.table-reservations'],
        children: [
            {
                label: 'Categories',
                href: route('admin.menu-categories'),
                routeNames: ['admin.menu-categories', 'admin.menu-categories.create'],
                permission: viewPermission('menu-category'),
            },
            {
                label: 'Menu items',
                href: route('admin.menu-items'),
                routeNames: ['admin.menu-items', 'admin.menu-items.create'],
                permission: viewPermission('menu-item'),
            },
            {
                label: 'Table reservations',
                href: route('admin.table-reservations'),
                routeNames: ['admin.table-reservations'],
                permission: viewPermission('table-reservation'),
            },
        ],
    },
    {
        label: 'Site settings',
        icon: 'ri-settings-3-line',
        routeNames: ['admin.social-links', 'admin.social-links.create', 'admin.footer-settings', 'admin.exchange-rates', 'admin.page-breadcrumbs'],
        children: [
            {
                label: 'Socials',
                href: route('admin.social-links'),
                routeNames: ['admin.social-links', 'admin.social-links.create'],
                permission: viewPermission('social-link'),
            },
            {
                label: 'Footer',
                href: route('admin.footer-settings'),
                routeNames: ['admin.footer-settings'],
                permission: viewPermission('footer-setting'),
            },
            {
                label: 'Currencies',
                href: route('admin.exchange-rates'),
                routeNames: ['admin.exchange-rates'],
                permission: viewPermission('exchange-rate'),
            },
            {
                label: 'Breadcrumbs',
                href: route('admin.page-breadcrumbs'),
                routeNames: ['admin.page-breadcrumbs'],
                permission: viewPermission('page-breadcrumb'),
            },
        ],
    },
    {
        label: 'Pricing',
        icon: 'ri-price-tag-3-line',
        routeNames: [
            'admin.pricing.units',
            'admin.pricing.units.create',
            'admin.pricing-plans',
            'admin.pricing-plans.create',
        ],
        children: [
            {
                label: 'Units',
                href: route('admin.pricing.units'),
                routeNames: ['admin.pricing.units', 'admin.pricing.units.create'],
                permission: viewPermission('pricing-plan'),
            },
            {
                label: 'Pricing plans',
                href: route('admin.pricing-plans'),
                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: 'Contact Messages',
        href: route('admin.contact-messages'),
        icon: 'ri-mail-line',
        routeNames: ['admin.contact-messages'],
        permission: viewPermission('contact-message'),
    },
    {
        label: 'QR codes',
        icon: 'ri-qr-code-line',
        routeNames: [
            'admin.qr-codes.categories',
            'admin.qr-codes.categories.create',
            'admin.qr-codes',
            'admin.qr-codes.create',
            'admin.qr-codes.documentations',
            'admin.qr-codes.documentations.create',
            'admin.qr-codes.documentations.templates',
            'admin.qr-codes.documentations.templates.create',
            'admin.qr-codes.documentations.templates.edit',
            'admin.qr-codes.documentations.templates.builder',
        ],
        children: [
            {
                label: 'QR categories',
                href: route('admin.qr-codes.categories'),
                routeNames: ['admin.qr-codes.categories', 'admin.qr-codes.categories.create'],
                permission: viewPermission('qr-code'),
            },
            {
                label: 'QR codes',
                href: route('admin.qr-codes'),
                routeNames: ['admin.qr-codes', 'admin.qr-codes.create'],
                permission: viewPermission('qr-code'),
            },
            {
                label: 'Documentations',
                href: route('admin.qr-codes.documentations'),
                routeNames: [
                    'admin.qr-codes.documentations',
                    'admin.qr-codes.documentations.create',
                    'admin.qr-codes.documentations.templates',
                    'admin.qr-codes.documentations.templates.create',
                    'admin.qr-codes.documentations.templates.edit',
                    'admin.qr-codes.documentations.templates.builder',
                ],
                permission: viewPermission('documentation'),
                anyPermissions: [viewPermission('documentation'), viewOwnPermission('documentation')],
            },
        ],
    },
    {
        label: 'Partners',
        href: route('admin.partners'),
        icon: 'ri-shake-hands-line',
        routeNames: ['admin.partners', 'admin.partners.create'],
        permission: viewPermission('partner'),
    },
];

const customizationNav: NavItem[] = [];

const administrationNav: NavItem[] = [
    {
        label: 'Users',
        href: route('admin.users'),
        icon: 'ri-group-line',
        routeNames: ['admin.users', 'admin.users.create'],
        permission: viewPermission('user'),
    },
    {
        label: 'Administrative units',
        href: route('admin.administrative-units'),
        icon: 'ri-building-line',
        routeNames: ['admin.administrative-units', 'admin.administrative-units.create'],
        permission: viewPermission('administrative-unit'),
    },
    {
        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'),
    },
    {
        label: 'Audit trail',
        href: route('admin.audit-trail'),
        icon: 'ri-history-line',
        routeNames: ['admin.audit-trail'],
        superAdminOnly: true,
    },
];

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

    return routeNames.some((name) => (routeParams ? route().current(name, routeParams) : route().current(name)));
}

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

function canSeeNavChild(
    permission: string | undefined,
    permissions: string[] | undefined,
    anyPermissions?: string[],
): boolean {
    if (anyPermissions?.length) {
        return userCanAny(permissions, anyPermissions);
    }

    if (!permission) {
        return true;
    }

    return userCan(permissions, permission);
}

function canSeeNavItem(
    item: NavItem | NavSubmenuItem,
    permissions: string[] | undefined,
    isSuperAdmin: boolean,
): boolean {
    if (isNavItem(item)) {
        if (item.superAdminOnly && !isSuperAdmin) {
            return false;
        }

        return canSeeNavChild(item.permission, permissions, item.anyPermissions);
    }

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

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

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

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

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

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 routeOpen = isActive(item.routeNames);
    const [open, setOpen] = useState(routeOpen);
    const children = visibleSubmenuChildren(item, permissions);

    useEffect(() => {
        if (routeOpen) {
            setOpen(true);
        }
    }, [routeOpen]);

    return (
        <li className={cn('slide has-sub', open && 'open')}>
            <button type="button" className="side-menu__item" aria-expanded={open} onClick={() => setOpen((current) => !current)}>
                <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" />
            </button>
            <ul className="slide-menu child1" style={{ display: open ? 'block' : 'none' }}>
                <li className="slide side-menu__label1">
                    <span>{item.label}</span>
                </li>
                {children.map((child) => {
                    const active = isActive(child.routeNames, child.routeParams);

                    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[];
            roles?: string[];
            canViewDashboard?: boolean;
            home?: string;
        } | null;
    };
};

export function Sidebar() {
    const { auth } = usePage<SharedAuth>().props;
    const permissions = auth.user?.permissions;
    const isSuperAdmin = userIsSuperAdmin(auth.user?.roles);
    const homeHref = auth.user?.home ?? route('dashboard');
    const visibleMainNav = auth.user?.canViewDashboard === false ? [] : mainNav;
    const visibleContentNav = filterContentNav(permissions, isSuperAdmin);
    const visibleCustomizationNav = filterCustomizationNav(permissions, isSuperAdmin);
    const visibleAdminNav = filterAdminNav(permissions, isSuperAdmin);

    return (
        <aside className="app-sidebar" id="sidebar">
            <div className="main-sidebar-header">
                <Link href={homeHref} 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={siteBrandLogoWhiteSrc}
                        alt={siteBrandLogoAlt}
                        className="main-logo desktop-dark site-brand-logo"
                    />
                    <img src={siteBrandLogoWhiteSrc} alt="" aria-hidden="true" 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">
                        {visibleMainNav.length > 0 && (
                            <>
                                <li className="slide__category">
                                    <span className="category-name">Main</span>
                                </li>
                                {visibleMainNav.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>
    );
}
