import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _createClass from "@babel/runtime/helpers/createClass";
import _inherits from "@babel/runtime/helpers/inherits";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import isNumber from 'lodash/isNumber';
import isString from 'lodash/isString';
import { FormGroup } from '@panneau/field';
import { PropTypes as PanneauPropTypes } from '@panneau/core';
var styles = {
  "formGroup": "panneau-field-code-formGroup"
};
/**
 *  Class: CodeField
 *
 *  @param {string,number,array} value
 *  @return {string} newValue
 */

var propTypes = {
  language: PropTypes.string,
  theme: PropTypes.string,
  name: PropTypes.string,
  label: PanneauPropTypes.label,
  value: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
  width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  extensions: PropTypes.arrayOf(PropTypes.string),
  editorProps: PropTypes.object,
  // eslint-disable-line
  isJson: PropTypes.bool,
  onChange: PropTypes.func
};
var defaultProps = {
  language: 'javascript',
  theme: 'github',
  name: null,
  label: null,
  value: null,
  width: '100%',
  height: 300,
  isJson: true,
  extensions: [],
  editorProps: {
    $blockScrolling: Infinity
  },
  onChange: null
};

var CodeField =
/*#__PURE__*/
function (_Component) {
  _inherits(CodeField, _Component);

  _createClass(CodeField, null, [{
    key: "parse",
    value: function parse(value) {
      if (typeof value === 'undefined' || value === null) {
        return value;
      }

      return isString(value) || isNumber(value) ? value : JSON.stringify(value, null, 4);
    }
  }]);

  function CodeField(props) {
    var _this;

    _classCallCheck(this, CodeField);

    _this = _possibleConstructorReturn(this, _getPrototypeOf(CodeField).call(this, props));
    _this.AceEditor = null;
    _this.brace = null;
    _this.importCanceled = false;
    _this.onChange = _this.onChange.bind(_assertThisInitialized(_assertThisInitialized(_this)));
    _this.state = {
      ready: false,
      textValue: props.language === 'json' && props.isJson ? CodeField.parse(props.value) : null
    };
    return _this;
  }

  _createClass(CodeField, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      var _this2 = this;

      var _this$props = this.props,
          language = _this$props.language,
          theme = _this$props.theme,
          extensions = _this$props.extensions;
      import(
      /* webpackChunkName: "vendor/react-ace" */
      'react-ace').then(function (AceEditor) {
        _this2.AceEditor = AceEditor.default;
      }).then(function () {
        return import(
        /* webpackChunkName: "vendor/brace/mode/[request]" */
        "brace/mode/".concat(language));
      }).then(function () {
        return import(
        /* webpackChunkName: "vendor/brace/theme/[request]" */
        "brace/theme/".concat(theme));
      }).then(function () {
        return Promise.all(extensions.map(function (ext) {
          return import(
          /* webpackChunkName: "vendor/brace/ext/[request]" */
          "brace/ext/".concat(ext));
        }));
      }).then(function () {
        if (_this2.importCanceled) {
          return;
        }

        _this2.setState({
          ready: true
        });
      });
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      this.importCanceled = true;
    }
  }, {
    key: "onChange",
    value: function onChange(newValue) {
      var _this$props2 = this.props,
          language = _this$props2.language,
          onChange = _this$props2.onChange,
          isJson = _this$props2.isJson,
          value = _this$props2.value;

      if (language === 'json' && isJson) {
        this.setState({
          textValue: newValue
        }, function () {
          var val;

          try {
            val = JSON.parse(newValue);
          } catch (e) {
            val = value;
          }

          if (onChange) {
            onChange(val);
          }
        });
      } else if (onChange) {
        onChange(newValue);
      }
    }
  }, {
    key: "renderField",
    value: function renderField() {
      var _this$props3 = this.props,
          language = _this$props3.language,
          theme = _this$props3.theme,
          value = _this$props3.value,
          isJson = _this$props3.isJson,
          width = _this$props3.width,
          height = _this$props3.height,
          editorProps = _this$props3.editorProps,
          props = _objectWithoutProperties(_this$props3, ["language", "theme", "value", "isJson", "width", "height", "editorProps"]);

      var textValue = this.state.textValue;
      var AceEditor = this.AceEditor;
      var val = language === 'json' && isJson ? textValue : CodeField.parse(value);
      var editorWidth = isNumber(width) ? "".concat(width, "px") : width;
      var editorHeight = isNumber(height) ? "".concat(height, "px") : height;
      return React.createElement(AceEditor, _extends({}, props, {
        mode: language,
        theme: theme,
        value: val || '',
        width: editorWidth,
        height: editorHeight,
        editorProps: editorProps,
        onChange: this.onChange
      }));
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props4 = this.props,
          name = _this$props4.name,
          label = _this$props4.label,
          other = _objectWithoutProperties(_this$props4, ["name", "label"]);

      var ready = this.state.ready;
      return React.createElement(FormGroup, _extends({
        className: "".concat(styles.formGroup, " form-group-code"),
        name: name,
        label: label
      }, other), ready ? this.renderField() : null);
    }
  }]);

  return CodeField;
}(Component);

CodeField.propTypes = propTypes;
CodeField.defaultProps = defaultProps;
export default CodeField;