import DashboardController from "@/actions/App/Http/Controllers/Dashboard/IndexController";
import LogAbsensiController from "@/actions/App/Http/Controllers/LogAbsensi/IndexController";
import IzinController from "@/actions/App/Http/Controllers/Izin/IndexController";
import { Link, router, usePage } from "@inertiajs/react";
import { Collapse, Image, Nav } from "react-bootstrap";
import {
    MdAccessTime,
    MdArrowBack,
    MdArrowForward,
    MdDashboard,
    MdEventNote,
    MdTimeline,
    MdViewCarousel,
} from "react-icons/md";
import { RxChevronRight } from "react-icons/rx";
import { IconType } from "react-icons/lib";
import { Fragment, JSX, useEffect, useState } from "react";
import { useIsMobile } from "@/hooks/use-mobile";
import classNames from "classnames";
import { SharedData } from "@/types";
import RefLokasiController from "@/actions/App/Http/Controllers/Master/RefLokasiController";
import RefSKPDController from "@/actions/App/Http/Controllers/Master/RefSKPDController";
import UsersController from "@/actions/App/Http/Controllers/Master/UsersController";
import RoleController from "@/actions/App/Http/Controllers/RoleController";
import PermissionController from "@/actions/App/Http/Controllers/PermissionController";
import RefShiftKodeController from "@/actions/App/Http/Controllers/Master/RefShiftKodeController";
import RefTipeIzinController from "@/actions/App/Http/Controllers/Master/RefTipeIzinController";
import RefJenisIzinController from "@/actions/App/Http/Controllers/Master/RefJenisIzinController";
import LaporanController from "@/actions/App/Http/Controllers/Laporan/IndexController";

interface NavItem {
    label: string;
    url?: string;
    icon?: IconType;
    children?: NavItem[] | [];
    isHeading?: boolean;
    roles?: string[];
    permissions?: string[];
}

const routes: NavItem[] = [
    {
        label: "Statistik",
        isHeading: true,
    },
    {
        label: "Dashboard",
        url: DashboardController.index.url(),
        icon: MdDashboard,
    },
    {
        label: "Features",
        isHeading: true,
        permissions: ["log-absen.viewAny"],
    },
    {
        label: "Log Absensi",
        url: LogAbsensiController.index.url(),
        icon: MdAccessTime,
        permissions: ["log-absen.viewAny"],
    },
    {
        label: "Izin",
        url: IzinController.index.url(),
        icon: MdEventNote,
        permissions: ["izin.viewAny"],
    },
    {
        label: "Master Data",
        isHeading: true,
        permissions: [
            "shift.viewAny",
            "lokasi.viewAny",
            "skpd.viewAny",
            "skpd-kode.viewAny",
            "user.viewAny",
            "role.viewAny",
            "tipe-izin.viewAny",
            "jenis-izin.viewAny",
            "permission.viewAny",
        ],
    },
    {
        label: "Kelola Master",
        url: "#/",
        icon: MdViewCarousel,
        permissions: [
            "shift.viewAny",
            "lokasi.viewAny",
            "skpd.viewAny",
            "skpd-kode.viewAny",
            "user.viewAny",
            "role.viewAny",
            "tipe-izin.viewAny",
            "jenis-izin.viewAny",
            "permission.viewAny",
        ],
        children: [
            {
                label: "Ref Shift",
                url: RefShiftKodeController.index.url(),
                permissions: ["shift.viewAny"],
            },
            {
                label: "Ref Lokasi",
                url: RefLokasiController.index.url(),
                permissions: ["lokasi.viewAny"],
            },
            {
                label: "Ref SKPD",
                url: RefSKPDController.index.url(),
                permissions: ["skpd.viewAny"],
            },
            {
                label: "Ref Tipe Izin",
                url: RefTipeIzinController.index.url(),
                permissions: ["tipe-izin.viewAny"],
            },
            {
                label: "Ref Jenis Izin",
                url: RefJenisIzinController.index.url(),
                permissions: ["jenis-izin.viewAny"],
            },
            {
                label: "Roles",
                url: RoleController.index.url(),
                permissions: ["role.viewAny"],
            },
            {
                label: "Permissions",
                url: PermissionController.index.url(),
                permissions: ["permission.viewAny"],
            },
            {
                label: "Users",
                url: UsersController.index.url(),
                permissions: ["user.viewAny"],
            },
        ],
    },
    {
        label: "Reporting",
        isHeading: true,
        permissions: ["log-absen.laporanViewAny"],
    },
    {
        label: "Laporan",
        url: "#/",
        icon: MdViewCarousel,
        permissions: ["log-absen.laporanViewAny"],
        children: [
            {
                label: "Detail Absensi Pegawai",
                url: LaporanController.detail.url(),
                permissions: ["log-absen.laporanViewAny"],
            },
            {
                label: "Rekap Absensi Pegawai",
                url: LaporanController.rekap.url(),
                permissions: ["log-absen.laporanViewAny"],
            },
        ],
    },
];

function hasAccess(item: NavItem, user: any): boolean {
    // Jika tidak ada role atau permission yang diperlukan
    if (!item.roles && !item.permissions) {
        // Untuk menu dengan children, cek apakah ada submenu yang bisa diakses
        if (item.children) {
            return item.children.some((child) => hasAccess(child, user));
        }
        return true;
    }

    if (item.roles && item.roles.some((role) => user?.roles?.includes(role))) {
        return true;
    }

    if (
        item.permissions &&
        item.permissions.some((permission) =>
            user?.permissions?.includes(permission),
        )
    ) {
        return true;
    }

    // Jika menu punya children, cek apakah ada submenu yang bisa diakses
    if (item.children) {
        return item.children.some((child) => hasAccess(child, user));
    }

    return false;
}
function findActivePath(
    items: NavItem[],
    url: string,
    path: number[] = [],
): number[] {
    for (let i = 0; i < items.length; i++) {
        const item = items[i];

        // cek children dulu
        if (item.children) {
            const childPath = findActivePath(item.children, url, [...path, i]);
            if (childPath.length) return childPath;
        }

        if (item.url && url.startsWith(item.url)) {
            return [...path, i];
        }
    }
    return [];
}

interface AppSidebarProps {
    isSidebarMobileOpen: boolean;
    setIsSidebarMobileOpen: (open: boolean) => void;
    onToggleSidebarSize?: () => void;
}

export default function AppSidebarLayout({
    isSidebarMobileOpen,
    setIsSidebarMobileOpen,
    onToggleSidebarSize,
}: AppSidebarProps) {
    const { url } = usePage<{ url: string }>();
    const isMobile = useIsMobile();
    const [sidebarSize, setSidebarSize] = useState<string>(() => {
        return isMobile ? "lg" : localStorage.getItem("sidebarSize") || "lg";
    });
    const [isSidebarHover, setIsSidebarHover] = useState(false);

    const activePath = findActivePath(routes, url);
    const [openIdx, setOpenIdx] = useState<number[]>(activePath);

    const toggleSidebarSize = () => {
        if (!isMobile) {
            const newSize = sidebarSize === "lg" ? "sm" : "lg";
            setSidebarSize(newSize);
            localStorage.setItem("sidebarSize", newSize);
        }
    };

    const handleAccordion = (level: number, idx: number) => {
        if (sidebarSize === "sm" && !isSidebarHover) return; // Disable toggle in small mode
        setOpenIdx((prev) => {
            const newOpen = prev.slice(0, level);
            newOpen[level] = prev[level] === idx ? -1 : idx;
            return newOpen;
        });
    };

    function isChildActive(item: NavItem, url: string): boolean {
        if (!item.children) return false;
        return item.children.some((child) => {
            if (child.url && url.startsWith(child.url)) return true;
            return isChildActive(child, url);
        });
    }

    const renderNav = (
        navItems: NavItem[],
        level = 0,
        parentIdxPath: number[] = [],
    ): JSX.Element => (
        <Nav
            className={classNames(
                level === 0 ? "flex-column" : "flex-column nav-children",
                { "nav-nested-small": level >= 2 },
            )}
        >
            {navItems.map((item, idx) => {
                const idxPath = [...parentIdxPath, idx];
                const isOpen = openIdx[level] === idx;
                const isActive =
                    (!!item.url && url.startsWith(item.url)) ||
                    isChildActive(item, url);
                const hasChildren = !!item.children;
                const isHeading = !!item?.isHeading && item.isHeading === true;
                const user = usePage<SharedData>().props.auth.user;

                if (!hasAccess(item, user)) {
                    return null;
                }

                if (isHeading) {
                    return (
                        <div key={idxPath.join("-")} className="nav-heading">
                            <div className="nav-heading-title">
                                {item.label}
                            </div>
                        </div>
                    );
                }

                if (hasChildren) {
                    return (
                        <Fragment key={idxPath.join("-")}>
                            <Nav.Item>
                                <button
                                    className={classNames("nav-link", {
                                        active: isActive || isOpen,
                                    })}
                                    onClick={() => handleAccordion(level, idx)}
                                    type="button"
                                    tabIndex={sidebarSize === "sm" ? -1 : 0}
                                >
                                    {!!item.icon ? (
                                        <item.icon
                                            className="nav-icon"
                                            size={20}
                                        />
                                    ) : (
                                        <i className="bi bi-dash nav-icon-children"></i>
                                    )}
                                    <span className="nav-title">
                                        {item.label}
                                    </span>
                                    <RxChevronRight
                                        className={classNames("nav-arrow", {
                                            "rotate-90": isOpen,
                                        })}
                                    />
                                </button>
                            </Nav.Item>
                            <Collapse
                                in={
                                    isOpen &&
                                    (sidebarSize !== "sm" || isSidebarHover)
                                }
                            >
                                <div>
                                    {renderNav(
                                        item.children!,
                                        level + 1,
                                        idxPath,
                                    )}
                                </div>
                            </Collapse>
                        </Fragment>
                    );
                }

                return (
                    <Nav.Item key={idxPath.join("-")}>
                        <Nav.Link
                            as={Link}
                            href={item.url}
                            className={classNames({ active: isActive })}
                        >
                            {!!item.icon ? (
                                <item.icon className="nav-icon" size={20} />
                            ) : (
                                <i className="bi bi-dash nav-icon-children"></i>
                            )}
                            <span className="nav-title">{item.label}</span>
                        </Nav.Link>
                    </Nav.Item>
                );
            })}
        </Nav>
    );

    useEffect(() => {
        if (sidebarSize === "sm") {
            setOpenIdx([]);
        }
        document.documentElement.setAttribute("data-sidebar-size", sidebarSize);
        document.documentElement.setAttribute(
            "data-sidebar-hover",
            isSidebarHover ? "true" : "false",
        );
    }, [sidebarSize, isSidebarHover]);

    // Only set mobile view attribute, remove sidebar size reset
    useEffect(() => {
        document.documentElement.setAttribute(
            "data-mobile-view",
            isMobile ? "true" : "false",
        );
    }, [isMobile]);

    // Update sidebarSize when isMobile changes
    useEffect(() => {
        if (isMobile) {
            setSidebarSize("lg");
        } else {
            // Restore from localStorage when switching back to desktop
            setSidebarSize(localStorage.getItem("sidebarSize") || "lg");
        }
    }, [isMobile]);

    // Expose toggleSidebarSize function to parent component
    useEffect(() => {
        if (onToggleSidebarSize) {
            // Store the function reference for external access
            (window as any).__toggleSidebarSize = toggleSidebarSize;
        }
        return () => {
            // Cleanup on unmount
            delete (window as any).__toggleSidebarSize;
        };
    }, [toggleSidebarSize, onToggleSidebarSize]);

    return (
        <Fragment>
            {(isSidebarMobileOpen ||
                (!isSidebarMobileOpen &&
                    sidebarSize === "sm" &&
                    isSidebarHover)) && (
                <div
                    className="app-sidebar-overlay"
                    onClick={() => setIsSidebarMobileOpen(false)}
                    aria-label="Close sidebar"
                />
            )}

            <aside
                className={classNames("app-sidebar", {
                    "sidebar-overlay-open":
                        sidebarSize === "sm" && isSidebarHover,
                    "sidebar-mobile-open": isSidebarMobileOpen,
                })}
                onMouseEnter={() =>
                    sidebarSize === "sm" && setIsSidebarHover(true)
                }
                onMouseLeave={() =>
                    sidebarSize === "sm" && setIsSidebarHover(false)
                }
            >
                <div className="app-sidebar-container">
                    <div className="app-sidebar-header">
                        <h5
                            className="app-brand-wrapper cursor-pointer"
                            onClick={() => router.visit("dashboard")}
                        >
                            <div className="flex-shrink-0 app-brand">
                                <Image src="/assets/logo_pemkot.png" />
                            </div>
                            <div className="flex-grow-1 app-title">
                                <div className="mb-1">SIAB</div>
                                <div
                                    className="text-secondary"
                                    style={{ fontSize: "0.65rem" }}
                                >
                                    Absensi Paruh Waktu
                                </div>
                            </div>
                        </h5>

                        <div
                            className="btn-toggle"
                            onClick={() => {
                                if (isMobile) {
                                    setIsSidebarMobileOpen(false);
                                } else {
                                    toggleSidebarSize();
                                }
                            }}
                        >
                            {sidebarSize == "lg" ? (
                                <MdArrowBack className="text-dark" />
                            ) : (
                                <MdArrowForward className="text-dark" />
                            )}
                        </div>
                    </div>
                    <div className="app-sidebar-body">{renderNav(routes)}</div>
                </div>
            </aside>
        </Fragment>
    );
}
