"use client";

import type { MouseEvent } from "react";
import { useRouter } from "next/navigation";

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

import type { NavItem } from "@/constants/sidebar-menu";
import { ChevronDown } from "@/components/ui/icon";
import { SidebarNotificationBadge } from "./sidebar-notification-badge";

type SidebarLinkItemProps = {
  item: NavItem;
  active: boolean;
};

type SidebarParentItemProps = {
  item: NavItem;
  active: boolean;
  open: boolean;
  onToggle: () => void;
};

type SidebarChildLinkProps = {
  child: NavItem;
  active: boolean;
};

function shouldHandleClientNavigation(event: MouseEvent<HTMLAnchorElement>) {
  return !(
    event.defaultPrevented ||
    event.button !== 0 ||
    event.metaKey ||
    event.ctrlKey ||
    event.shiftKey ||
    event.altKey
  );
}

function useSidebarNavClick(href: string) {
  const router = useRouter();

  return (event: MouseEvent<HTMLAnchorElement>) => {
    if (!shouldHandleClientNavigation(event)) return;
    event.preventDefault();
    router.push(href);
  };
}

function SidebarIcon({ item, active }: { item: NavItem; active: boolean }) {
  const theme = useTheme();

  if (!item.icon) return null;

  const Icon = item.icon.icon;

  return (
    <Box
      sx={{
        width: 24,
        height: 24,
        display: "grid",
        placeItems: "center",
        flexShrink: 0,
        color: active
          ? theme.palette.primary.main
          : theme.palette.text.secondary,
      }}
    >
      <Icon sx={{ fontSize: item.icon.size ?? 20 }} />
    </Box>
  );
}

export function SidebarLinkItem({ item, active }: SidebarLinkItemProps) {
  const theme = useTheme();
  const handleClick = useSidebarNavClick(item.url);

  return (
    <ListItemButton
      component="a"
      href={item.url}
      onClick={handleClick}
      sx={{
        minHeight: 44,
        px: 1.5,
        gap: 1.25,
        borderRadius: "12px",
        textDecoration: "none",
        color: active
          ? theme.palette.primary.main
          : theme.palette.text.secondary,
        bgcolor: active
          ? alpha(
              theme.palette.primary.main,
              theme.palette.mode === "dark" ? 0.18 : 0.1,
            )
          : "transparent",
        "&:hover": {
          bgcolor: active
            ? alpha(
                theme.palette.primary.main,
                theme.palette.mode === "dark" ? 0.22 : 0.13,
              )
            : theme.palette.action.hover,
        },
      }}
    >
      <SidebarIcon item={item} active={active} />

      <Box
        sx={{
          flex: 1,
          minWidth: 0,
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          gap: 1,
        }}
      >
        <Typography
          component="span"
          sx={{
            fontSize: 14,
            fontWeight: active ? 600 : 500,
            lineHeight: 1.35,
            color: active
              ? theme.palette.primary.main
              : theme.palette.text.secondary,
            overflow: "hidden",
            textOverflow: "ellipsis",
            whiteSpace: "nowrap",
          }}
        >
          {item.title}
        </Typography>

        {item.showNotificationBadge && <SidebarNotificationBadge />}
      </Box>
    </ListItemButton>
  );
}

export function SidebarParentItem({
  item,
  active,
  open,
  onToggle,
}: SidebarParentItemProps) {
  const theme = useTheme();

  return (
    <ListItemButton
      onClick={onToggle}
      sx={{
        minHeight: 44,
        px: 1.5,
        gap: 1.25,
        borderRadius: "12px",
        color: active
          ? theme.palette.primary.main
          : theme.palette.text.secondary,
        bgcolor: active
          ? alpha(
              theme.palette.primary.main,
              theme.palette.mode === "dark" ? 0.18 : 0.1,
            )
          : "transparent",
        "&:hover": {
          bgcolor: active
            ? alpha(
                theme.palette.primary.main,
                theme.palette.mode === "dark" ? 0.22 : 0.13,
              )
            : theme.palette.action.hover,
        },
      }}
    >
      <SidebarIcon item={item} active={active} />

      <Typography
        sx={{
          flex: 1,
          minWidth: 0,
          fontSize: 14,
          fontWeight: active ? 600 : 500,
          lineHeight: 1.35,
          color: active
            ? theme.palette.primary.main
            : theme.palette.text.secondary,
        }}
      >
        {item.title}
      </Typography>

      <ChevronDown
        sx={{
          fontSize: 18,
          flexShrink: 0,
          color: active
            ? theme.palette.primary.main
            : theme.palette.text.secondary,
          transform: open ? "rotate(180deg)" : "rotate(0deg)",
          transition: "transform 0.2s ease",
        }}
      />
    </ListItemButton>
  );
}

export function SidebarChildLink({ child, active }: SidebarChildLinkProps) {
  const theme = useTheme();
  const handleClick = useSidebarNavClick(child.url);
  const hasIcon = Boolean(child.icon);

  return (
    <ListItemButton
      component="a"
      href={child.url}
      onClick={handleClick}
      sx={{
        minHeight: 36,
        ml: 4.5,
        px: 1.5,
        gap: hasIcon ? 1 : 0,
        borderRadius: "10px",
        textDecoration: "none",
        color: active
          ? theme.palette.primary.main
          : theme.palette.text.secondary,
        bgcolor: active
          ? alpha(
              theme.palette.primary.main,
              theme.palette.mode === "dark" ? 0.16 : 0.08,
            )
          : "transparent",
        "&:hover": {
          bgcolor: active
            ? alpha(
                theme.palette.primary.main,
                theme.palette.mode === "dark" ? 0.2 : 0.12,
              )
            : theme.palette.action.hover,
        },
      }}
    >
      {hasIcon ? <SidebarIcon item={child} active={active} /> : null}
      <Typography
        component="span"
        sx={{
          fontSize: 13,
          fontWeight: active ? 600 : 500,
          lineHeight: 1.35,
          color: active
            ? theme.palette.primary.main
            : theme.palette.text.secondary,
        }}
      >
        {child.title}
      </Typography>
    </ListItemButton>
  );
}
