<template>
  <form ref="mainRef">
    <slot />
  </form>
</template>
<script>
import util from '../../utils';
export default {
  name: "FbgForm",
  componentName: 'FbgForm',
  props: {
    labelWidth: {
      type: String,
      default: "80px"
    },
    model: {
      type: [Array, Object],
      default() {
        return {};
      }
    },
    rules: {
      type: Object,
      default() {
        return {};
      }
    },
    type: {
      type: String,
      default: 'normal'
    }
  },
  data() {
    return {
      fields: [],
      validateData: {},
      clearValidateData: [],
      formData: {
        labelWidth: this.labelWidth,
        model: this.model,
        rules: this.rules,
        formType: this.type
      }
    };
  },
  provide() {
    return {
      formData: this.formData,
      deleteValidateField: (key) => {
        if (this.validateData[key]) {
          delete this.validateData[key];
        }
      },
      addValidateField: (key, callback, context) => {
        this.validateData[key] = (valiCallback) => {
          typeof callback === 'function' && callback((vali) => {
            valiCallback(vali, context);
          });
        }
      },
      clearValidate: (key, callback) => {
        this.clearValidateData[key] = () => {
          callback();
        }
      }
    }
  },
  watch: {
    labelWidth: {
      immediate: true,
      handler(value) {
        this.formData.labelWidth = value;
      }
    },
    model: {
      immediate: true,
      handler(data) {
        this.formData.model = data;
      }
    },
    rules: {
      immediate: true,
      handler(data) {
        this.formData.rules = data;
      }
    }
  },
  created() {
    this.$on('fbg.form.addField', (field) => {
      if (field) {
        this.fields.push(field);
      }
    });
    /* istanbul ignore next */
    this.$on('fbg.form.removeField', (field) => {
      if (field.prop) {
        this.fields.splice(this.fields.indexOf(field), 1);
      }
    });
  },
  methods: {
    resetFields() {
      if (!this.model) {
        console.warn('[Form]model is required for resetFields to work.');
        return;
      }
      this.fields.forEach(field => {
        field.resetField();
      });
    },
    validate(callback) {
      const len = Object.keys(this.validateData).length;
      let success = 0;
      let count = 0;
      let flag = false;
      let autoPosition = true;
      for(let valiKey in this.validateData) {
        this.validateData[valiKey]((vali, context) => {
          count++;
          if (vali === true) {
            success++;
          } else if(autoPosition) {
            const el = context.$refs.mainRef;
            const boxEl = util.getScrollParentNode(context.$refs.mainRef);
            if (boxEl) {
              const top = util.getElTop(el, boxEl);
              const scrollTop = util.getElScrollTop(boxEl);
              if (scrollTop > top) {
                util.setElScrollTop(boxEl, top - 50);
              }
            }
            autoPosition = false;
          }
          if (count === len && success === len) {
            callback(true);
            flag = true;
          } else if (count === len) {
            callback(false);
            flag = true;
          }
        });
      }
      if (!flag) {
        callback(false);
      }
    },
    validateField(field, callback) {
      const valifun = this.validateData[field];
      valiFun((vali) => {
        callback(vali);
      });
    },
    clearValidate() {
      for(let key in this.clearValidateData) {
        if (typeof this.clearValidateData[key] === 'function') {
          this.clearValidateData[key]();
        }
      }
    },
    clearValidateField(field) {
      if (typeof this.clearValidateData[field] === 'function') {
        this.clearValidateData[field]();
      } else {
        throw new Error(field + ' field not undefined！');
      }
    }
  }
}
</script>
<style lang="scss" scoped>

</style>