import React from 'react';
import { observer } from 'mobx-react';
import { CSSProperties, css } from 'glamor';
import { useApphouse } from '../../context/useApphouse';
import { useLocalStyles } from '../../styles/defaults/useLocalStyles';
import { ApphouseComponent } from '../component.interfaces';
import { InputProps } from './input.interface';
import { Input } from './Input';
import { toRems } from '../../utils/units/toRems';
import { InputComponentStyles } from './input.styles.interface';
import { View } from '../View';
import { merge } from '../..';

export interface InputColorStyles {
  container?: CSSProperties;
  input?: InputComponentStyles;
  colorPicker?: CSSProperties;
  presetButton?: CSSProperties;
}

/**
 * Interface for the preset color option
 */
export interface InputColorPreset {
  value: string;
  label: string;
}
/**
 * Interface for the input color component
 */
export interface InputColorProps
  extends Omit<InputProps, 'styleOverwrites'>,
    ApphouseComponent<InputColorStyles> {
  /**
   * A list of color presets to be displayed in the color picker
   */
  presets?: InputColorPreset[];
}

/**
 * An input component for colors
 */
export const InputColor: React.FC<InputColorProps> = observer((props) => {
  const {
    styleOverwrites,
    gutters,
    id,
    value,
    onChange,
    variant = 'm',
    presets,
    ...rest
  } = props;
  const [color, setColor] = React.useState<string>(`${value}` || '#000000');
  const { theme } = useApphouse();
  const padding = parseInt(theme.styles.boxSize[variant || 'm'].paddingTop) / 2;
  const pickerPos = toRems(padding);
  const pickerSize = getPickerSize(variant);
  const componentStyles: InputColorStyles = {
    container: { position: 'relative' },
    input: {
      input: {
        position: 'relative',
        paddingLeft: toRems(padding + pickerSize + padding)
      }
    },
    colorPicker: {
      position: 'absolute',
      left: pickerPos,
      top: pickerPos,
      backgroundColor: 'transparent',
      borderImageWidth: 0,
      padding: '0px',
      width: toRems(pickerSize),
      height: toRems(pickerSize),
      border: 'none',
      borderRadius: '4px',
      outline: 'none',
      cursor: 'pointer',
      zIndex: 1
    },
    // styles for the preset button
    presetButton: {
      width: toRems(pickerSize),
      height: toRems(pickerSize),
      border: 'none',
      borderRadius: theme.styles.input[variant].borderRadius,
      outline: 'none',
      cursor: 'pointer'
    }
  };

  const localStyles = useLocalStyles<InputColorStyles>(
    componentStyles,
    styleOverwrites,
    gutters
  );

  const handleOnChange = (c: string) => {
    setColor(c);
    onChange && onChange(c);
  };

  return (
    <div {...css(localStyles.container)}>
      <Input
        id={id}
        styleOverwrites={localStyles.input}
        value={color}
        variant={variant}
        onChange={(c) => handleOnChange(c)}
        {...rest}
      >
        <input
          type="color"
          {...css(localStyles.colorPicker)}
          value={color}
          onChange={(e) => handleOnChange(e.target.value)}
        />
      </Input>
      <View>
        {presets?.map((presetColor) => (
          <button
            title={presetColor.label}
            onClick={() => {
              setColor(presetColor.value);
            }}
            {...css(
              merge({}, localStyles.presetButton, {
                backgroundColor: presetColor.value
              })
            )}
          />
        ))}
      </View>
    </div>
  );
});

const getPickerSize = (variant: string) => {
  switch (variant) {
    case 'xs':
      return 20;
    case 's':
      return 24;
    case 'm':
      return 36;
    case 'l':
      return 40;
    case 'xl':
      return 48;
    default:
      return 30;
  }
};
