<script>
import { debounce } from 'throttle-debounce';
import util from 'eoss-ui/src/utils/util';
import rules from 'eoss-ui/src/utils/rules.js';
export default {
  name: 'EsInput',
  componentName: 'EsInput',
  inheritAttrs: false,
  props: {
    value: [String, Number],
    rules: [Object, Array],
    method: {
      type: String,
      default: 'get'
    },
    data: {
      type: Array,
      default() {
        return [];
      }
    },
    label: [Object, String],
    url: {
      type: String,
      default: ''
    },
    param: {
      type: Object,
      default() {
        return {};
      }
    },
    fetchSuggestions: Function,
    focusShow: {
      type: Boolean,
      default: false
    },
    display: {
      type: Boolean,
      default: true
    },
    readonly: Boolean,
    plain: Boolean,
    text: [String, Number],
    scope: {},
    exclude: Boolean
  },
  watch: {
    data: {
      immediate: true,
      deep: true,
      handler(val) {
        this.results = val;
      }
    }
  },
  data() {
    return {
      results: []
    };
  },
  computed: {
    showLimit() {
      if (this.showWordLimit === false) {
        return false;
      }
      if (this.showWordLimit === true) {
        return true;
      }
      if (this.count) {
        return true;
      }
      return false;
    },
    maxInput() {
      if (typeof this.count === 'number') {
        return this.count;
      }
      return this.maxlength;
    },
    model: {
      get() {
        return this.value;
      },
      set(val) {
        return val;
      }
    },
    rule() {
      if (this.rules) {
        if (Array.isArray(this.rules)) {
          return this.rules.map((item) => {
            if (rules[item.type]) {
              return {
                pattern: rules[item.type]['pattern'],
                message: item.message
                  ? item.message
                  : rules[item.type]['message'],
                trigger: item.trigger
                  ? item.trigger
                  : this.fetchSuggestions || this.url || this.data.length > 0
                  ? 'change'
                  : 'blur'
              };
            }
            return item;
          });
        }
        if (rules[this.rules.type]) {
          return {
            pattern: rules[this.rules.type]['pattern'],
            message: this.rules.message
              ? this.rules.message
              : rules[this.rules.type]['message'],
            trigger: this.rules.trigger
              ? this.rules.trigger
              : this.fetchSuggestions || this.url || this.data.length > 0
              ? 'change'
              : 'blur'
          };
        }
        return this.rules;
      }
      return undefined;
    }
  },
  beforeCreate() {
    this.getData = debounce(500, (query, callback, isChange) => {
      this.getDatas(query, callback, isChange);
    });
  },
  created() {},
  mounted() {},
  methods: {
    getDatas(query, callback, isChange) {
      if (typeof this.url && this.results.length === 0) {
        util
          .ajax({
            method: this.method,
            url: this.url,
            data: this.param,
            params: this.param
          })
          .then((res) => {
            if (res.rCode === 0) {
              this.results = JSON.parse(JSON.stringify(res.results));
              let results = query
                ? this.results.filter(this.searchFilter(query))
                : this.results;
              callback(results);
            }
          })
          .catch((err) => {
            if (err.message && err.message !== 'canceled') {
              this.$message.error(err.message);
            }
          });
      } else {
        let results = query
          ? this.results.filter(this.searchFilter(query, isChange))
          : this.results;
        callback(results);
      }
    },
    searchFilter(query, isChange) {
      return (state) => {
        if (isChange) {
          return state.value.indexOf(query) > -1;
        } else {
          if (this.exclude) {
            return state.value !== query;
          } else {
            return state.value === query;
          }
        }
      };
    },
    renderd(doms, h, type) {
      if (typeof this.$attrs[type] === 'boolean') {
        if (this.$attrs.render) {
          if (typeof this.$attrs.render == 'string') {
            try {
              doms.push(
                h(
                  'template',
                  { slot: type },
                  util.toFunction(this.$attrs.render)(h, this)
                )
              );
            } catch (error) {
              throw error;
            }
          } else {
            doms.push(
              h('template', { slot: type }, this.$attrs.render(h, this))
            );
          }
        }
      } else if (typeof this.$attrs[type] === 'object') {
        doms.push(
          h(
            'es-button',
            {
              slot: type,
              class: ['el-primeval', this.$attrs[type].class],
              props: {
                ...this.$attrs[type].props,
                size: this.$attrs[type].size
                  ? this.$attrs[type].size
                  : type === 'prefix' || type === 'suffix'
                  ? 'small'
                  : '',
                type: 'primary'
              },
              attrs: this.$attrs[type].attrs,
              domProps: this.$attrs[type].icon
                ? { innerHTML: this.$attrs[type].icon }
                : {},
              on: {
                click: () => {
                  this.$attrs[type].click &&
                    this.$attrs[type].click(this, this.model, this.scope);
                  this.$attrs[type].event &&
                    this.$attrs[type].event(this, this.model, this.scope);
                }
              }
            },
            [this.$attrs[type].text]
          )
        );
      } else {
        doms.push(h('template', { slot: type }, [this.$attrs[type]]));
      }
    }
  },
  render(h) {
    if (!this.hide) {
      let cls = [];
      let doms = [];
      if (this.readonly) {
        let content = this.model ? this.model : this.text;
        if (this.$attrs.disabled && this.$attrs.disabledTips) {
          content =
            typeof this.$attrs.disabledTips == 'string'
              ? this.$attrs.disabledTips
              : this.$attrs.placeholder;
        }
        if (
          this.$attrs.type === 'textarea' &&
          !this.$attrs.disabled &&
          !this.$attrs.disabledTips
        ) {
          if (this.model) {
            content = this.model.replace(RegExp('\\n', 'g'), '<br/>');
            content = content.replace(RegExp(' ', 'g'), '&nbsp;');
          }
          return h('div', {
            class: ['es-textarea__inner ', { 'es-plain': this.plain }],
            domProps: {
              innerHTML: content
            }
          });
        } else {
          return h(
            'div',
            {
              class: [
                'es-input__inner',
                {
                  'es-plain': this.plain,
                  'es-disabled-tips':
                    this.$attrs.disabled && this.$attrs.disabledTips
                }
              ]
            },
            [content]
          );
        }
      }
      let { prefix, suffix, prepend, append, ...attrs } = this.$attrs;
      if (this.$slots.prefix) {
        doms.push(h('template', { slot: 'prefix' }, this.$slots.prefix));
      } else if (prefix) {
        this.renderd(doms, h, 'prefix');
        cls.push('es-input-button-prefix');
      }
      if (this.$slots.suffix) {
        doms.push(h('template', { slot: 'suffix' }, this.$slots.suffix));
      } else if (suffix) {
        this.renderd(doms, h, 'suffix');
        cls.push('es-input-button-suffix');
      }
      if (this.$slots.prepend) {
        doms.push(h('template', { slot: 'prepend' }, this.$slots.prepend));
      } else if (prepend) {
        this.renderd(doms, h, 'prepend');
      }
      if (this.$slots.append) {
        doms.push(h('template', { slot: 'append' }, this.$slots.append));
      } else if (append) {
        this.renderd(doms, h, 'append');
      }
      if (this.fetchSuggestions || this.url || this.data.length > 0) {
        return h(
          'el-autocomplete',
          {
            show: this.display,
            props: {
              rules: this.rule
            },
            attrs: {
              ...attrs,
              fetchSuggestions: this.fetchSuggestions
                ? this.fetchSuggestions
                : this.getData,
              triggerOnFocus: this.focusShow,
              value: this.model
            },
            on: this.$listeners
          },
          doms
        );
      }
      return h(
        'el-input',
        {
          class: cls,
          props: {
            label: this.label
              ? typeof this.label === 'string'
                ? this.label
                : this.label.text
              : '',
            rules: this.rule,
            value: this.model
          },
          domProps: {
            value: this.model
          },
          attrs: { ...attrs },
          on: { ...this.$listeners },
          directives: [
            {
              name: 'show',
              value: this.display
            }
          ]
        },
        doms
      );
    } else {
      return '';
    }
  }
};
</script>
