import { MAX_ARTICLES_DEPTH } from '@composed-components/LibrariesSidebar/constants';
import {
  type LibrariesTreeItem,
  type SortedItem,
  type SortOrder,
} from '@composed-components/LibrariesSidebar/types';
import {
  type SidebarCapabilities,
  type SidebarNode,
} from '@composed-components/LibrariesSidebar/types/model';
import { type AvatarProps } from '@design-system/Avatar/types';
import { type UniqueIdentifier } from '@dnd-kit/core';
import { arrayMove } from '@dnd-kit/sortable';
import { IconType } from '@src/types/icons';
import { IconGripVertical } from '@tabler/icons-react';

import { AVATAR_STYLES } from '../styles';

export const toLibrariesTreeItem = (
  node: SidebarNode,
  capabilities: SidebarCapabilities,
): LibrariesTreeItem => ({
  id: node.id,
  title: node.title,
  icon: node.icon,
  position: node.position,
  parentId: node.parentId,
  isActive: node.status === 'enabled',
  hasChildren: node.childCount > 0,
  hasReachedLimit: node.depth >= MAX_ARTICLES_DEPTH,
  showBadge: capabilities.showStatusBadge,
  hideCreateButton: !capabilities.canCreate,
});

export const getAvatarConfig = (
  item: LibrariesTreeItem,
  showDragIcon?: boolean,
): AvatarProps => {
  const color = item.isActive ? 'success' : 'disabled';

  const isImage = item.icon.type === IconType.IMAGE;
  const isEmoji = item.icon.type === IconType.EMOJI;

  if (showDragIcon) return { Icon: IconGripVertical };

  return {
    withBadge: item.showBadge,
    badgeProps: { color },
    variant: 'square',
    color: 'white',
    src: isImage ? item.icon.value : undefined,
    text: isEmoji ? item.icon.value : undefined,
    sx: AVATAR_STYLES,
  };
};

export const getLeftSpacing = (depth: number) => 2 + depth * 2;

export const getCursorMode = (isSortMode: boolean, isDragging?: boolean) => {
  if (isDragging) return 'grabbing';
  if (isSortMode) return 'grab';
  return 'pointer';
};

export const getReorderedItems = (
  items: LibrariesTreeItem[],
  active: UniqueIdentifier,
  over: UniqueIdentifier | null,
) => {
  if (over == null || active === over) return items;

  const oldIndex = items.findIndex(item => item.id === active);
  const newIndex = items.findIndex(item => item.id === over);

  if (oldIndex === -1 || newIndex === -1) return items;

  return arrayMove(items, oldIndex, newIndex);
};

/**
 * Adapt the sidebar's `onSort` payload into the `{ parentId, orderedIds }`
 * shape backends typically expect for a bulk reorder.
 */
export const getNewPositionOrders = (payload: SortedItem[]): SortOrder[] =>
  payload.map(order => ({
    parentId: order.parentId,
    orderedIds: order.items.map(item => item.id),
  }));
