<template>
  <div class="ezj-form-pane">
    <template v-if="form.hint">
      <div class="ezj-form-pane__hint" v-html="form.hint"></div>
    </template>
    <!-- 多个表单 -->
    <template v-if="form.hasAdd">
      <template v-if="isMultiple">
        <template v-for="(item, index) in model">
          <div class="ejz-form-pane_group" :key="index">
            <div class="remove" @click="handleRemove(index)" v-if="index">
              <i class="el-icon-close"></i>
            </div>
            <form-form
              :options="form.options"
              :model="item"
              :items="form.items"
              :hasButton="false"
              ref="form"
            ></form-form>
          </div>
        </template>
        <el-button @click="handleAdd">增加一项</el-button>
        <el-button @click="handleSubmit">保存</el-button>
      </template>
    </template>

    <!-- 一个表单 -->
    <template v-else>
      <form-form
        :options="form.options"
        :model="model"
        :items="form.items"
        @onSubmit="onSubmit"
        ref="form"
      ></form-form>
    </template>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'EzjFormPane',
  components: {},
  props: {
    title: String,
    get: {
      type: Object,
      default() {
        return {}
      }
    },
    update: {
      type: Object,
      default() {
        return {}
      }
    },
    form: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    let model =
      this.form.model ||
      (this.form.hasAdd ? [Object.assign({}, this.form.defaultModel)] : {})
    return {
      model
    }
  },
  computed: {
    isMultiple() {
      return Array.isArray(this.model)
    }
  },
  methods: {
    init() {
      this.getData()
    },
    // 获取
    getData() {
      let {
        action,
        headers = {},
        data = {},
        beforeRequest,
        callback
      } = this.get
      if (beforeRequest) {
        data = beforeRequest(data)
      }
      axios.get(action, { params: data, headers }).then(res => {
        let { data } = res
        // 默认数据设置
        if (this.form.hasAdd && Array.isArray(data) && !data.length) {
          data.push(Object.assign({}, this.form.defaultModel))
        }
        if (callback) {
          data = callback(data)
        }
        this.model = data
      })
    },
    // 更新
    updateData(formData) {
      let {
        action,
        headers = {},
        data = {},
        beforeRequest,
        callback
      } = this.update
      if (beforeRequest) {
        formData = beforeRequest(formData)
      }
      // 自定义数据和表单数据合并
      formData = Object.assign({}, formData, data)
      // 自定义header和默认header合并
      headers = Object.assign(
        { 'Content-Type': 'application/x-www-form-urlencoded' },
        headers
      )
      // 表单数据序列化
      if (headers['Content-Type'] === 'application/x-www-form-urlencoded') {
        let params = new URLSearchParams()
        for (let key in formData) {
          let value = formData[key]
          params.append(
            key,
            typeof value === 'object' ? JSON.stringify(value) : value
          )
        }
        formData = params
      }
      axios.post(action, formData, { headers }).then(res => {
        let { data } = res
        callback && callback(data)
        this.$emit('update', data)
      })
    },
    onSubmit(data) {
      this.updateData(data)
    },
    // 新增表单
    handleAdd() {
      this.model.push(Object.assign({}, this.form.defaultModel))
    },
    // 删除表单
    handleRemove(index) {
      this.model.splice(index, 1)
    },
    // 提交
    handleSubmit() {
      const formCompoents = this.$refs.form
      let allPromise = formCompoents.map(form => form.validate())
      Promise.all(allPromise).then(() => {
        this.updateData(this.model)
      })
    }
  },
  beforeMount() {
    this.init()
  }
}
</script>

<style lang="scss">
.ezj-form-pane__hint {
  margin-bottom: 20px;
}
.ejz-form-pane_group {
  position: relative;
  margin-bottom: 20px;
  padding: 15px;
  border: 2px solid #c41230;
  border-radius: 10px;

  .remove {
    position: absolute;
    top: -12px;
    right: -12px;
    z-index: 999;
    font-size: 20px;
    line-height: 24px;
    text-align: center;
    color: #fff;
    cursor: pointer;
    background-color: #c41230;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    overflow: hidden;
  }
}
</style>
