import type { ComponentProps } from 'react';
import { useEffect, useState } from 'react';
import { isSvgImageUrl } from '@/lib/is-svg-image-url';
import { cn } from '@/lib/utils';

const maskStyle = (imageUrl: string): ComponentProps<'span'>['style'] => ({
    WebkitMaskImage: `url("${imageUrl}")`,
    maskImage: `url("${imageUrl}")`,
    WebkitMaskSize: 'contain',
    maskSize: 'contain',
    WebkitMaskRepeat: 'no-repeat',
    maskRepeat: 'no-repeat',
    WebkitMaskPosition: 'center',
    maskPosition: 'center',
});

type VehicleSizeCategoryIconProps = {
    imageUrl: string | null;
    name: string;
    emojiFallback?: string | null;
    /** Icon dimensions (default size-10). */
    className?: string;
    /** Applied to SVG mask tint via text-* (e.g. text-primary). */
    colorClassName?: string;
    /** Rounded tile behind icon for contrast in tables. */
    withTile?: boolean;
};

export function VehicleSizeCategoryIcon({
    imageUrl,
    name,
    emojiFallback = '🚗',
    className = 'size-10',
    colorClassName = 'text-foreground',
    withTile = false,
}: VehicleSizeCategoryIconProps) {
    const [imageFailed, setImageFailed] = useState(false);

    useEffect(() => {
        setImageFailed(false);
    }, [imageUrl]);

    const tileClassName =
        'flex shrink-0 items-center justify-center rounded-md border border-border/70 bg-muted/70 p-1 shadow-sm';

    const emoji = (
        <span
            className={cn(
                'flex items-center justify-center text-xl leading-none',
                className,
            )}
            aria-hidden
        >
            {emojiFallback ?? '🚗'}
        </span>
    );

    if (!imageUrl || imageFailed) {
        if (!withTile) {
            return emoji;
        }

        return <span className={cn(tileClassName, className)}>{emoji}</span>;
    }

    const icon = isSvgImageUrl(imageUrl) ? (
        <>
            <img
                src={imageUrl}
                alt=""
                aria-hidden
                className="sr-only"
                onError={() => setImageFailed(true)}
            />
            <span
                role="img"
                aria-label={name}
                className={cn('block size-full bg-current', colorClassName)}
                style={maskStyle(imageUrl)}
            />
        </>
    ) : (
        <img
            src={imageUrl}
            alt={name}
            className="size-full object-contain"
            onError={() => setImageFailed(true)}
        />
    );

    if (!withTile) {
        return <span className={cn('block', className)}>{icon}</span>;
    }

    return (
        <span className={cn(tileClassName, className)}>
            <span className="relative size-7">{icon}</span>
        </span>
    );
}
