"use strict"

Object.defineProperty(exports, "__esModule", {
  value: true,
})

var _bind2 = require("lodash/bind")

var _bind3 = _interopRequireDefault(_bind2)

var _isFunction2 = require("lodash/isFunction")

var _isFunction3 = _interopRequireDefault(_isFunction2)

var _reduce3 = require("lodash/reduce")

var _reduce4 = _interopRequireDefault(_reduce3)

var _forEach2 = require("lodash/forEach")

var _forEach3 = _interopRequireDefault(_forEach2)

var _lowerFirst2 = require("lodash/lowerFirst")

var _lowerFirst3 = _interopRequireDefault(_lowerFirst2)

var _has2 = require("lodash/has")

var _has3 = _interopRequireDefault(_has2)

exports.construct = construct
exports.componentDidMount = componentDidMount
exports.componentDidUpdate = componentDidUpdate
exports.componentWillUnmount = componentWillUnmount

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj }
}

/* global google */
/* eslint-disable no-param-reassign */
function rdcUncontrolledAndControlledProps(acc, value, key) {
  if ((0, _has3.default)(acc.prevProps, key)) {
    var match = key.match(/^default(\S+)/)
    if (match) {
      var unprefixedKey = (0, _lowerFirst3.default)(match[1])
      if (!(0, _has3.default)(acc.nextProps, unprefixedKey)) {
        acc.nextProps[unprefixedKey] = acc.prevProps[key]
      }
    } else {
      acc.nextProps[key] = acc.prevProps[key]
    }
  }
  return acc
}

function applyUpdaterToNextProps(updaterMap, prevProps, nextProps, instance) {
  ;(0, _forEach3.default)(updaterMap, function(fn, key) {
    var nextValue = nextProps[key]
    if (nextValue !== prevProps[key]) {
      fn(instance, nextValue)
    }
  })
}

function construct(propTypes, updaterMap, prevProps, instance) {
  var _reduce2 = (0, _reduce4.default)(
      propTypes,
      rdcUncontrolledAndControlledProps,
      {
        nextProps: {},
        prevProps: prevProps,
      }
    ),
    nextProps = _reduce2.nextProps

  applyUpdaterToNextProps(
    updaterMap,
    {
      /* empty prevProps for construct */
    },
    nextProps,
    instance
  )
}

function componentDidMount(component, instance, eventMap) {
  registerEvents(component, instance, eventMap)
}

function componentDidUpdate(
  component,
  instance,
  eventMap,
  updaterMap,
  prevProps
) {
  component.unregisterAllEvents()
  applyUpdaterToNextProps(updaterMap, prevProps, component.props, instance)
  registerEvents(component, instance, eventMap)
}

function componentWillUnmount(component) {
  component.unregisterAllEvents()
}

function registerEvents(component, instance, eventMap) {
  var registeredList = (0, _reduce4.default)(
    eventMap,
    function(acc, googleEventName, onEventName) {
      if ((0, _isFunction3.default)(component.props[onEventName])) {
        acc.push(
          google.maps.event.addListener(
            instance,
            googleEventName,
            component.props[onEventName]
          )
        )
      }
      return acc
    },
    []
  )

  component.unregisterAllEvents = (0, _bind3.default)(
    _forEach3.default,
    null,
    registeredList,
    unregisterEvent
  )
}

function unregisterEvent(registered) {
  google.maps.event.removeListener(registered)
}