(function (document, window) {

  if(!window.customElements ||!HTMLElement.prototype.attachShadow) {
    loadScript('https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.2.0/webcomponents-sd-ce.js', loadImgIcon )
  } else {
    if(!window.customElements.get('img-icon')) {
      loadImgIcon();
    } else {
      loadTextInput();
    }
  }

  function loadScript(url, callback){
      const script = document.createElement("script")
      script.type = "text/javascript";
      if (script.readyState){
          script.onreadystatechange = function(){
              if (script.readyState === "loaded" || script.readyState === "complete"){
                  script.onreadystatechange = null;
                  callback();
              }
          };
      } else {
          script.onload = function (){ callback() };
      }

      script.src = url;
      document.getElementsByTagName("head")[0].appendChild(script);
  }

  function loadImgIcon() {
    loadScript('https://cdn.rawgit.com/Nevraeka/img-icon/master/img-icon.js', loadTextInput);
  }

  function loadTextInput() {
    if (!!!window.customElements.get('text-input')) {
      window.customElements.define('text-input',
        class TextInput extends HTMLElement {

          static get observedAttributes() { return ['icon', 'is-valid', 'placeholder', 'size']; }

          constructor() {
            super();
            this._root = null;
            this._state = {
              icon: '',
              placeholder: '',
              size: 'large',
              text: ''
            };
          }

          get value(){
            return this._state.text;
          }

          setValue(val){
            if(this._root){ this._root.querySelector('.text__input').value = val; }
            return this._state.text = val;
          }
          
          connectedCallback() {
            if (this._root === null) {
              if (!!this.attachShadow) {
                this._root = this.attachShadow({ mode: "open" });
              } else {
                this._root = this;
              }
            }
            const initVal = this.getAttribute('initial-value');
            if (!!initVal) { this._state.text = initVal; }
            render(this);
          }

          attributeChangedCallback(name, oldValue, newValue) {
            if (newValue === oldValue) { return };
            if (name === 'placeholder') { this._state.placeholder = newValue; }
            if (name === 'size') { this._state.size = newValue; }
            if (name === 'icon') { this._state.icon = newValue; }
            if (name === 'is-valid') {
              if (newValue === 'true' || newValue === 'false') {
                this._state.isValid = newValue;
              } else {
                this._state.isValid = '';
              }
            }
            render(this);
          }
        }
      );
    }
  }

  function render(component) {

    if (!!component._root) {
      const setPlaceholderAttr = !!component._state.placeholder ? `placeholder="${component._state.placeholder}"` : '';
      const blurHandler = (evt) => blurEvent(component);
      const focusHandler = (evt) => focusEvent(component);

      let textInput = null;
      let setValidationClass = '';
      let iconShape = '';
      let iconDisplay = 'none';
      let iconFill = 'currentColor';
      if(component._state.isValid !== 'true' && component._state.isValid !== 'false') {
        if(component._state.icon !== '') {
          iconShape = component._state.icon;
          iconDisplay = 'block';
          iconFill = '#3777bc';
        }
      }
      if (component._state.isValid === 'true') {
        setValidationClass = 'is-valid';
        iconShape = 'checkmark';
        iconDisplay = 'block';
        iconFill = '#7dc243';
      }

      if (component._state.isValid === 'false') {
        setValidationClass = 'not-valid';
        iconShape = 'alertCircle'
        iconDisplay = 'block';
        iconFill = '#f44336';
      }

      component._root.innerHTML = `
        <style>

        :host {
          overflow: hidden;
          display: flex;
          width: inherit;
          min-width: ${component._state.size === 'small' ? '6' : '8'}0px;
          max-width: 100%;
        }

        .text__input_wrapper {
          position: relative;
          font-family: 'Roboto', Arial, sans-serif;
          display: flex;
          max-width: 100%;
          width: 100%;
        }

        .text__input {
          background-color: #fff;
          transition: border-color 0.25s, width 0.2s;
          padding: 16px 16px 14px 16px;
          border-radius: 6px;
          border: 1px solid #bdbdbd;
          font-size: 16px;
          line-height: 24px;
          color: #424242;
          outline: none;
          width: 100%;
          max-width: 100%;
          box-shadow: none;
          box-sizing: border-box;
        }

        .text__input_icon {
          display: ${iconDisplay};
          color: ${iconFill};
          background-color: rgba(255,255,255,0);
          max-width: 24px;
          max-height: 24px;
          position: absolute;
          right: 16px;
          top: calc(50% - 12px);
          z-index: 10;
        }

        .text__input.small {
          padding: 11px 16px;
        }

        .text__input.disabled {
          background-color: #eee;
          border-color: #bdbdbd;
          color: #bdbdbd;
        }
        .text__input:focus,
        .text__input:hover {
          border-color: #3777bc;
        }

        .text__input.not-valid {
          border-color: #f44336;
        }

        .text__input_icon.is-valid,
        .text__input_icon.not-valid {
          display: block;
        }
        </style>
        <div class="text__input_wrapper">
          <input ${setPlaceholderAttr} class="text__input ${component._state.size} ${setValidationClass}" type="text" />
          <img-icon fill="100" class="text__input_icon" shape="${iconShape}"></img-icon>
        </div>
      `;

      textInput = component._root.querySelector('.text__input');
      textInput.setAttribute('value', component._state.text);
      textInput.removeEventListener('focus', focusHandler);
      textInput.addEventListener('focus', focusHandler);
      textInput.removeEventListener('blur', blurHandler);
      textInput.addEventListener('blur', blurHandler);
    }
  }

  function focusEvent(component) {
    component._state.text = component._root.querySelector('.text__input').value;
    component.dispatchEvent(textInputFocusedEvent(component));
  }

  function blurEvent(component) {
    component._state.text = component._root.querySelector('.text__input').value;
    component.dispatchEvent(textInputBlurredEvent(component));
  }

  function textInputFocusedEvent(component) {
    return new CustomEvent('textInputFocused', {
      composed: true,
      cancelable: true,
      detail: { text: component._state.text }
    });
  }

  function textInputBlurredEvent(component) {
    return new CustomEvent('textInputBlurred', {
      composed: true,
      cancelable: true,
      detail: { text: component._state.text }
    });
  }

})(document, window);