'use client';

import { useEffect, useState, type ReactNode } from 'react';
import { User } from 'lucide-react';
import { getUploadUrl } from '@/lib/api';
import { cn, getInitials } from '@/lib/utils';

export const avatarSizeClasses = {
  xs: 'h-10 w-10 text-xs',
  sm: 'h-12 w-12 text-sm',
  md: 'h-16 w-16 text-lg',
  lg: 'h-20 w-20 text-3xl',
  xl: 'h-24 w-24 text-2xl',
  feed: 'h-11 w-11 text-sm',
  picker: 'h-24 w-24 md:h-28 md:w-28 text-xl md:text-2xl',
} as const;

const iconSizeClasses: Record<keyof typeof avatarSizeClasses, string> = {
  xs: 'h-5 w-5',
  sm: 'h-6 w-6',
  md: 'h-8 w-8',
  lg: 'h-10 w-10',
  xl: 'h-10 w-10',
  feed: 'h-5 w-5',
  picker: 'h-10 w-10 md:h-12 md:w-12',
};

const objectFitClasses = {
  cover: 'object-cover object-center',
  contain: 'object-contain object-center',
} as const;

export interface UserAvatarProps {
  firstName?: string | null;
  lastName?: string | null;
  avatarUrl?: string | null;
  /** Already-resolved image URL (e.g. blob preview). Takes precedence over avatarUrl. */
  imageSrc?: string | null;
  size?: keyof typeof avatarSizeClasses;
  /** Fill the parent container (e.g. card cover). Defaults object-fit to cover. */
  fill?: boolean;
  objectFit?: keyof typeof objectFitClasses;
  className?: string;
  rounded?: 'full' | '2xl' | 'none';
  ringClassName?: string;
  fallback?: ReactNode;
  alt?: string;
}

export function UserAvatar({
  firstName,
  lastName,
  avatarUrl,
  imageSrc,
  size = 'sm',
  fill = false,
  objectFit = 'cover',
  className,
  rounded = 'full',
  ringClassName,
  fallback,
  alt = '',
}: UserAvatarProps) {
  const [imgError, setImgError] = useState(false);
  const resolvedUrl = imageSrc ?? (avatarUrl ? getUploadUrl(avatarUrl) : null);

  useEffect(() => {
    setImgError(false);
  }, [resolvedUrl]);

  const roundedClass =
    rounded === '2xl' ? 'rounded-2xl' : rounded === 'none' ? 'rounded-none' : 'rounded-full';
  const sizeClass = fill ? 'h-full w-full' : avatarSizeClasses[size];
  const fitClass = objectFitClasses[objectFit];
  const initials = getInitials(firstName, lastName);
  const showImage = Boolean(resolvedUrl) && !imgError;

  return (
    <div
      className={cn(
        'relative shrink-0 overflow-hidden',
        sizeClass,
        roundedClass,
        ringClassName,
        className
      )}
      aria-hidden={!alt && !showImage}
    >
      {showImage ? (
        // eslint-disable-next-line @next/next/no-img-element
        <img
          src={resolvedUrl!}
          alt={alt}
          onError={() => setImgError(true)}
          className={cn('h-full w-full', fitClass)}
        />
      ) : (
        <div
          className={cn(
            'flex h-full w-full items-center justify-center bg-[var(--home-ink)] font-bold uppercase tracking-tight text-white',
            fill ? 'text-4xl md:text-5xl' : ''
          )}
        >
          {fallback ??
            (initials ? (
              <span>{initials}</span>
            ) : (
              <User
                className={fill ? 'h-10 w-10 md:h-12 md:w-12' : iconSizeClasses[size]}
                aria-hidden
              />
            ))}
        </div>
      )}
    </div>
  );
}
