import React from 'react';

import type {SelectOption, SelectOptionGroup} from '@gravity-ui/uikit';
import {Select} from '@gravity-ui/uikit';
import block from 'bem-cn-lite';
import {i18n} from 'i18n';
import {getPalettesOrder} from 'shared';
import type {ColorPalette, InternalPaletteId, Palettes} from 'shared';
import {selectAvailableClientPalettes} from 'ui/constants';
import {getDefaultColorPalette, getDefaultPaletteLabel} from 'ui/utils';

import AutogeneratedPaletteIcon from '../AutogeneratedPaletteIcon/AutogeneratedPaletteIcon';
import {PaletteIcon, PaletteType} from '../PaletteIcon/PaletteIcon';
import {SelectOptionWithIcon} from '../SelectComponents';

import './ColorPaletteSelect.scss';

const b = block('color-palette-select');

const getPaletteSelectorItems = ({
    colorPalettes = [],
    withAuto = false,
}: {
    colorPalettes?: ColorPalette[];
    withAuto?: boolean;
}): SelectOptionGroup<{icon: JSX.Element}>[] => {
    const availablePalettes = selectAvailableClientPalettes();
    const palettesOrder = getPalettesOrder();

    const result: SelectOptionGroup<{icon: JSX.Element}>[] = [];

    if (withAuto) {
        const defaultColorPalette = getDefaultColorPalette({colorPalettes});
        const icon =
            'colors' in defaultColorPalette ? (
                <AutogeneratedPaletteIcon
                    colors={defaultColorPalette.colors}
                    height="16px"
                    width="20px"
                />
            ) : (
                <PaletteIcon
                    paletteType={PaletteType.ColorPalette}
                    paletteId={defaultColorPalette.id}
                />
            );

        result.push({
            label: '',
            options: [
                {
                    data: {
                        icon,
                    },
                    content: getDefaultPaletteLabel(defaultColorPalette),
                    value: '',
                },
            ],
        });
    }

    result.push(
        ...palettesOrder.map(
            (paletteName: keyof Palettes): SelectOptionGroup<{icon: JSX.Element}> => {
                const palette = availablePalettes[paletteName];
                const options = palette.map(
                    (item: string): SelectOption<{icon: JSX.Element}> => ({
                        data: {
                            icon: (
                                <PaletteIcon
                                    paletteType={PaletteType.ColorPalette}
                                    paletteId={item}
                                />
                            ),
                        },
                        content: i18n('wizard.palette', `label_${item as InternalPaletteId}`),
                        value: item,
                        qa: item,
                    }),
                );

                return {
                    label: '',
                    options,
                };
            },
        ),
    );

    if (colorPalettes.length) {
        return result.concat({
            label: '',
            options: colorPalettes.map(
                (colorPalette): SelectOption<{icon: JSX.Element}> => ({
                    data: {
                        icon: (
                            <AutogeneratedPaletteIcon
                                colors={colorPalette.colors}
                                height="16px"
                                width="20px"
                            />
                        ),
                    },
                    content: colorPalette.displayName,
                    value: colorPalette.colorPaletteId,
                }),
            ),
        });
    }

    return result;
};

type Props = {
    colorPalettes: ColorPalette[];
    onUpdate: (value: string[]) => void;
    value: string;
    disabled?: boolean;
    className?: string;
    qa?: string;
    withAuto?: boolean;
};

export const ColorPaletteSelect = (props: Props) => {
    const {colorPalettes, value, disabled, className, qa, withAuto, onUpdate} = props;

    const options = getPaletteSelectorItems({colorPalettes, withAuto});

    return (
        <Select
            options={options}
            onUpdate={onUpdate}
            value={[value]}
            renderSelectedOption={(option) => {
                return <SelectOptionWithIcon option={option} />;
            }}
            renderOption={(option) => {
                return <SelectOptionWithIcon option={option} />;
            }}
            popupClassName={b('popup')}
            className={b(null, className)}
            disabled={disabled}
            qa={qa}
        />
    );
};
