import React from 'react';
import cx from 'classnames';
import { upperFirst } from '../../utils';
import { CDN_MANIFEST, CdnAsset } from '../cdnAsset';
import type { CdnAssetProps, Manifest, VariantType } from '../cdnAsset';

export type StoreIcons = Manifest['stores'];
export type StoreIconName = keyof StoreIcons;
export type StoreIconSize<Name extends keyof StoreIcons> = keyof StoreIcons[Name];
export type StoreIconVariant<
    Name extends keyof StoreIcons,
    Size extends keyof StoreIcons[Name],
> = VariantType<StoreIcons[Name][Size]>;

export interface StoreIconProps<
    Name extends keyof StoreIcons,
    Size extends keyof StoreIcons[Name],
    Variant extends VariantType<StoreIcons[Name][Size]>,
> extends Omit<
        CdnAssetProps<'stores', Name, Size, Variant>,
        'category' | 'name' | 'size' | 'height' | 'width'
    > {
    size?: Size;
    name: Name;
    variant?: Variant;
}

export const STORE_ICONS_BY_SIZE = Object.entries(CDN_MANIFEST.stores).reduce(
    (stores, [store, sizes]) => ({
        ...stores,
        [store]: Object.keys(sizes).map((size) => parseInt(size, 10)),
    }),
    {} as Record<string, number[]>
);

/**
 * Store icons visually represent stores we distribute to. They're used in various components such as dropdowns, graphs or tables.
 *
 * @type atom
 * @status live
 * @tags visuals
 */
export function StoreIcon<
    Name extends keyof StoreIcons,
    Size extends keyof StoreIcons[Name],
    Variant extends VariantType<StoreIcons[Name][Size]>,
>({
    size = 16 as Size,
    name,
    testId,
    className,
    variant = 'primary' as Variant,
    ...rest
}: StoreIconProps<Name, Size, Variant>) {
    if (!CDN_MANIFEST.stores?.[name]) return null;

    const iconClass = upperFirst(`${name.toString()}StoreIcon`);

    return (
        <CdnAsset
            {...rest}
            name={name}
            className={cx('StoreIcon', iconClass, className)}
            testId={testId ?? iconClass}
            size={size}
            variant={variant}
            category="stores"
        />
    );
}
