import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import {
    Tooltip,
    TooltipContent,
    TooltipTrigger,
} from '@/components/ui/tooltip';
import { avatarUrl, cn, getInitials } from '@/lib/utils';
import type { DivisionTaskAssignee } from '@/types/task';
import type { User } from '@/types/task';

/** Bentuk assignee generik: menerima User (camelCase) atau DivisionTaskAssignee (snake_case). */
type AssigneeLike = User | DivisionTaskAssignee;

function getAssigneeId(assignee: AssigneeLike): string | number {
    return 'user_id' in assignee ? assignee.user_id : assignee.id;
}

function getAssigneeName(assignee: AssigneeLike): string {
    return 'user_name' in assignee ? assignee.user_name : assignee.name;
}

interface AssigneeAvatarStackProps {
    assignees?: AssigneeLike[];
    /** Jumlah avatar yang ditampilkan sebelum diringkas menjadi "+N". Default: 3. */
    max?: number;
    /** Ukuran avatar. 'sm' (size-7) untuk kartu, 'md' (size-8) untuk tabel. Default: 'md'. */
    size?: 'sm' | 'md';
    /** Bila true, nama assignee ditampilkan lewat Tooltip (dipakai di tabel). */
    withTooltip?: boolean;
    /** Teks saat tidak ada assignee. Default: 'Unassigned'. */
    emptyLabel?: string;
    /** Class tambahan untuk teks fallback "Unassigned". */
    emptyClassName?: string;
}

const SIZE_CLASSES = {
    sm: 'size-7 text-[10px]',
    md: 'size-8 text-xs',
} as const;

/**
 * Menampilkan deretan avatar assignee (inisial) yang saling bertumpuk, dengan
 * ringkasan "+N" bila jumlahnya melebihi `max`. Bila tidak ada assignee,
 * menampilkan teks fallback.
 */
export function AssigneeAvatarStack({
    assignees,
    max = 3,
    size = 'md',
    withTooltip = false,
    emptyLabel = 'Unassigned',
    emptyClassName,
}: AssigneeAvatarStackProps) {
    const visibleAssignees = assignees?.slice(0, max) ?? [];
    const hiddenCount = Math.max(
        (assignees?.length ?? 0) - visibleAssignees.length,
        0,
    );

    if (visibleAssignees.length === 0) {
        return (
            <span
                className={cn(
                    'text-xs font-medium text-muted-foreground italic',
                    emptyClassName,
                )}
            >
                {emptyLabel}
            </span>
        );
    }

    const avatarClass = cn(
        'shrink-0 border border-background',
        SIZE_CLASSES[size],
    );
    const fallbackClass = 'bg-primary/10 font-medium text-primary';
    const counterClass = cn(
        'flex shrink-0 items-center justify-center rounded-full border border-background bg-muted font-medium text-muted-foreground',
        SIZE_CLASSES[size],
    );

    return (
        <div className="flex items-center -space-x-2">
            {visibleAssignees.map((assignee) => {
                const id = getAssigneeId(assignee);
                const name = getAssigneeName(assignee);

                // `title` hanya dipasang pada varian tanpa tooltip; kalau
                // keduanya aktif, tooltip Radix dan tooltip bawaan peramban
                // muncul bersamaan menimpa satu sama lain.
                const avatar = (
                    <Avatar
                        key={id}
                        className={avatarClass}
                        title={withTooltip ? undefined : name}
                    >
                        <AvatarImage
                            src={avatarUrl(assignee.avatar)}
                            alt={name}
                        />
                        <AvatarFallback className={fallbackClass}>
                            {getInitials(name)}
                        </AvatarFallback>
                    </Avatar>
                );

                return withTooltip ? (
                    <Tooltip key={id}>
                        <TooltipTrigger asChild>{avatar}</TooltipTrigger>
                        <TooltipContent>
                            <p className="font-medium">{name}</p>
                        </TooltipContent>
                    </Tooltip>
                ) : (
                    avatar
                );
            })}
            {hiddenCount > 0 && (
                <div className={counterClass}>+{hiddenCount}</div>
            )}
        </div>
    );
}
