import { type FC, useState } from 'react';

import ListItem from '@design-system/List/components/ListItem';
import HuMenu from '@design-system/Menu';
import Tooltip from '@design-system/Tooltip';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import {
  Collapse,
  Divider,
  IconButton,
  Stack,
  Typography,
} from '@mui/material';
import { useTheme } from '@mui/material/styles';
import {
  IconChevronDown,
  IconDotsVertical,
  IconGripVertical,
} from '@tabler/icons-react';

import { type SectionItemProps } from './types';

const NOOP_SORTABLE = {
  setNodeRef: undefined,
  attributes: {},
  listeners: undefined,
  transform: null,
  isDragging: false,
};

const SectionItem: FC<SectionItemProps> = ({
  children,
  title,
  expanded,
  isSelected = false,
  hasError = false,
  errorTooltip,
  onToggleExpand,
  onClick,
  menuOptions,
  footer,
  draggable = false,
  dragId,
  dragData,
  backgroundColor,
  hasDefaultBorder = false,
  ...stackProps
}) => {
  const theme = useTheme();
  const [menuAnchor, setMenuAnchor] = useState<HTMLElement | null>(null);

  const sortable = useSortable({
    id: dragId ?? '',
    data: dragData,
    disabled: !draggable,
  });

  const { setNodeRef, attributes, listeners, transform, isDragging } = draggable
    ? sortable
    : NOOP_SORTABLE;

  const getBorder = () => {
    if (isSelected) {
      return `1px solid ${theme.palette.new.border.neutral.brand}`;
    }
    if (hasError) {
      return `1px solid ${theme.palette.new.border.states.error}`;
    }
    if (hasDefaultBorder) {
      return `1px solid ${theme.palette.new.border.neutral.default}`;
    }
    return '1px solid transparent';
  };

  const handleChevronClick: React.MouseEventHandler = event => {
    event.stopPropagation();
    onToggleExpand(event, !expanded);
  };

  const handleMenuToggle: React.MouseEventHandler<
    HTMLButtonElement
  > = event => {
    event.stopPropagation();
    setMenuAnchor(prev => (prev ? null : event.currentTarget));
  };

  const handleMenuClose = () => {
    setMenuAnchor(null);
  };

  const handleMenuItemClick = (callback: () => void) => () => {
    setMenuAnchor(null);
    callback();
  };

  const style = {
    transform: transform ? CSS.Translate.toString(transform) : undefined,
  } as const;

  const hasMenu = menuOptions && menuOptions.length > 0;

  return (
    <Tooltip
      disableTooltip={!hasError || !errorTooltip}
      description={errorTooltip ?? ''}
      direction="right"
    >
      <Stack
        ref={setNodeRef}
        style={style}
        sx={{
          minWidth: 0,
          width: 1,
          opacity: isDragging ? 0.7 : 1,
          zIndex: isDragging ? 1000 : 1,
        }}
        {...stackProps}
        {...attributes}
        {...listeners}
      >
        <Stack
          sx={{
            minWidth: 0,
            backgroundColor:
              backgroundColor ?? theme.palette.new.background.layout.default,
            border: getBorder,
            borderRadius: 2,
            overflow: 'hidden',
            ...(draggable && {
              '&:hover .drag-handle': { opacity: 1 },
            }),
          }}
        >
          {/* Header */}
          <Stack
            role="button"
            tabIndex={0}
            onClick={onClick}
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              gap: 0.5,
              p: 2,
              cursor: 'pointer',
              userSelect: 'none',
            }}
          >
            {draggable && (
              <Stack
                className="drag-handle"
                sx={{
                  alignItems: 'center',
                  justifyContent: 'center',
                  width: 28,
                  height: 28,
                  borderRadius: '50%',
                  cursor: 'grab',
                  opacity: 0,
                  transition: 'opacity 0.2s',
                  flexShrink: 0,
                  color: hasError
                    ? theme.palette.new.text.feedback.error
                    : theme.palette.new.text.neutral.lighter,
                }}
              >
                <IconGripVertical size={24} />
              </Stack>
            )}

            <Typography
              variant="globalS"
              fontWeight="fontWeightSemiBold"
              sx={{
                flex: 1,
                overflow: 'hidden',
                textOverflow: 'ellipsis',
                whiteSpace: 'nowrap',
                color: hasError
                  ? theme.palette.new.text.feedback.error
                  : theme.palette.new.text.neutral.default,
              }}
            >
              {title}
            </Typography>

            {hasMenu && (
              <IconButton
                size="large"
                onClick={handleMenuToggle}
                sx={{ flexShrink: 0 }}
              >
                <IconDotsVertical size={24} />
              </IconButton>
            )}

            <IconButton
              size="large"
              onClick={handleChevronClick}
              aria-expanded={expanded}
              sx={{ flexShrink: 0 }}
            >
              <IconChevronDown
                size={24}
                style={{
                  transform: expanded ? 'rotate(180deg)' : 'none',
                  transition: 'transform 0.2s',
                }}
              />
            </IconButton>
          </Stack>

          <Collapse
            in={expanded}
            timeout="auto"
            unmountOnExit
          >
            <Stack sx={{ px: 2, pb: 2 }}>
              {children}
              {footer && (
                <>
                  <Divider sx={{ my: 1 }} />
                  {footer}
                </>
              )}
            </Stack>
          </Collapse>
        </Stack>

        {hasMenu && (
          <HuMenu
            anchorEl={menuAnchor}
            open={Boolean(menuAnchor)}
            onClose={handleMenuClose}
          >
            {menuOptions.map(option => (
              <ListItem
                key={option.title}
                onClick={handleMenuItemClick(option.onClick)}
                disabled={option.disabled}
                text={{ title: option.title }}
                avatar={option.Icon ? { Icon: option.Icon } : undefined}
              />
            ))}
          </HuMenu>
        )}
      </Stack>
    </Tooltip>
  );
};

export type { SectionItemMenuOption, SectionItemProps } from './types';

export default SectionItem;
