<template>
  <form
    class="v-form" :class="'v-form__' + kind" ref="form"
    :action="action" :method="method"
    @submit.native="onSubmit">
    <slot></slot>
  </form>
</template>

<script>
//import Promise from 'any-promise';

/**
 * VForm
 * @author mmzhou
 */
export default {
    name: 'VForm',
    props: {
        /**
         * All input values in this form
         * eg:
         *    {
         *        username: 'xxx',
         *        password: 'xxx',
         *    }
         */
        model: Object,
        /**
         * Rules
         *    {
         *        username: [
         *            {required: true, message: '请输入邮箱地址', trigger: 'change'},
         *            {email: true, message: '请输入正确的邮箱地址', trigger: 'change'},
         *            {validate: /regexp/, message: '不符合正则', trigger: 'change', submit: false},
         *        ],
         *        password: [
         *            {required: true, message: '请输入账户密码', trigger: 'blur'}
         *        ],
         *    }
         */
        rules: Object,
        kind: {
            // 'default', 'inline'
            type: String,
            default: 'default'
        },
        labelWidth: {
            type: Number,
            default: 60
        },
        action: String,
        method: {
            type: String,
            default: 'POST'
        }
    },
    data() {
        return {
            fields: {},
            fieldLength: 0,
            submiting: false
        };
    },
    created() {
        this.$on('VForm.addField', (field) => {
            this.fields[field.name] = field;
            this.fieldLength++;
        });
        this.$on('VForm.removeField', (field) => {
            delete this.fields[field.name];
            this.fieldLength--;
        });
    },
    methods: {
        validate() {
            const promises = [];
            for (let prop in this.fields) {
                if (!this.fields.hasOwnProperty(prop)) {
                    continue;
                }

                let field = this.fields[prop];
                promises.push(field.validate('submit'));
            }
            return Promise.all(promises);
        },
        onSubmit(e) {
            if (this.submiting) {
                // already submiting
                e.preventDefault();
                return;
            }
            this.submiting = true;

            if (this.canSubmit) {
                // go through validate
                this.canSubmit = false;
                this.submiting = false;
                this.$emit('submit', e);
                return;
            }

            e.preventDefault();
            // validate
            this.validate()
                .then(
                    () => {
                        // valid
                        this.$refs.form.submit();
                        this.canSubmit = true;
                        this.submiting = false;
                    },
                    () => {
                        // invalid
                        this.submiting = false;
                    }
                );
        }
    }
};
</script>
