import _ from "lodash";
import React, { DetailedHTMLProps, ImgHTMLAttributes, ReactNode } from "react";
import { twMerge } from "tailwind-merge";

export type TWUIImageProps = DetailedHTMLProps<
    ImgHTMLAttributes<HTMLImageElement>,
    HTMLImageElement
> & {
    alt: string;
    size?: number;
    circle?: boolean;
    bgImg?: boolean;
    backgroundImage?: boolean;
    fallbackImageSrc?: string;
    srcLight?: string;
    srcDark?: string;
    imgErrSrc?: string;
    imgErrComp?: ReactNode;
    imgErrSrcLight?: string;
    imgErrSrcDark?: string;
};

/**
 * # Image Component
 * @className twui-img
 */
export default function Img({
    imgErrSrc,
    imgErrComp,
    imgErrSrcDark,
    imgErrSrcLight,
    ...props
}: TWUIImageProps) {
    const width = props.size || props.width;
    const height = props.size || props.height;
    const sizeRatio = width && height ? Number(width) / Number(height) : 1;

    const [imageError, setImageError] = React.useState(false);

    const finalProps = _.omit(props, [
        "size",
        "circle",
        "bgImg",
        "backgroundImage",
        "fallbackImageSrc",
        "srcLight",
        "srcDark",
    ]);

    const interpolatedProps: typeof props = {
        ...finalProps,
        width: width,
        height: height,
        className: twMerge(
            "object-cover",
            props.circle && "rounded-full",
            props.bgImg || props.backgroundImage
                ? "absolute top-0 left-0 w-full h-full object-cover z-0"
                : "",
            "twui-img",
            props.className
        ),
        onError: (e) => {
            if (props.fallbackImageSrc) {
                e.currentTarget.src = props.fallbackImageSrc;
            }
            props.onError?.(e);
        },
        style: {
            ...(props.size
                ? {
                      width: `${props.size}px`,
                      minWidth: `${props.size}px`,
                      height: `${props.size}px`,
                  }
                : {}),
            ...props.style,
        },
    };

    if (imageError) {
        return (
            imgErrComp || (
                <img
                    loading="lazy"
                    {...interpolatedProps}
                    src={
                        imgErrSrc ||
                        "https://static.datasquirel.com/images/user-images/user-2/castcord-image-preset_thumbnail.jpg"
                    }
                />
            )
        );
    }

    if (props.srcDark && props.srcLight) {
        return (
            <React.Fragment>
                <img
                    loading="lazy"
                    {...interpolatedProps}
                    className={twMerge(
                        "hidden dark:block",
                        interpolatedProps.className
                    )}
                    src={props.srcDark}
                    onError={(e) => {
                        setImageError(true);
                        props.onError?.(e);
                    }}
                />
                <img
                    loading="lazy"
                    {...interpolatedProps}
                    className={twMerge(
                        "block dark:hidden",
                        interpolatedProps.className
                    )}
                    src={props.srcLight}
                    onError={(e) => {
                        setImageError(true);
                        props.onError?.(e);
                    }}
                />
            </React.Fragment>
        );
    }

    return (
        <img
            {...interpolatedProps}
            onError={(e) => {
                setImageError(true);
                props.onError?.(e);
            }}
        />
    );
}
