// frontend/src/components/Avatar.tsx

import type { ImgHTMLAttributes } from 'react'

export type AvatarSize = 6 | 8 | 9 | 10 | 12 | 14 | 16
export type AvatarShape = 'circle' | 'rounded'
export type AvatarStatus = 'gray' | 'red' | 'green'
export type AvatarStatusPosition = 'top' | 'bottom'

export type AvatarProps = Omit<ImgHTMLAttributes<HTMLImageElement>, 'size'> & {
  src?: string
  name?: string
  initials?: string
  size?: AvatarSize
  shape?: AvatarShape
  status?: AvatarStatus
  statusPosition?: AvatarStatusPosition
  /**
   * Online-Status der Person. true = online (grün), false = offline (grau).
   * Wird ignoriert, wenn `status` explizit gesetzt ist.
   */
  online?: boolean
  showPlaceholderIcon?: boolean
  wrapperClassName?: string
}

function classNames(...classes: Array<string | false | null | undefined>) {
  return classes.filter(Boolean).join(' ')
}

const sizeClassNames: Record<AvatarSize, string> = {
  6: 'size-6',
  8: 'size-8',
  9: 'size-9',
  10: 'size-10',
  12: 'size-12',
  14: 'size-14',
  16: 'size-16',
}

const initialsSizeClassNames: Record<AvatarSize, string> = {
  6: 'text-xs',
  8: 'text-sm',
  9: 'text-sm',
  10: 'text-base',
  12: 'text-lg',
  14: 'text-xl',
  16: 'text-2xl',
}

const statusSizeClassNames: Record<AvatarSize, string> = {
  6: 'size-1.5',
  8: 'size-2',
  9: 'size-2',
  10: 'size-2.5',
  12: 'size-3',
  14: 'size-3.5',
  16: 'size-4',
}

const statusColorClassNames: Record<AvatarStatus, string> = {
  gray: 'bg-gray-300 dark:bg-gray-500',
  red: 'bg-red-400 dark:bg-red-500',
  green: 'bg-green-400 dark:bg-green-500',
}

function getInitials(name?: string, initials?: string) {
  if (initials) {
    return initials.slice(0, 2).toUpperCase()
  }

  if (!name) {
    return ''
  }

  return name
    .split(/\s+/)
    .filter(Boolean)
    .slice(0, 2)
    .map((part) => part.charAt(0))
    .join('')
    .toUpperCase()
}

function PlaceholderIcon({ className }: { className?: string }) {
  return (
    <svg
      fill="currentColor"
      viewBox="0 0 24 24"
      className={className}
      aria-hidden="true"
    >
      <path d="M24 20.993V24H0v-2.996A14.977 14.977 0 0 1 12.004 15c4.904 0 9.26 2.354 11.996 5.993zM16.002 8.999a4 4 0 1 1-8 0 4 4 0 0 1 8 0z" />
    </svg>
  )
}

export default function Avatar({
  src,
  alt,
  name,
  initials,
  size = 10,
  shape = 'circle',
  status,
  statusPosition = 'bottom',
  online,
  showPlaceholderIcon = true,
  wrapperClassName,
  className,
  ...props
}: AvatarProps) {
  const roundedClassName = shape === 'circle' ? 'rounded-full' : 'rounded-md'
  const avatarInitials = getInitials(name, initials)

  // `status` hat Vorrang; ansonsten leitet sich der Punkt aus `online` ab.
  const effectiveStatus: AvatarStatus | undefined =
    status ?? (online === undefined ? undefined : online ? 'green' : 'gray')
  const statusLabel =
    online === undefined ? undefined : online ? 'Online' : 'Offline'

  const avatar = src ? (
    <img
      {...props}
      src={src}
      alt={alt ?? name ?? ''}
      className={classNames(
        'inline-block bg-gray-100 outline -outline-offset-1 outline-black/5 dark:bg-gray-800 dark:outline-white/10',
        sizeClassNames[size],
        roundedClassName,
        className,
      )}
    />
  ) : avatarInitials ? (
    <span
      className={classNames(
        'inline-flex items-center justify-center bg-gray-500 outline -outline-offset-1 outline-black/5 dark:bg-gray-800 dark:outline-white/10',
        sizeClassNames[size],
        roundedClassName,
        className,
      )}
      aria-label={name}
    >
      <span
        className={classNames(
          'font-medium text-white',
          initialsSizeClassNames[size],
        )}
      >
        {avatarInitials}
      </span>
    </span>
  ) : (
    <span
      className={classNames(
        'inline-block overflow-hidden bg-gray-100 outline -outline-offset-1 outline-black/5 dark:bg-gray-800 dark:outline-white/10',
        sizeClassNames[size],
        roundedClassName,
        className,
      )}
      aria-label={name}
    >
      {showPlaceholderIcon && (
        <PlaceholderIcon className="size-full text-gray-300 dark:text-gray-600" />
      )}
    </span>
  )

  if (!effectiveStatus) {
    return avatar
  }

  return (
    <span className={classNames('relative inline-block', wrapperClassName)}>
      {avatar}

      <span
        role={statusLabel ? 'status' : undefined}
        aria-label={statusLabel}
        title={statusLabel}
        className={classNames(
          'absolute right-0 block rounded-full ring-2 ring-white dark:ring-gray-900',
          statusPosition === 'top' ? 'top-0' : 'bottom-0',
          statusSizeClassNames[size],
          statusColorClassNames[effectiveStatus],
          shape === 'rounded' &&
            statusPosition === 'top' &&
            'translate-x-1/2 -translate-y-1/2 transform',
          shape === 'rounded' &&
            statusPosition === 'bottom' &&
            'translate-x-1/2 translate-y-1/2 transform',
        )}
      />
    </span>
  )
}