"use client";

import { useMemo, useState } from "react";
import { usePathname } from "next/navigation";

import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { useTheme } from "@mui/material/styles";

import {
  getSidebarNavItemsByPathname,
  type NavItem,
} from "@/constants/sidebar-menu";
import { getClientAuthRole } from "@/features/auth/service/auth-service";
import { usePermissions } from "@/features/auth/hook/use-permissions";
import { useAppLanguage } from "@/components/providers/app-language-provider";

import {
  SidebarChildLink,
  SidebarLinkItem,
  SidebarParentItem,
} from "./sidebar-nav-item";

function getNavKey(item: NavItem, index: number) {
  return `${item.titleEn}-${item.url || "parent"}-${index}`;
}

function getChildNavKey(item: NavItem, index: number) {
  return `${item.titleEn}-${item.url || "child"}-${index}`;
}

function createInitialOpenGroups(items: NavItem[]) {
  return items.reduce<Record<string, boolean>>((groups, item, index) => {
    const key = getNavKey(item, index);
    groups[key] = item.titleEn === "Dashboard";
    return groups;
  }, {});
}

function isExactMatchNavUrl(url: string) {
  return url === "/admin/dashboard" || url === "/ministry/dashboard";
}

function isNavUrlActive(pathname: string, url: string) {
  if (!url) return false;

  if (isExactMatchNavUrl(url)) {
    return pathname === url || pathname === `${url}/`;
  }

  if (pathname === url) return true;

  return pathname.startsWith(`${url}/`);
}

function isAdminPath(pathname: string) {
  return pathname === "/admin" || pathname.startsWith("/admin/");
}

export function SidebarMenu() {
  const pathname = usePathname();
  const theme = useTheme();
  const { language, t } = useAppLanguage();
  const { permissions, role: sessionRole } = usePermissions();

  const [cookieRole] = useState(() => getClientAuthRole());
  const role = sessionRole ?? cookieRole;

  const navItems = useMemo(() => {
    return getSidebarNavItemsByPathname(pathname, role, language, permissions);
  }, [pathname, role, language, permissions]);

  const defaultOpenGroups = useMemo(
    () => createInitialOpenGroups(navItems),
    [navItems],
  );

  const [openGroups, setOpenGroups] = useState<Record<string, boolean>>({});

  function toggleGroup(key: string) {
    setOpenGroups((previousState) => ({
      ...previousState,
      [key]: !(previousState[key] ?? false),
    }));
  }

  return (
    <Box
      sx={{
        position: "relative",
        zIndex: 1000,
        height: "100%",
        flex: 1,
        minHeight: 0,
        display: "flex",
        flexDirection: "column",
        bgcolor: theme.palette.background.paper,
      }}
    >
      <Box
        sx={{
          px: 2.5,
          pt: 2.5,
          flex: 1,
          display: "flex",
          flexDirection: "column",
          minHeight: 0,
        }}
      >
        <Typography
          sx={{
            py: 0.75,
            mb: 2.25,
            color: theme.palette.text.secondary,
            fontSize: 12,
            fontWeight: 500,
          }}
        >
          {isAdminPath(pathname) ? "" : t("mainMenu")}
        </Typography>

        <Box
          sx={{
            display: "flex",
            flexDirection: "column",
            gap: 1.25,
            flex: 1,
            overflowY: "auto",
          }}
        >
          {navItems.map((item, index) => {
            const navKey = getNavKey(item, index);
            const hasChildren = item.items.length > 0;
            const parentActive = isNavUrlActive(pathname, item.url);
            const childActive = item.items.some((child) =>
              isNavUrlActive(pathname, child.url),
            );

            // A parent item is active only when its own URL matches.
            // A child route still keeps the parent group open below.
            const active = parentActive;

            const groupOpen = hasChildren
              ? (openGroups[navKey] ??
                (active || childActive || defaultOpenGroups[navKey]))
              : false;

            return (
              <Box key={navKey}>
                {hasChildren ? (
                  <SidebarParentItem
                    item={item}
                    active={active}
                    open={groupOpen}
                    onToggle={() => toggleGroup(navKey)}
                  />
                ) : (
                  <SidebarLinkItem item={item} active={active} />
                )}

                {hasChildren && groupOpen ? (
                  <Box
                    sx={{
                      mt: 1,
                      display: "flex",
                      flexDirection: "column",
                      gap: 0.5,
                    }}
                  >
                    {item.items.map((child, childIndex) => (
                      <SidebarChildLink
                        key={getChildNavKey(child, childIndex)}
                        child={child}
                        active={isNavUrlActive(pathname, child.url)}
                      />
                    ))}
                  </Box>
                ) : null}
              </Box>
            );
          })}
        </Box>
      </Box>
    </Box>
  );
}
