import Select, { Props, GroupBase, StylesConfig, components } from 'react-select';
import Label from './../../atoms/Label/Label';
import style from '../../../style/';
import Text from '../../atoms/Text';
import { twMerge } from 'tailwind-merge';
import { CSSProperties } from 'react';
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 SelectProps {
    /**
     * Select variation that will switch between styles for the Button .
     */
    variation?: 'initial' | 'default' | 'primary' | 'secondary';
    /**
     * className for the message.
     */
    className?: string;
    /**
     * String text for the label.
     */
    label?: string;
    /**
     * String text for the placeholder or a component element.
     */
    placeholder?: string | React.ReactNode;
    /**
     * Smaller descriptive text that can be added to the input.
     */
    message?: string;
    /**
     * className for the message.
     */
    messageClassName?: string;
}

const InitStyles: CSSProperties = {
    backgroundColor: 'white',
    color: 'black',
    borderColor: 'rgb(229, 231, 235)',
    borderRadius: '0',    
};

const DefaultStyles: CSSProperties = {
    backgroundColor: 'rgb(229, 231, 235)',
    color: 'black',
    borderColor: 'rgb(229, 231, 235)',
    borderRadius: '0',    
};

const PrimaryStyles: CSSProperties = {
    backgroundColor: 'rgb(61, 90, 254)',
    color: 'white',
    borderColor: 'rgb(61, 90, 254)',
    borderRadius: '0',    
};

const SecondaryStyles: CSSProperties = {
    backgroundColor: 'black',
    color: 'white',
    borderColor: 'black',
    borderRadius: '0',    
};

export const SelectWrap = <
    Option,
    IsMulti extends boolean = false,
    Group extends GroupBase<Option> = GroupBase<Option>,
>(
    props: Props<Option, IsMulti, Group> & SelectProps,
) => {
    const { message, messageClassName, variation, className } = props;

    const elementProps = Object.assign({}, props);
    delete elementProps.message;
    delete elementProps.messageClassName;

    const variationStyles = ()=> {
        switch (variation) {
            case 'primary':
                return PrimaryStyles
            case 'secondary':
                return SecondaryStyles
            case 'default':
                return DefaultStyles
            default:
                return InitStyles;
        }
    }


    const selectStyle: StylesConfig<Option, IsMulti, Group> = {
        singleValue: (provided) => ({
            ...provided,
            color: variation === 'primary' || variation ==='secondary' ? 'white' :'black',
        }),
        control: (provided, state) => {
          const { selectProps } = state;
          const customControlStyles = variationStyles();
          return {
            ...provided,
            ...customControlStyles
          };
        },
        multiValue:  (provided) => {
            return {
                ...provided,  backgroundColor: 'inherit'
            }
        },
        multiValueLabel:  (provided) => {
            return {
                ...provided,  color: 'inherit'
            }
        },
        multiValueRemove: (provided) => {
            return {
                ...provided,  ':hover': {
                    backgroundColor: '#b2b2b230',
                },
                marginLeft: '0.2rem',
            }
        }

      };

    const { Option } = components;
      const IconOption = props => (
        <Option {...props}>
          <div className='flex items-center w-full'>
            {props.data.icon && <div className='mr-1'>{props.data.icon}</div>}
            {props.data.label}
          </div>
        </Option>
    );

    const { SingleValue } = components;
      const SingleValueElement = props => (
        <SingleValue {...props}>
          <div className='flex items-center w-full'>
            {props.data.icon && <div className='mr-1'>{props.data.icon}</div>}
            {props.data.label}
          </div>
        </SingleValue>
    );

    const { MultiValue } = components;
      const MultiValueElement = props => (
        <MultiValue {...props}>
          <div className='flex items-center w-full'>
            {props.data.icon && <div className='mr-1'>{props.data.icon}</div>}
            {props.data.label}
          </div>
        </MultiValue>
    );
   
    
    return (
        <>
            {props.label && <Label className={style.label}>{props.label}</Label>}
            <Select
                {...props}
                styles={selectStyle}
                className={twMerge(`react-select flex-auto relative z-auto ${className}`)}
                theme={(theme) => ({ ...theme, borderRadius: 0 })}
                components={{ Option: IconOption, SingleValue: SingleValueElement, MultiValue: MultiValueElement }}
            />
            {message ? (
                <Text className={`inline-flex py-2 text-xs font-light ${messageClassName ?? ''}`}>{message}</Text>
            ) : (
                ''
            )}
        </>
    );
};

SelectWrap.displayName = 'Select';

export default SelectWrap;
