var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

import React, { Component } from 'react';
import { findDOMNode } from 'react-dom';
import { ThemeContext } from 'styled-components';
import { Box } from 'grommet/es6/components/Box';
import { Keyboard } from 'grommet/es6/components/Keyboard';
import { normalizeColor } from 'grommet/es6/utils';
import { parseMetricToNum } from 'grommet/es6/utils';

import { StyledColors, StyledColor, StyledColorContainer, StyledRow, StyledRows } from './StyledColors';

var buildState = function buildState(props) {
  var colors = props.colors,
      color = props.color,
      columns = props.columns,
      wrap = props.wrap;

  var colorRows = [];
  var lastRow = null;
  if (colors) {
    Object.keys(colors).forEach(function (item) {
      if (_typeof(colors[item]) === 'object') {
        var row = { name: item, colors: [] };
        Object.keys(colors[item]).forEach(function (colorName) {
          var colorsColor = colors[item][colorName];
          row.colors.push({ name: colorName, color: colorsColor });
        });
        colorRows.push(row);
      } else {
        if (!lastRow) {
          lastRow = { name: undefined, colors: [] };
          colorRows.push(lastRow);
        }
        lastRow.colors.push({ name: item, color: colors[item] });
      }
    });
  }
  var colorsPerRow = columns || (colorRows.length === 1 ? Math.sqrt(colorRows[0].colors.length) : colorRows.reduce(function (res, row) {
    return Math.min(res, row.colors.length);
  }, Number.MAX_SAFE_INTEGER));
  var wrapColors = wrap;
  if (wrapColors === undefined) {
    wrapColors = columns === undefined && colorRows.length === 1;
  }
  if (wrapColors) {
    var finalRows = [];
    colorRows.forEach(function (row) {
      while (row.colors.length > 0) {
        finalRows.push({ name: row.name, colors: row.colors.splice(0, colorsPerRow) });
      }
    });
    colorRows = finalRows;
  } else {
    colorRows = colorRows.map(function (row) {
      return _extends({}, row, { colors: row.colors.filter(function (_, index) {
          return index < colorsPerRow;
        }) });
    });
  }
  var activeRow = 0;
  var activeColor = 0;
  colorRows.find(function (row, rowIndex) {
    return row.colors.find(function (item, colorIndex) {
      var found = item.color === color;
      if (found) {
        activeRow = rowIndex;
        activeColor = colorIndex;
      }
      return found;
    });
  });
  return { colorRows: colorRows, activeRow: activeRow, activeColor: activeColor };
};

var Colors = function (_Component) {
  _inherits(Colors, _Component);

  function Colors(props) {
    _classCallCheck(this, Colors);

    var _this = _possibleConstructorReturn(this, _Component.call(this, props));

    _this.setActive = function (_ref) {
      var rowIndex = _ref.rowIndex,
          colorIndex = _ref.colorIndex;
      var colorRows = _this.state.colorRows;

      _this.setFocus = true;
      var activeRow = Math.min(Math.max(0, rowIndex), colorRows.length - 1);
      var color = Math.max(0, colorIndex);
      var activeColor = Math.min(color, colorRows[activeRow].colors.length - 1);
      _this.setState({
        activeRow: activeRow,
        activeColor: activeColor
      });
    };

    _this.onClickColor = function (_ref2) {
      var color = _ref2.color,
          rowIndex = _ref2.rowIndex,
          colorIndex = _ref2.colorIndex,
          rowName = _ref2.rowName,
          colorName = _ref2.colorName;
      return function () {
        var onSelect = _this.props.onSelect;

        _this.setActive({ rowIndex: rowIndex, colorIndex: colorIndex });
        if (onSelect) {
          onSelect({ color: color, rowName: rowName, colorName: colorName });
        }
      };
    };

    _this.state = buildState(props);
    return _this;
  }

  Colors.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
    this.setState(buildState(nextProps));
  };

  Colors.prototype.componentDidUpdate = function componentDidUpdate() {
    if (this.setFocus) {
      var _state = this.state,
          activeRow = _state.activeRow,
          activeColor = _state.activeColor,
          colorRows = _state.colorRows;


      this.setFocus = false;
      if (colorRows[activeRow] && colorRows[activeRow].colors[activeColor] && colorRows[activeRow].colors[activeColor].buttonRef) {
        var buttonNode = findDOMNode(colorRows[activeRow].colors[activeColor].buttonRef);
        if (buttonNode) {
          buttonNode.scrollIntoView();
          buttonNode.focus();
        }
      }
    }
  };

  Colors.prototype.componentWillUnmount = function componentWillUnmount() {
    clearTimeout(this.timer);
  };

  Colors.prototype.render = function render() {
    var _this2 = this;

    var _props = this.props,
        wrap = _props.wrap,
        column = _props.column,
        disabled = _props.disabled,
        onSelect = _props.onSelect,
        columns = _props.columns,
        size = _props.size,
        rest = _objectWithoutProperties(_props, ['wrap', 'column', 'disabled', 'onSelect', 'columns', 'size']);

    var _state2 = this.state,
        colorRows = _state2.colorRows,
        activeRow = _state2.activeRow,
        activeColor = _state2.activeColor;

    var colors = function colors(theme, cellSize) {
      return colorRows.map(function (row, rowIndex) {
        return React.createElement(
          StyledRow,
          {
            key: 'row_' + rowIndex,
            theme: theme,
            style: { width: cellSize * row.colors.length + 'px', height: cellSize + 'px' }
          },
          row.colors.map(function (color, colorIndex) {
            var isActive = activeRow === rowIndex && activeColor === colorIndex;
            var colorStyle = {
              backgroundColor: color.color,
              color: normalizeColor('text', theme),
              left: cellSize * colorIndex + 'px'
            };
            return React.createElement(
              StyledColorContainer,
              { key: 'color_' + colorIndex, size: size, theme: theme },
              React.createElement(
                StyledColor
                // eslint-disable-next-line no-param-reassign
                ,
                { ref: function ref(_ref3) {
                    color.buttonRef = _ref3;
                  },
                  style: colorStyle,
                  size: size,
                  theme: theme,
                  tabIndex: isActive ? '0' : '-1',
                  a11yTitle: (row.name !== undefined ? row.name : '') + ' ' + color.name,
                  plain: true,
                  active: isActive,
                  hoverIndicator: 'background',
                  onClick: _this2.onClickColor({
                    color: color.color,
                    rowIndex: rowIndex,
                    colorIndex: colorIndex,
                    colorName: color.name,
                    rowName: row.name
                  })
                },
                React.createElement(
                  'span',
                  null,
                  color.color
                )
              )
            );
          })
        );
      });
    };
    return React.createElement(
      ThemeContext.Consumer,
      null,
      function (theme) {
        var cellSize = parseMetricToNum(theme.calendar[size].daySize);
        return React.createElement(
          StyledColors,
          _extends({ size: size, theme: theme }, rest),
          React.createElement(
            Keyboard,
            {
              onUp: function onUp(event) {
                event.preventDefault();
                _this2.setActive({ rowIndex: activeRow - 1, colorIndex: activeColor });
              },
              onDown: function onDown(event) {
                event.preventDefault();
                _this2.setActive({ rowIndex: activeRow + 1, colorIndex: activeColor });
              },
              onLeft: function onLeft() {
                return _this2.setActive({ rowIndex: activeRow, colorIndex: activeColor - 1 });
              },
              onRight: function onRight() {
                return _this2.setActive({ rowIndex: activeRow, colorIndex: activeColor + 1 });
              }
            },
            React.createElement(
              Box,
              null,
              React.createElement(
                StyledRows,
                { style: { height: cellSize * colorRows.length + 'px' } },
                colors(theme, cellSize)
              )
            )
          )
        );
      }
    );
  };

  return Colors;
}(Component);

Colors.defaultProps = {
  size: 'medium'
};


var ColorsDoc = void 0;
if (process.env.NODE_ENV !== 'production') {
  ColorsDoc = require('./doc').default(Colors); // eslint-disable-line global-require
}

var ColorsWrapper = ColorsDoc || Colors;

export { ColorsWrapper as Colors };