import clsx from 'clsx';
import type { CSSProperties } from 'react';
import styles from './Avatar.module.css';

export interface AvatarProps {
	src?: string | null;
	alt?: string;
	size?: number;
	fallback?: string;
	status?: 'online' | 'idle' | 'dnd' | 'offline';
	className?: string;
	style?: CSSProperties;
	onClick?: () => void;
}

function getInitials(name: string): string {
	return name
		.split(/\s+/)
		.map((w) => w[0])
		.join('')
		.toUpperCase()
		.slice(0, 2);
}

function stringToColor(str: string): string {
	let hash = 0;
	for (let i = 0; i < str.length; i++) {
		hash = str.charCodeAt(i) + ((hash << 5) - hash);
	}
	const hue = Math.abs(hash % 360);
	return `hsl(${hue}, 60%, 50%)`;
}

function getStatusGeometry(avatarSize: number): { dotSize: number; borderWidth: number; offset: number } {
	if (avatarSize <= 16) return { dotSize: 8, borderWidth: 0, offset: -1 };
	if (avatarSize <= 20) return { dotSize: 8, borderWidth: 0, offset: -1 };
	if (avatarSize <= 24) return { dotSize: 10, borderWidth: 2, offset: -2 };
	if (avatarSize <= 32) return { dotSize: 10, borderWidth: 3, offset: -3 };
	if (avatarSize <= 36) return { dotSize: 10, borderWidth: 3, offset: -3 };
	if (avatarSize <= 40) return { dotSize: 12, borderWidth: 3, offset: -3 };
	if (avatarSize <= 48) return { dotSize: 14, borderWidth: 3, offset: -3 };
	if (avatarSize <= 56) return { dotSize: 16, borderWidth: 3, offset: -3 };
	if (avatarSize <= 80) return { dotSize: 16, borderWidth: 6, offset: -4 };
	return { dotSize: 24, borderWidth: 8, offset: -6 };
}

export function Avatar({ src, alt = '', size = 40, fallback, status, className, style, onClick }: AvatarProps) {
	const initials = fallback ? getInitials(fallback) : alt ? getInitials(alt) : '?';
	const bgColor = stringToColor(fallback || alt || '?');
	const geo = getStatusGeometry(size);

	return (
		<div
			className={clsx(styles.wrapper, className)}
			style={{
				width: size,
				height: size,
				cursor: onClick ? 'pointer' : undefined,
				...style,
			}}
			onClick={onClick}
		>
			{src ? (
				<img src={src} alt={alt} className={styles.image} />
			) : (
				<div
					className={styles.fallback}
					style={{
						width: size,
						height: size,
						backgroundColor: bgColor,
						fontSize: size * 0.4,
						userSelect: 'none',
					}}
				>
					{initials}
				</div>
			)}
			{status && (
				<div
					className={clsx(styles.statusBadge, styles[status])}
					style={{
						width: geo.dotSize,
						height: geo.dotSize,
						borderWidth: geo.borderWidth,
						bottom: geo.offset,
						right: geo.offset,
					}}
				/>
			)}
		</div>
	);
}
