<template>
  <div class="mm-form-box">
    <slot></slot>
  </div>
</template>

<script>
import scrollIntoView from "scroll-into-view"

export default {
  name: "mm-form-box",
  props: {},
  provide() {
    return {
      "mm-form-box": this,
    }
  },
  data() {
    return {
      forms: [],
    }
  },
  computed: {
    realForms() {
      return this.forms.slice().sort((a, b) => a.order - b.order)
    },
  },
  methods: {
    register(form) {
      this.forms.push(form)
    },

    unregister(form) {
      const index = this.forms.indexOf(form)
      if (~index) {
        this.forms.splice(index, 1)
      }
    },

    validate(o) {
      const options = {
        names: [],
        scroll: false,
        detail: false,
      }

      if (options.scroll) {
        options.detail = true
      }

      Object.assign(options, o)

      return Promise.all(
        this.realForms
          .filter(f => (options.names.length > 0 ? options.names.includes(f.name) : true))
          .map(f =>
            f.validate({
              detail: true,
            })
          )
      ).catch(error => {
        if (error) {
          if (options.scroll) {
            return new Promise((resolve, reject) => {
              const first = error[0]
              scrollIntoView(first.element, () => {
                if (first.instance && first.instance.focus) {
                  first.instance.focus()
                }
                reject(error)
              })
            })
          }
          return Promise.reject(error)
        } else {
          return Promise.reject(error)
        }
      })
    },

    reset(names = []) {
      this.realForms
        .filter(f => (names.length > 0 ? names.includes(f.name) : true))
        .targets.forEach(target => {
          target.reset()
        })
    },
  },
}
</script>
