import type { FC } from 'react';
import React, { useState } from 'react';
import cx from 'classnames';
import { SkeletonLoader } from '../skeletonLoader/skeletonLoader';

const CLASS_NAME = 'CoverArt';
const CLASS_NAME_EMPTY = `${CLASS_NAME}-empty`;
const CLASS_NAME_IMG = `${CLASS_NAME}-image`;

export type CoverArtWidth =
    | '100pct'
    | '20'
    | '30'
    | '40'
    | '50'
    | '60'
    | '70'
    | '80'
    | '120'
    | '160';
export type CoverArtShape = 'square' | 'round' | 'letterbox' | 'landscape';

export interface CoverArtProps {
    children?: React.ReactNode;
    url?: string | null;
    shape?: CoverArtShape;
    width?: CoverArtWidth | number;
    className?: string;
    style?: React.CSSProperties;
    testId?: string;
    lazy?: boolean;
    alt?: string;
    unknown?: boolean;
    loading?: boolean;
    onError?: React.ReactEventHandler<HTMLImageElement>;
    onLoad?: React.ReactEventHandler<HTMLImageElement>;
}

/**
 * CovertArt is our container for products, artists, and videos covers. It provides various sizes and contains a placeholder visual.
 *
 * @type atom
 * @status live
 * @tags visuals
 */
export const CoverArt: FC<CoverArtProps> = ({
    url,
    className,
    style,
    width = 80,
    shape = 'square',
    testId = CLASS_NAME,
    children,
    lazy,
    alt = 'cover art',
    unknown,
    loading = false,
    onError,
    onLoad,
}) => {
    const [empty, setEmpty] = useState(!url);

    React.useEffect(() => {
        setEmpty(!url);
    }, [url]);

    const renderImage = () => {
        if (empty) {
            return (
                <div
                    className={cx(CLASS_NAME_EMPTY, CLASS_NAME_IMG, {
                        [`${CLASS_NAME}-unknown`]: unknown,
                    })}
                />
            );
        }

        return (
            <img
                className={CLASS_NAME_IMG}
                alt={alt}
                src={url || undefined}
                loading={lazy ? 'lazy' : undefined}
                onError={(e) => {
                    setEmpty(true);
                    onError?.(e);
                }}
                onLoad={onLoad}
            />
        );
    };

    const renderLoading = () => {
        const getWidthAndHeight = () => {
            if (width === '100pct') {
                return { width: undefined, height: undefined };
            }

            const widthValue = typeof width === 'number' ? width : Number(width);

            if (shape === 'landscape' || shape === 'letterbox') {
                return {
                    width: widthValue,
                    height: Math.round(widthValue * (9 / 16)), // 16:9 aspect ratio
                };
            }

            return { width: widthValue, height: widthValue };
        };

        return (
            <SkeletonLoader
                shape={shape === 'round' ? 'circle' : 'square'}
                {...getWidthAndHeight()}
            />
        );
    };

    return (
        <div
            data-testid={testId}
            className={cx(CLASS_NAME, className, {
                [shape]: shape,
            })}
            style={{
                width: width === '100pct' ? '100%' : `${width}px`,
                ...style,
            }}
        >
            {/* always render so it can be preloaded */}
            {renderImage()}

            {/* if needed, the skeleton renders above the image */}
            {loading && renderLoading()}

            {children}
        </div>
    );
};
