import React from 'react';
import { twMerge } from 'tailwind-merge';
import style from '../../../style';
import clsx from 'clsx';
import { isString } from 'lodash';

export interface Option<T> {
    /**
     * Value of the select option.
     */
    value: T;
    /**
     * Text of the select option.
     */
    label: string;
    /**
     * Icon of the select option. Imported from carbon icons
     */
    icon?: any;
}

export interface InputSelectProps {
    /**
     * Input Ref .
     */
    ref?: React.Ref<HTMLSelectElement>;
    /**
     * Input variation that will switch between styles for the Input .
     */
    variation?: 'default' | 'primary' | 'secondary';
    /**
     * Options for the select, array of strings or an array of Option type
     */
    options: string[] | Option<string | number | readonly string[] | undefined>[];
}

export const InputSelect: React.FC<InputSelectProps & React.InputHTMLAttributes<HTMLSelectElement>> = React.forwardRef(
    (props, ref) => {
        const { title, className, options, variation, value, disabled } = props;
        const elementProps = Object.assign({}, props);

        const variationClasses = clsx({
            [style.input.default]: variation === 'default',
            [style.input.primary]: variation === 'primary',
            [style.input.secondary]: variation === 'secondary',
        });

        const classesMerged = `${style.input?.init} ${variationClasses} ${className ? className : ''} ${
            disabled ? 'opacity-60 cursor-not-allowed' : ''
        }`;

        return (
            <select
                ref={ref}
                {...elementProps}
                className={twMerge(classesMerged)}
                aria-label={title}
                title={title}
                value={value}
            >
                {options.map((option: string | Option<string | number | readonly string[] | undefined>, index) => {
                    const value = isString(option) ? option : option.value;
                    const label = isString(option) ? option : option.label;
                    return (
                        <option key={value + label + index} value={value}>
                            {label}
                        </option>
                    );
                })}
            </select>
        );
    },
);

export default InputSelect;
