"use client";

import {
  Box,
  Drawer,
  DrawerBody,
  DrawerCloseButton,
  DrawerContent,
  DrawerHeader,
  DrawerOverlay,
  HStack,
  Icon,
  IconButton,
  Link,
  SimpleGrid,
  Stack,
  Text,
  Tooltip,
  VStack,
  useDisclosure,
} from "@chakra-ui/react";
import { Children, forwardRef, isValidElement, useRef } from "react";
import { FiMoreHorizontal } from "react-icons/fi/index.js";
import { IoExit } from "react-icons/io5/index.js";
import { logoutKeycloak } from "../core/keycloak.jsx";
import { usePermission } from "../core/permission.jsx";

const normalizeSidebarPath = (value = "") => {
  const path = String(value).split(/[?#]/)[0] || "";

  if (!path || path === "/") return path || "/";

  return path.replace(/\/+$/, "");
};

export const isSidebarPathActive = (currentPath, item) => {
  const normalizedPath = normalizeSidebarPath(currentPath);
  const candidatePaths = [item?.path, ...(item?.aliases || [])]
    .filter(Boolean)
    .map(normalizeSidebarPath);

  return candidatePaths.some(
    (path) => normalizedPath === path || normalizedPath.startsWith(`${path}/`),
  );
};

export const getActiveSidebarItem = (items = [], currentPath) =>
  items.find((item) => isSidebarPathActive(currentPath, item));

const SidebarLink = forwardRef(
  ({ linkComponent, href, children, ...props }, ref) => {
    const linkProps = linkComponent ? { as: linkComponent } : {};

    return (
      <Link ref={ref} href={href} {...linkProps} {...props}>
        {children}
      </Link>
    );
  },
);

SidebarLink.displayName = "SidebarLink";

const DesktopNavItem = ({
  item,
  isActive,
  isDisabled,
  linkComponent,
  onNavigate,
}) => {
  const commonProps = {
    variant: "ghost",
    position: "relative",
    bg: "transparent",

    _before: isActive
      ? {
          content: '""',
          position: "absolute",
          top: 0,
          bottom: 0,
          insetInlineStart: 0,
          insetInlineEnd: 0,
          bg: "gray.200",
          borderRadius: "md",
          zIndex: 0,
        }
      : undefined,

    sx: {
      "> svg": {
        position: "relative",
        zIndex: 1,
      },
    },

    icon: <Icon as={item.icon} />,
    fontSize: "xl",
    size: { base: "sm", lg: "md" },
    "aria-label": item.title,
    "aria-current": isActive ? "page" : undefined,
  };

  let content;

  if (isDisabled || isActive) {
    content = (
      <IconButton
        {...commonProps}
        isDisabled={isDisabled}
        cursor={isActive && !isDisabled ? "default" : undefined}
      />
    );
  } else {
    const linkProps = linkComponent
      ? { as: linkComponent, href: item.path }
      : { as: "a", href: item.path };

    content = (
      <IconButton {...commonProps} {...linkProps} onClick={onNavigate} />
    );
  }

  return (
    <Tooltip
      label={isDisabled ? "عدم دسترسی" : item.title}
      placement="left-start"
      hasArrow
      rounded="md"
      py={2}
      px={4}
      fontWeight="bold"
      closeDelay={150}
    >
      <Box as="span">{content}</Box>
    </Tooltip>
  );
};

const MobileNavigationButton = ({
  item,
  isActive,
  isDisabled,
  linkComponent,
  onNavigate,
}) => {
  const content = (
    <VStack
      as="span"
      spacing={0.5}
      w="full"
      minW={0}
      py={1}
      px={1}
      borderRadius="xl"
      color={isActive ? "blue.600" : "gray.600"}
      bg={isActive ? "blue.50" : "transparent"}
      opacity={isDisabled ? 0.4 : 1}
      transition="background-color 150ms ease, color 150ms ease"
    >
      <Icon as={item.icon} boxSize={5} />
      <Text
        as="span"
        w="full"
        fontSize="10px"
        fontWeight={isActive ? "bold" : "medium"}
        lineHeight="short"
        textAlign="center"
        noOfLines={1}
      >
        {item.mobileTitle || item.title}
      </Text>
    </VStack>
  );

  if (isDisabled || isActive) {
    return (
      <Box
        flex="1"
        minW={0}
        display="flex"
        alignItems="center"
        aria-disabled={isDisabled ? "true" : undefined}
        aria-current={isActive ? "page" : undefined}
      >
        {content}
      </Box>
    );
  }

  return (
    <SidebarLink
      linkComponent={linkComponent}
      href={item.path}
      flex="1"
      minW={0}
      display="flex"
      alignItems="center"
      _hover={{ textDecoration: "none" }}
      onClick={onNavigate}
      aria-current={isActive ? "page" : undefined}
    >
      {content}
    </SidebarLink>
  );
};

const SidebarExit = () => null;

const SidebarRoot = ({
  items = [],
  currentPath,
  linkComponent,
  onNavigate,
  children,
  primaryMobileCount = 4,
  moreTitle = "بیشتر",
  moreDrawerTitle = "سایر بخش‌های سامانه",
  desktopProps,
  mobileProps,
}) => {
  const { isOpen, onOpen, onClose } = useDisclosure();
  const moreButtonRef = useRef();
  const { cannot } = usePermission();

  const exitElement = Children.toArray(children).find(
    (child) => isValidElement(child) && child.type === SidebarExit,
  );
  const hasExit = Boolean(exitElement);
  const logoutTitle = exitElement?.props?.title || "خروج";
  const logoutIcon = exitElement?.props?.icon || IoExit;

  const resolvedCurrentPath =
    currentPath ??
    (typeof window !== "undefined"
      ? `${window.location.pathname}${window.location.search}`
      : "");

  const primaryItems = items.slice(0, primaryMobileCount);
  const secondaryItems = items.slice(primaryMobileCount);

  const disabled = (item) => {
    const permissions = Array.isArray(item?.perm) ? item.perm : [item?.perm];

    return permissions.filter(Boolean).some((permission) => cannot(permission));
  };
  const active = (item) => isSidebarPathActive(resolvedCurrentPath, item);

  const isSecondaryItemActive = secondaryItems.some(active);
  const hasMoreContent = secondaryItems.length > 0 || hasExit;

  const handleNavigate = (item) => {
    onNavigate?.(item);
    onClose();
  };

  const handleLogout = () => {
    onClose();
    logoutKeycloak();
  };

  return (
    <>
      <Stack
        py={6}
        as="nav"
        flexShrink={0}
        justify="space-between"
        h="full"
        borderLeft="1px"
        borderColor="gray.200"
        overflowY="scroll"
        sx={{
          "::-webkit-scrollbar": { display: "none" },
          scrollbarWidth: "none",
          msOverflowStyle: "none",
        }}
        display={{ base: "none", lg: "flex" }}
        {...desktopProps}
      >
        <VStack spacing={2}>
          {items.map((item) => (
            <DesktopNavItem
              key={item.path}
              item={item}
              isDisabled={disabled(item)}
              isActive={active(item)}
              linkComponent={linkComponent}
              onNavigate={() => onNavigate?.(item)}
            />
          ))}

          {hasExit && (
            <Tooltip
              label={logoutTitle}
              placement="left-start"
              hasArrow
              rounded="md"
              py={2}
              px={4}
              fontWeight="bold"
              closeDelay={150}
            >
              <IconButton
                variant="ghost"
                icon={<Icon as={logoutIcon} />}
                fontSize="xl"
                size={{ base: "sm", lg: "lg" }}
                aria-label={logoutTitle}
                onClick={handleLogout}
              />
            </Tooltip>
          )}
        </VStack>
      </Stack>

      <Box
        as="nav"
        aria-label="ناوبری اصلی موبایل"
        display={{ base: "block", lg: "none" }}
        position="fixed"
        insetInline={0}
        bottom={0}
        zIndex={1200}
        bg="white"
        borderTopWidth="1px"
        borderColor="gray.200"
        boxShadow="0 -6px 18px rgba(0, 0, 0, 0.08)"
        pb="env(safe-area-inset-bottom)"
        {...mobileProps}
      >
        <HStack h="56px" px={1.5} spacing={1} align="stretch">
          {primaryItems.map((item) => (
            <MobileNavigationButton
              key={item.path}
              item={item}
              isDisabled={disabled(item)}
              isActive={active(item)}
              linkComponent={linkComponent}
              onNavigate={() => handleNavigate(item)}
            />
          ))}

          {hasMoreContent && (
            <Box
              as="button"
              ref={moreButtonRef}
              type="button"
              flex="1"
              minW={0}
              h="full"
              p={0}
              border={0}
              bg="transparent"
              font="inherit"
              display="flex"
              alignItems="center"
              justifyContent="center"
              cursor="pointer"
              onClick={onOpen}
              aria-label="نمایش سایر بخش‌ها"
            >
              <VStack
                spacing={0.5}
                w="full"
                py={1}
                px={1}
                borderRadius="xl"
                color={isSecondaryItemActive ? "blue.600" : "gray.600"}
                bg={isSecondaryItemActive ? "blue.50" : "transparent"}
              >
                <Icon as={FiMoreHorizontal} boxSize={5} />
                <Text
                  fontSize="10px"
                  fontWeight={isSecondaryItemActive ? "bold" : "medium"}
                  lineHeight="short"
                >
                  {moreTitle}
                </Text>
              </VStack>
            </Box>
          )}
        </HStack>
      </Box>

      {hasMoreContent && (
        <Drawer
          isOpen={isOpen}
          placement="bottom"
          onClose={onClose}
          finalFocusRef={moreButtonRef}
        >
          <DrawerOverlay />
          <DrawerContent
            borderTopRadius="2xl"
            maxH="min(78dvh, 620px)"
            pb="env(safe-area-inset-bottom)"
          >
            <DrawerCloseButton insetInlineEnd={3} insetInlineStart="auto" />
            <DrawerHeader borderBottomWidth="1px" fontSize="md">
              {moreDrawerTitle}
            </DrawerHeader>

            <DrawerBody py={4} overflowY="auto">
              <SimpleGrid columns={4} spacing={2}>
                {secondaryItems.map((item) => {
                  const isDisabled = disabled(item);
                  const isActive = active(item);

                  const content = (
                    <VStack
                      h="70px"
                      minW={0}
                      justify="center"
                      spacing={1}
                      px={1}
                      borderWidth="1px"
                      borderColor={isActive ? "blue.300" : "gray.200"}
                      borderRadius="lg"
                      bg={isActive ? "blue.50" : "white"}
                      color={isActive ? "blue.700" : "gray.700"}
                      opacity={isDisabled ? 0.4 : 1}
                    >
                      <Icon as={item.icon} boxSize={5} flexShrink={0} />
                      <Text
                        w="full"
                        fontSize="10px"
                        lineHeight="shorter"
                        fontWeight={isActive ? "bold" : "medium"}
                        textAlign="center"
                        noOfLines={2}
                      >
                        {item.mobileTitle || item.title}
                      </Text>
                    </VStack>
                  );

                  if (isDisabled || isActive) {
                    return (
                      <Box
                        key={item.path}
                        aria-disabled={isDisabled ? "true" : undefined}
                        aria-current={isActive ? "page" : undefined}
                      >
                        {content}
                      </Box>
                    );
                  }

                  return (
                    <SidebarLink
                      key={item.path}
                      linkComponent={linkComponent}
                      href={item.path}
                      _hover={{ textDecoration: "none" }}
                      onClick={() => handleNavigate(item)}
                      aria-current={isActive ? "page" : undefined}
                    >
                      {content}
                    </SidebarLink>
                  );
                })}
              </SimpleGrid>

              {hasExit && (
                <Box mt={4} pt={4} borderTopWidth="1px" borderColor="gray.200">
                  <HStack
                    as="button"
                    type="button"
                    w="full"
                    justify="center"
                    py={3}
                    borderRadius="xl"
                    border={0}
                    color="red.600"
                    bg="red.50"
                    cursor="pointer"
                    onClick={handleLogout}
                  >
                    <Icon as={logoutIcon} boxSize={5} />
                    <Text fontWeight="bold">{logoutTitle}</Text>
                  </HStack>
                </Box>
              )}
            </DrawerBody>
          </DrawerContent>
        </Drawer>
      )}
    </>
  );
};

export const Sidebar = Object.assign(SidebarRoot, {
  Exit: SidebarExit,
});
