import { css, CSSProperties } from 'glamor';
import { observer } from 'mobx-react';
import { useApphouse } from '../context/useApphouse';
import {
  BoxSizeStyles,
  ButtonStyleVariant
} from '../styles/defaults/themes.interface';
import React from 'react';
import { StyleOverwrites } from './component.interfaces';
import { useLocalStyles } from '../styles/defaults/useLocalStyles';
import { merge } from '..';
import { getSelectCustomStyle } from '../styles/getSelectCustomStyle';
import { toRems } from '../utils/units/toRems';

export interface SelectStyles {
  container?: CSSProperties;
  select?: CSSProperties;
  option?: CSSProperties;
}

export interface SelectOption {
  label: string;
  value: string;
}

export interface SelectProps extends StyleOverwrites<SelectStyles> {
  variant?: keyof ButtonStyleVariant;
  size?: keyof BoxSizeStyles;
  children?: React.ReactNode;
  options?: SelectOption[];
  onChange: (value: string) => void;
  value?: string;
  disabled?: boolean;
  id: string;
}

/**
 * A select component built on top of the native select component
 * just with a few style overwrites
 */
export const Select = observer((props: SelectProps) => {
  const {
    id,
    variant = 'select',
    children,
    disabled = false,
    options,
    onChange,
    size = 'm',
    value,
    styleOverwrites
  } = props;
  const { theme } = useApphouse();
  const { styles } = theme;

  const boxSizeStyles = styles.boxSize[size];
  const buttonStyles =
    variant === 'select' ? styles.input[size] : styles.button[variant];
  const optionStyles = styles.input[size];
  const customSelect = getSelectCustomStyle(buttonStyles.color, size);

  // The padding on the right is to allow the ellipsis to not overlap the arrow
  const paddingRight = parseInt(`${boxSizeStyles.paddingRight || 0}`) + 50;
  const selectStyles = merge(
    {},
    styles.button.select,
    boxSizeStyles,
    customSelect,
    {
      backgroundColor: buttonStyles.backgroundColor,
      border: buttonStyles.border,
      borderRadius: buttonStyles.borderRadius,
      color: buttonStyles.color,
      overflow: 'hidden',
      paddingRight: toRems(paddingRight), // take into account the arrow
      textOverflow: 'ellipsis',
      whiteSpace: 'nowrap'
    }
  );

  const containerStyles = merge(
    {},
    {
      color: 'inherit',
      position: 'relative'
    }
  );
  const componentStyles = merge(
    {},
    {
      container: containerStyles,
      select: selectStyles,
      option: optionStyles
    }
  );
  const localStyles = useLocalStyles(componentStyles, styleOverwrites);

  return (
    <div
      {...css(localStyles.container)}
      data-id={`Select-${id}`}
      data-xray="Select"
      data-style="container"
    >
      <select
        id={id}
        disabled={disabled}
        value={value}
        onChange={(e) => {
          const v = e.target.value;
          if (v) {
            onChange(v);
          }
        }}
        data-style="select"
        {...css(localStyles.select)}
      >
        {options?.map((option) => {
          return (
            <option
              key={option.value}
              value={option.value}
              data-style="option"
              {...css(localStyles.option)}
            >
              {option.label}
            </option>
          );
        })}
      </select>
      {children}
    </div>
  );
});
