/*
 * Copyright © 2024 Hexastack. All rights reserved.
 *
 * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
 * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
 * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
 */

import {
  faAlignLeft,
  faAsterisk,
  faBars,
  faCogs,
  faComments,
  faDatabase,
  faGraduationCap,
  faLanguage,
  faTags,
  faUserCircle,
  faUsers,
  IconDefinition,
} from "@fortawesome/free-solid-svg-icons";
import { Flag, Language } from "@mui/icons-material";
import AppsIcon from "@mui/icons-material/Apps";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import DriveFolderUploadIcon from "@mui/icons-material/DriveFolderUpload";
import FolderIcon from "@mui/icons-material/Folder";
import HomeIcon from "@mui/icons-material/Home";
import PeopleAltRoundedIcon from "@mui/icons-material/PeopleAltRounded";
import SettingsAccessibilityRoundedIcon from "@mui/icons-material/SettingsAccessibilityRounded";
import { CSSObject, Grid, IconButton, styled, Theme } from "@mui/material";
import MuiDrawer from "@mui/material/Drawer";
import { OverridableComponent } from "@mui/material/OverridableComponent";
import { useRouter } from "next/router";
import { FC, useMemo } from "react";

import { HexabotLogo } from "@/app-components/logos/HexabotLogo";
import { Sidebar } from "@/app-components/menus/Sidebar";
import { useAuth } from "@/hooks/useAuth";
import { useConfig } from "@/hooks/useConfig";
import { useHasPermission } from "@/hooks/useHasPermission";
import { useTranslate } from "@/hooks/useTranslate";
import { EntityType } from "@/services/types";
import { PermissionAction } from "@/types/permission.types";
import { getLayout } from "@/utils/laylout";

const drawerWidth = 280;
const openedMixin = (theme: Theme): CSSObject => ({
  width: drawerWidth,
  transition: theme.transitions.create("width", {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.enteringScreen,
  }),
  overflowX: "hidden",
});
const closedMixin = (theme: Theme, isFloated: boolean): CSSObject => ({
  ...(isFloated && { position: "absolute" }),
  transition: theme.transitions.create("width", {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.leavingScreen,
  }),
  overflowX: "hidden",
  width: `calc(${theme.spacing(7)} + 1px)`,
  [theme.breakpoints.up("sm")]: {
    width: `calc(${theme.spacing(8)} + 1px)`,
  },
});
const DrawerHeader = styled("div")(({ theme }) => ({
  display: "flex",
  alignItems: "center",
  justifyContent: "flex-end",
  padding: theme.spacing(0, 1),
  // necessary for content to be below app bar
  ...theme.mixins.toolbar,
}));
const Drawer = styled(MuiDrawer, {
  shouldForwardProp: (prop) => prop !== "isToggled",
})(({ theme, open, ModalProps }) => ({
  width: drawerWidth,
  flexShrink: 0,
  whiteSpace: "nowrap",
  boxSizing: "border-box",
  borderRadius: "0px",
  ...(open && {
    ...openedMixin(theme),
    "& .MuiDrawer-paper": openedMixin(theme),
  }),
  ...(!open && {
    ...closedMixin(theme, !!ModalProps?.open),
    "& .MuiDrawer-paper": closedMixin(theme, !!ModalProps?.open),
  }),
}));
const StyledDrawerHeader = styled(DrawerHeader)(() => ({
  top: 0,
  zIndex: 1,
  position: "sticky",
  maxHeight: "60px",
  background: "#fffe",
}));

export type MenuItem = {
  text: string;
  href?: string;
  Icon?: OverridableComponent<any> | IconDefinition;
  requires?: { [key in EntityType]?: PermissionAction[] };
  submenuItems?: MenuItem[];
};

const getMenuItems = (ssoEnabled: boolean): MenuItem[] => [
  {
    text: "menu.dashboard",
    href: "/",
    Icon: HomeIcon,
    requires: {
      [EntityType.BOTSTATS]: [PermissionAction.READ],
    },
  },
  {
    text: "menu.visual_editor",
    href: "/visual-editor",
    Icon: AppsIcon,
    requires: {
      [EntityType.BLOCK]: [PermissionAction.READ],
    },
  },
  {
    text: "menu.nlp",
    href: "/nlp",
    Icon: faGraduationCap,
    requires: {
      [EntityType.NLP_SAMPLE]: [PermissionAction.READ],
    },
  },
  {
    text: "menu.inbox",
    href: "/inbox",
    Icon: faComments,
    requires: {
      [EntityType.MESSAGE]: [PermissionAction.READ],
    },
  },
  {
    text: "menu.categories",
    href: "/categories",
    Icon: FolderIcon,
    requires: {
      [EntityType.CATEGORY]: [PermissionAction.READ],
    },
  },
  {
    text: "menu.context_vars",
    href: "/context-vars",
    Icon: faAsterisk,
    requires: {
      [EntityType.CONTEXT_VAR]: [PermissionAction.READ],
    },
  },
  {
    text: "menu.manage_content",
    Icon: faDatabase,
    submenuItems: [
      {
        text: "menu.persistent_menu",
        href: "/content/persistent-menu",
        Icon: faBars,
        requires: {
          [EntityType.MENU]: [PermissionAction.READ],
        },
      },
      {
        text: "menu.cms",
        href: "/content/types",
        Icon: faAlignLeft,
        requires: {
          [EntityType.CONTENT_TYPE]: [PermissionAction.READ],
        },
      },
      {
        text: "menu.media_library",
        href: "/content/media-library",
        Icon: DriveFolderUploadIcon,
        requires: {
          [EntityType.ATTACHMENT]: [PermissionAction.READ],
        },
      },
    ],
  },
  {
    text: "menu.manage_subscribers",
    Icon: faUserCircle,
    submenuItems: [
      {
        text: "menu.subscribers",
        href: "/subscribers",
        Icon: faUserCircle,
        requires: {
          [EntityType.SUBSCRIBER]: [PermissionAction.READ],
        },
      },
      {
        text: "menu.labels",
        href: "/subscribers/labels",
        Icon: faTags,
        requires: {
          [EntityType.LABEL]: [PermissionAction.READ],
        },
      },

      
      // {
      //   text: 'menu.broadcast',
      //   href: "/subscribers/broadcast",
      //   Icon: faBullhorn,
      // },
    ],
  },
  {
    text: "menu.admin",
  },
  {
    text: "menu.manage_users",
    Icon: faUsers,
    submenuItems: [
      {
        text: "menu.users",
        href: "/users",
        Icon: PeopleAltRoundedIcon,
        requires: {
          [EntityType.USER]: [PermissionAction.READ],
        },
      },
      ...(!ssoEnabled
        ? [
            {
              text: "menu.roles",
              href: "/roles",
              Icon: SettingsAccessibilityRoundedIcon,
              requires: {
                [EntityType.ROLE]: [PermissionAction.READ],
              },
            },
          ]
        : []),
    ],
  },
  {
    text: "menu.manage_localization",
    Icon: Language,
    submenuItems: [
      {
        text: "menu.languages",
        href: "/localization/languages",
        Icon: Flag,
        requires: {
          [EntityType.LANGUAGE]: [PermissionAction.READ],
        },
      },
      {
        text: "menu.translations",
        href: "/localization/translations",
        Icon: faLanguage,
        requires: {
          [EntityType.TRANSLATION]: [PermissionAction.READ],
        },
      },
    ],
  },
  {
    text: "menu.settings",
    href: "/settings",
    Icon: faCogs,
    requires: {
      [EntityType.SETTING]: [PermissionAction.READ, PermissionAction.UPDATE],
    },
  },
];

export type VerticalMenuProps = {
  isSideBarOpen: boolean;
  onToggleIn: () => void;
  onToggleOut: () => void;
};

export const VerticalMenu: FC<VerticalMenuProps> = ({
  isSideBarOpen,
  onToggleIn,
  onToggleOut,
}) => {
  const { ssoEnabled } = useConfig();
  const { t } = useTranslate();
  const { isAuthenticated } = useAuth();
  const router = useRouter();
  const hasPermission = useHasPermission();
  const menuItems = getMenuItems(ssoEnabled);
  // Filter menu item to which user is allowed access
  const availableMenuItems = useMemo(() => {
    return menuItems.filter(({ requires: requiredPermissions }) => {
      return (
        !requiredPermissions ||
        Object.entries(requiredPermissions).every((permission) => {
          const entityType = permission[0] as EntityType;
          const actions = permission[1];

          return actions.every((action) => hasPermission(entityType, action));
        })
      );
    });
  }, [t, hasPermission]);
  const hasTemporaryDrawer =
    getLayout(router.pathname.slice(1)) === "full_width";

  return isAuthenticated ? (
    <Drawer
      open={isSideBarOpen}
      ModalProps={{
        open: isSideBarOpen && hasTemporaryDrawer,
        keepMounted: true,
      }}
      variant={hasTemporaryDrawer ? "temporary" : "permanent"}
      onClose={(_, reason) => {
        reason === "backdropClick" && onToggleOut();
      }}
      PaperProps={{
        sx: { borderRadius: "0px" },
      }}
    >
      <StyledDrawerHeader>
        <Grid item xs ml="10px">
          <HexabotLogo />
        </Grid>
        <Grid>
          <IconButton onClick={onToggleOut}>
            <ChevronLeftIcon />
          </IconButton>
        </Grid>
      </StyledDrawerHeader>
      <Sidebar
        menu={availableMenuItems}
        pathname={router.pathname}
        isToggled={isSideBarOpen}
        toggleFunction={() => (isSideBarOpen ? onToggleOut() : onToggleIn())}
      />
    </Drawer>
  ) : null;
};
