"use client";

import type { ReactNode } from "react";
import Link from "next/link";

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 { ChevronDown } from "@/components/ui/icon";
import type { NavItem } from "@/constants/sidebar-menu";

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;
};

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

function normalizeHref(url: string | undefined): string {
  const normalizedUrl = url?.trim();

  if (!normalizedUrl) {
    return "/";
  }

  return normalizedUrl;
}

function SidebarIcon({
  item,
  active,
}: SidebarIconProps) {
  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>
  );
}

function getItemBackground(
  active: boolean,
  mode: "light" | "dark",
  primaryColor: string,
) {
  if (!active) {
    return "transparent";
  }

  return alpha(
    primaryColor,
    mode === "dark" ? 0.18 : 0.1,
  );
}

function getItemHoverBackground(
  active: boolean,
  mode: "light" | "dark",
  primaryColor: string,
  defaultHover: string,
) {
  if (!active) {
    return defaultHover;
  }

  return alpha(
    primaryColor,
    mode === "dark" ? 0.22 : 0.13,
  );
}

function SidebarItemContent({
  item,
  active,
  showBadge = false,
}: {
  item: NavItem;
  active: boolean;
  showBadge?: boolean;
}) {
  const theme = useTheme();

  return (
    <>
      <SidebarIcon item={item} active={active} />

      <Box
        sx={{
          flex: 1,
          minWidth: 0,
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          gap: 1,
        }}
      >
        <Typography
          component="span"
          sx={{
            minWidth: 0,
            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>

        {showBadge ? <SidebarNotificationBadge /> : null}
      </Box>
    </>
  );
}

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

  return (
    <ListItemButton
      component={Link}
      href={href}
      selected={active}
      aria-current={active ? "page" : undefined}
      sx={{
        minHeight: 44,
        px: 1.5,
        gap: 1.25,
        borderRadius: "12px",
        textDecoration: "none",
        color: active
          ? theme.palette.primary.main
          : theme.palette.text.secondary,
        bgcolor: getItemBackground(
          active,
          theme.palette.mode,
          theme.palette.primary.main,
        ),

        "&.Mui-selected": {
          bgcolor: getItemBackground(
            active,
            theme.palette.mode,
            theme.palette.primary.main,
          ),
        },

        "&.Mui-selected:hover": {
          bgcolor: getItemHoverBackground(
            active,
            theme.palette.mode,
            theme.palette.primary.main,
            theme.palette.action.hover,
          ),
        },

        "&:hover": {
          bgcolor: getItemHoverBackground(
            active,
            theme.palette.mode,
            theme.palette.primary.main,
            theme.palette.action.hover,
          ),
        },
      }}
    >
      <SidebarItemContent
        item={item}
        active={active}
        showBadge={Boolean(item.showNotificationBadge)}
      />
    </ListItemButton>
  );
}

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

  return (
    <ListItemButton
      component="button"
      type="button"
      onClick={onToggle}
      aria-expanded={open}
      aria-label={item.title}
      sx={{
        width: "100%",
        minHeight: 44,
        px: 1.5,
        gap: 1.25,
        borderRadius: "12px",
        color: active
          ? theme.palette.primary.main
          : theme.palette.text.secondary,
        bgcolor: getItemBackground(
          active,
          theme.palette.mode,
          theme.palette.primary.main,
        ),

        "&.Mui-selected": {
          bgcolor: getItemBackground(
            active,
            theme.palette.mode,
            theme.palette.primary.main,
          ),
        },

        "&:hover": {
          bgcolor: getItemHoverBackground(
            active,
            theme.palette.mode,
            theme.palette.primary.main,
            theme.palette.action.hover,
          ),
        },
      }}
    >
      <SidebarIcon item={item} active={active} />

      <Typography
        component="span"
        sx={{
          flex: 1,
          minWidth: 0,
          textAlign: "left",
          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>

      <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 href = normalizeHref(child.url);
  const hasIcon = Boolean(child.icon);

  return (
    <ListItemButton
      component={Link}
      href={href}
      selected={active}
      aria-current={active ? "page" : undefined}
      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",

        "&.Mui-selected": {
          bgcolor: active
            ? alpha(
                theme.palette.primary.main,
                theme.palette.mode === "dark"
                  ? 0.16
                  : 0.08,
              )
            : "transparent",
        },

        "&.Mui-selected:hover": {
          bgcolor: active
            ? alpha(
                theme.palette.primary.main,
                theme.palette.mode === "dark"
                  ? 0.2
                  : 0.12,
              )
            : theme.palette.action.hover,
        },

        "&: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={{
          minWidth: 0,
          fontSize: 13,
          fontWeight: active ? 600 : 500,
          lineHeight: 1.35,
          color: active
            ? theme.palette.primary.main
            : theme.palette.text.secondary,
          overflow: "hidden",
          textOverflow: "ellipsis",
          whiteSpace: "nowrap",
        }}
      >
        {child.title}
      </Typography>
    </ListItemButton>
  );
}