import { useMemo } from 'react';

import { IconChevronRight } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';
import { colorPalette } from '@material-hu/theme/hugo/colors';

import HuAlert from '@material-hu/components/design-system/Alert';
import Button from '@material-hu/components/design-system/Buttons/Button';
import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuMenu from '@material-hu/components/design-system/Menu';

import { FlowNode, NodeType, WorkflowJson } from 'src/types/workflows';

import { useLokaliseTranslation } from 'src/utils/i18n';

import { type InvalidNodeInfo } from '../utils';

type InvalidNodesMenuProps = {
  anchorEl: HTMLElement | null;
  invalidNodes: InvalidNodeInfo[];
  workflowBody: WorkflowJson;
  showChangeStatusDrawer: (node?: FlowNode) => void;
  showChangeAssigneeDrawer: (node?: FlowNode) => void;
  showBranchesDrawer: (node?: FlowNode) => void;
  showApprovalDrawer: (node?: FlowNode) => void;
  showTaskDrawer: (node?: FlowNode) => void;
  onClose: () => void;
};

const InvalidNodesMenu = ({
  anchorEl,
  invalidNodes,
  workflowBody,
  showChangeStatusDrawer,
  showChangeAssigneeDrawer,
  showBranchesDrawer,
  showApprovalDrawer,
  showTaskDrawer,
  onClose,
}: InvalidNodesMenuProps) => {
  const { t } = useLokaliseTranslation('workflows');

  const groupedInvalidNodes = useMemo(
    () =>
      invalidNodes.reduce(
        (acc, node) => {
          const typeName = t(`type_${node.type}`);
          if (!acc[typeName]) acc[typeName] = [];
          acc[typeName].push(node);
          return acc;
        },
        {} as Record<string, InvalidNodeInfo[]>,
      ),
    [invalidNodes, t],
  );

  const getNode = (nodeId: string) =>
    workflowBody?.tasks?.find((task: FlowNode) => task.id === nodeId) ||
    workflowBody?.conditionals?.find(
      (conditional: FlowNode) => conditional.id === nodeId,
    );

  const handleNodeClick = (node: InvalidNodeInfo) => {
    onClose();
    const nodeData = getNode(node.id);

    switch (nodeData?.type) {
      case NodeType.CHANGE_ASSIGNEE:
        showChangeAssigneeDrawer(nodeData);
        break;
      case NodeType.CONDITIONAL:
        showBranchesDrawer(nodeData);
        break;
      case NodeType.APPROVAL:
        showApprovalDrawer(nodeData);
        break;
      case NodeType.TASK:
        showTaskDrawer(nodeData);
        break;
      case NodeType.CHANGE_STATE:
      default:
        showChangeStatusDrawer(nodeData);
        break;
    }
  };

  return (
    <HuMenu
      open={Boolean(anchorEl) && invalidNodes.length > 0}
      anchorEl={anchorEl}
      onClose={onClose}
      header={
        <HuAlert
          severity="warning"
          title={t('incomplete_components')}
          sx={{ p: 1, m: 1 }}
        />
      }
      sx={{
        maxWidth: 400,
        '& > .MuiPaper-root': {
          position: 'relative',
          top: '16px',
          left: '-16px',
        },
      }}
    >
      <Stack sx={{ p: 2, gap: 2 }}>
        <Typography
          variant="globalS"
          color={th => th.palette.textColors?.neutralTextLighter}
        >
          {t('incomplete_components_subtitle')}
        </Typography>
        {Object.entries(groupedInvalidNodes).map(([typeName, typeNodes]) => (
          <Stack key={typeName}>
            <Typography
              variant="globalXS"
              color={th => th.palette.textColors?.neutralTextLighter}
              sx={{ mb: 1 }}
            >
              {typeName}
              {typeNodes.length > 1 && ` (${typeNodes.length})`}
            </Typography>
            <Stack sx={{ gap: 1 }}>
              {typeNodes.map(node => (
                <HuCardContainer
                  key={node.id}
                  sx={{
                    border: 'none',
                    backgroundColor: th =>
                      th.palette.hugoBackground?.neutralBgTransparent,
                  }}
                  padding={0}
                  fullWidth
                >
                  <Stack
                    sx={{
                      justifyContent: 'space-between',
                      flexDirection: 'row',
                      alignItems: 'center',
                      p: 1,
                      pl: 2,
                    }}
                  >
                    <Typography
                      variant="globalS"
                      fontWeight="semiBold"
                    >
                      {node.name}
                    </Typography>
                    <Button
                      variant="tertiary"
                      size="small"
                      sx={{
                        minWidth: 30,
                        height: 30,
                        p: 0,
                      }}
                      onClick={() => handleNodeClick(node)}
                    >
                      <IconChevronRight
                        size={18}
                        color={colorPalette.textColors?.neutralText}
                      />
                    </Button>
                  </Stack>
                </HuCardContainer>
              ))}
            </Stack>
          </Stack>
        ))}
      </Stack>
    </HuMenu>
  );
};

export default InvalidNodesMenu;
