import type { FC } from 'react';
import React from 'react';
import { Illustration } from '@theorchard/suite-icons';
import cx from 'classnames';
import type { IllustrationName, IllustrationProps } from '@theorchard/suite-icons';

const CLASS_NAME = 'InfoMessage';

export interface InfoMessageProps {
    // @deprecated Use `title`
    message?: React.ReactNode;
    className?: string;
    style?: React.CSSProperties;
    testId?: string;
    title?: string;
    description?: string;
    variant?: 'full-page' | 'large' | 'medium' | 'small';
    // @deprecated Use `title` and `description`
    body?: React.ReactNode;
    // @deprecated Use `illustration`
    Icon?: React.FC | React.ReactNode;
    illustration?: IllustrationName;
    // @deprecated Use `variant`
    size?: 'sm' | 'lg';
    /**
     * Width of the component.
     * @default 400
     */
    width?: number | 'auto';
    children?: React.ReactNode;
}

const mapIllustrationSize: Record<string, IllustrationProps['size']> = {
    sm: 100,
    lg: 200,
    'full-page': 200,
    large: 100,
    medium: 100,
    small: 50,
};

interface InfoIllustrationProps extends Pick<InfoMessageProps, 'Icon' | 'illustration'> {
    size: IllustrationProps['size'];
}

const InfoIllustration: React.FC<InfoIllustrationProps> = ({ Icon, illustration, size }) => {
    if (Icon) return typeof Icon === 'function' ? <Icon /> : Icon;
    if (illustration) return <Illustration name={illustration} size={size} />;

    return <Illustration name="emptyState" size={size} />;
};

/**
 * InfoMessage is a notification that appears in the UI to inform users about an empty state or a no result state.
 *
 * @type molecule
 * @status live
 * @tags feedback
 */
export const InfoMessage: FC<InfoMessageProps> = ({
    message,
    className,
    style,
    body,
    Icon,
    testId = CLASS_NAME,
    illustration,
    size,
    variant,
    title,
    description,
    width,
    children,
}) => {
    const infoVariant = variant ?? size ?? 'lg';
    const infoTitle = title ?? message;
    const illustrationSize = mapIllustrationSize[infoVariant] ?? 200;
    const infoDescription = description ?? body;

    const InfoHeader = () => {
        let Header: keyof JSX.IntrinsicElements = 'h4';
        if (infoVariant === 'full-page') Header = 'h1';
        else if (infoVariant === 'lg') Header = 'h1';
        return <Header className={`${CLASS_NAME}-title`}>{infoTitle}</Header>;
    };

    return (
        <div
            className={cx(CLASS_NAME, className, `${CLASS_NAME}-${infoVariant}`)}
            data-testid={testId}
            style={{ width, ...style }}
        >
            <div className={`${CLASS_NAME}-illustration`}>
                <InfoIllustration size={illustrationSize} Icon={Icon} illustration={illustration} />
            </div>
            <div className={`${CLASS_NAME}-content`}>
                <div className={`${CLASS_NAME}-content-text`}>
                    <InfoHeader />
                    <div className={`${CLASS_NAME}-description`}>{infoDescription}</div>
                </div>
                {children && <p className={`${CLASS_NAME}-body`}>{children}</p>}
            </div>
        </div>
    );
};
