/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable react/jsx-key */
import { clsx } from 'clsx';
import { CommonProps } from '../common';
import AvatarView, { AvatarViewProps } from '../avatarView';

type AvatarType = { asset?: AvatarViewProps['children'] } & Omit<
  AvatarViewProps,
  'notification' | 'selected' | 'size' | 'badge' | 'action' | 'children'
>;
type AvatarGroupOrientation = 'horizontal' | 'diagonal';
type AvatarGroupDiagonalSize = 24 | 32 | 40 | 48 | 56 | 72;
type AvatarGroupSize = 16 | AvatarGroupDiagonalSize;

/**
 * Diagonal avatar groups have custom styles for avatars, icons, and fonts
 */
const MAP_DIAGONAL_AVATAR_STYLE = {
  16: { avatar: 0, icon: 0, font: 0 },
  24: { avatar: 15, icon: 11.25, font: 8 },
  32: { avatar: 20, icon: 15, font: 12 },
  40: { avatar: 24, icon: 18, font: 12 },
  48: { avatar: 30, icon: 16.88, font: 14 },
  56: { avatar: 34, icon: 19.13, font: 14 },
  72: { avatar: 44, icon: 22, font: 22 },
};

const MAP_DIAGONAL_AVATAR_POSITION = {
  24: 9,
  32: 12,
  40: 16,
  48: 18,
  56: 22,
  72: 28,
};

/**
 * AvatarGroup size: Avatar position (px)
 */
const MAP_HORIZONTAL_AVATAR_POSITION = {
  16: 2,
  24: 2,
  32: 7,
  40: 4,
  48: 4,
  56: 6,
  72: 8,
};

export type Props = {
  'aria-label'?: string;
  avatars: AvatarType[];
  orientation?: AvatarGroupOrientation;
  size?: AvatarGroupSize;
  interactive?: boolean;
} & CommonProps;

export default function AvatarGroup({
  avatars,
  orientation = 'horizontal',
  size: groupSize = 48,
  'aria-label': ariaLabel,
  className,
  interactive,
}: Props) {
  const isDiagonal = orientation === 'diagonal';
  const singleAvatarSize = isDiagonal ? MAP_DIAGONAL_AVATAR_STYLE[groupSize]?.avatar : groupSize;
  return (
    <div
      className={clsx('np-avatar-group', `np-avatar-group-${orientation}`, className)}
      style={{
        // @ts-expect-error `--np-avatar-group-size` exsits in styles of AvatarGroup
        '--np-avatar-group-size': `${groupSize}px`,
        '--np-avatar-group-single-size': `${singleAvatarSize}px`,
      }}
      aria-label={ariaLabel}
    >
      {avatars.length < 2 ||
      ((groupSize === 16 || avatars.length > 2) && orientation === 'diagonal')
        ? null
        : avatars.map((avatar, index) => (
            <div
              className={clsx(
                { [`np-avatar-group-${orientation}-child`]: index !== 0 },
                { [`np-avatar-group-${orientation}-mask`]: index !== avatars.length - 1 },
              )}
              style={{
                // @ts-expect-error CSS custom props allowed
                '--np-avatar-group-diagonal-child-position': `${MAP_DIAGONAL_AVATAR_POSITION[groupSize]}px`,
                '--np-avatar-group-horizontal-child-position': `${MAP_HORIZONTAL_AVATAR_POSITION[groupSize]}px`,
              }}
            >
              <AvatarView
                {...avatar}
                // @ts-expect-error AvatarGroup has custom sizes for it's avatars
                size={singleAvatarSize}
                style={{
                  ...(interactive && {
                    '--circle-border-width': 0,
                    backgroundColor: 'var(--color-background-neutral)',
                  }),
                  // diagonal AvatarGroup variant uses custom sizes for it's avatars, icons, and font
                  ...(isDiagonal && {
                    '--circle-size': `${singleAvatarSize}px`,
                    '--circle-icon-size': `${MAP_DIAGONAL_AVATAR_STYLE[groupSize].icon}px`,
                    '--circle-font-size': `${MAP_DIAGONAL_AVATAR_STYLE[groupSize].font}px`,
                  }),
                  ...avatar.style,
                }}
              >
                {avatar.asset}
              </AvatarView>
            </div>
          ))}
    </div>
  );
}
