/* eslint-disable no-param-reassign */

import React from 'react';

const Gutter = 12;
const SIZES = ['', 'xs', 'sm', 'md', 'lg', 'xl'];
const SIZE_MAP = {
  xs: 4,
  sm: 8,
  '': 12,
  md: 12,
  lg: 16,
  xl: 24,
};

const DIRECTIONS = ['t', 'r', 'b', 'l', 'v', 'h'];
const DIRECTION_SUFFIXES = {
  t: 'Top',
  r: 'Right',
  b: 'Bottom',
  l: 'Left',
  v: 'Vertical',
  // h: 'Horizontal',
};

const getFlex = flex => {
  if (typeof flex === 'boolean') {
    return 1;
  }

  if (typeof flex === 'number') {
    return flex;
  }

  return 0;
};

const buildSpacingStyles = ({ props, propPrefix, stylePrefix }) => {
  const style = SIZES.reduce((styles, size) => {
    const pixels = SIZE_MAP[size];
    if (props[propPrefix + size]) {
      styles[stylePrefix] = pixels;
    }

    const directionalStyles = DIRECTIONS.reduce((dirStyles, direction) => {
      const validDirectionProp = props[propPrefix + direction + size];
      if (validDirectionProp) {
        const styleKey = stylePrefix + DIRECTION_SUFFIXES[direction];

        return {
          ...dirStyles,
          [styleKey]: pixels,
        };
      }
      return dirStyles;
    }, {});

    return {
      ...styles,
      ...directionalStyles,
    };
  }, {});

  return style;
};

const margin = props => buildSpacingStyles({ props, propPrefix: 'm', stylePrefix: 'margin' });

const padding = props => buildSpacingStyles({ props, propPrefix: 'p', stylePrefix: 'padding' });

const alignment = ({ row, col, v, h, justify, align, flex, collapsed }) => {
  const vprop = row ? 'alignItems' : 'justifyContent';
  const hprop = row ? 'justifyContent' : 'alignItems';
  const styles = {
    flex: getFlex(flex),
    flexDirection: row ? 'row' : 'column',
    [vprop]: v,
    [hprop]: h,
    justifyContent: justify,
    alignItems: align,
  };

  if (row) {
    // styles.marginHorizontal = collapsed ? 0 : -Gutter;
  }

  if (col) {
    // styles.paddingHorizontal = collapsed ? 0 : Gutter;
    styles.flex = typeof col === 'number' ? col : 1;
  }

  return styles;
};

const dimensions = ({ width, height, w, h }) => {
  const style = {};

  if (width || w) {
    style.width = width || w;
  }
  if (height || h) {
    style.height = height || h;
  }

  return style;
};

const border = ({ border }) => {
  if (border) {
    const borderColor = border.color || '#000';
    return {
      borderColor,
      borderWidth: border.width,
      borderTopWidth: border.top || border.width,
      borderBottomWidth: border.bottom || border.width,
      borderLeftWidth: border.left || border.width,
      borderRightWidth: border.right || border.width,
    };
  }
  return '';
};

export default BaseComponent => props => (
  <BaseComponent
    {...props}
    style={{
      ...border(props),
      ...margin(props),
      ...padding(props),
      ...alignment(props),
      ...dimensions(props),
      ...(props.style || {}),
    }}>
    {props.children}
  </BaseComponent>
);
