"use strict";

exports.__esModule = true;
exports.default = useWhyDidYouUpdate;
exports.guid = guid;
exports.useDeprecated = useDeprecated;
exports.useForceUpdate = useForceUpdate;
exports.useGuid = useGuid;
exports.useValue = useValue;

var _react = _interopRequireWildcard(require("react"));

var _fp = require("./fp");

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function useValue(props, defaultValue, options) {
  var _ref = options || {},
      _ref$valueName = _ref.valueName,
      valueName = _ref$valueName === void 0 ? 'value' : _ref$valueName,
      fitValue = _ref.fitValue,
      compare = _ref.compare;

  var defaultName = (0, _react.useMemo)(function () {
    var n = valueName.substr(0, 1).toUpperCase() + valueName.substr(1);
    return "default" + n;
  }, [valueName]);
  var isControlled = (valueName in props);
  var defaultVal = (0, _react.useMemo)(function () {
    var v = defaultValue;

    if (defaultName in props) {
      v = props[defaultName];
    }

    if (isControlled) {
      v = props[valueName];
    }

    if ((0, _fp.isNil)(v)) {
      v = defaultValue;
    }

    if (fitValue) {
      v = fitValue(v);
    }

    return v;
  }, []);

  var getControlledValue = function () {
    var x = props[valueName];

    if ((0, _fp.isNil)(x)) {
      if (fitValue) {
        return fitValue(defaultValue);
      }

      return defaultValue;
    }

    if (fitValue) {
      return fitValue(x);
    }

    return x;
  };

  var _useState = (0, _react.useState)(defaultVal),
      value = _useState[0],
      setValue = _useState[1];

  var propValue = (0, _react.useRef)(defaultVal);
  (0, _react.useEffect)(function () {
    if (isControlled) {
      var newValue = getControlledValue();
      var isSame = compare ? compare(newValue, propValue.current) : newValue === propValue.current;

      if (!isSame) {
        propValue.current = newValue;
        setValue(newValue);
      }
    }
  }, [props[valueName]]);

  var setPropValue = function (val) {
    var isSame = compare ? compare(val, propValue.current) : val === propValue.current;

    if (!isSame) {
      propValue.current = val;
      setValue(val);
    }
  };

  if (isControlled) {
    return [propValue.current, setValue, isControlled, setPropValue];
  }

  return [value, setValue, isControlled, setPropValue];
}

function useDeprecated(comp, props, oldName, newName, defaultValue) {
  (0, _react.useEffect)(function () {
    if (oldName in props && console && console.warn) {
      console.warn("Warning: " + comp + "." + oldName + " is deprecated and will be removed in a future version, please use " + newName + " instead");
    }
  }, []);

  if (newName in props) {
    return props[newName];
  }

  if (oldName in props) {
    return props[oldName];
  }

  return defaultValue;
}

var counter = 0;

function guid(prefix) {
  if (prefix === void 0) {
    prefix = '';
  }

  counter += 1;
  return "" + prefix + counter;
}

function useGuid(prefix) {
  if (prefix === void 0) {
    prefix = '';
  }

  var id = (0, _react.useRef)(guid(prefix));
  return id.current;
}

function useForceUpdate() {
  var _useState2 = (0, _react.useState)(0),
      update = _useState2[1];

  var cb = (0, _react.useCallback)(function () {
    return update(function (x) {
      return x >= Number.MAX_SAFE_INTEGER ? 0 : x + 1;
    });
  }, []);
  return cb;
}

function useWhyDidYouUpdate(componentName, props) {
  var prevProps = (0, _react.useRef)({});
  (0, _react.useEffect)(function () {
    if (prevProps.current) {
      var allKeys = Object.keys(Object.assign(Object.assign({}, prevProps.current), props));
      var changedProps = {};
      allKeys.forEach(function (key) {
        if (prevProps.current[key] !== props[key]) {
          changedProps[key] = {
            from: prevProps.current[key],
            to: props[key]
          };
        }
      });

      if (Object.keys(changedProps).length) {
        console.log('[why-did-you-update]', componentName, changedProps);
      }
    }

    prevProps.current = props;
  });
}