<template>
  <div id="c-form">
    <el-form ref="form" :model="form" :rules="rules" :label-width="labelWidth" class="form" size="small" @submit.native.prevent>
      <template v-for="(item, index) in fields">
        <el-form-item v-if="display(item)" :key="'form-field-' + index" :label="getField('label', item)" :prop="item.model" :required="item.required">
          <template v-if="!item.custom">
            <template v-if="item.type === `date` || item.type === `datetime`">
              <el-date-picker
                v-model="form[item.model]"
                :type="item.type"
                placeholder="请选择"
                :format="item.type === 'date' ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'"
                :value-format="item.type === 'date' ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'"
                v-bind="item.options"
                style="width: 100%"
                @change="dataChange(item.model)"
              >
              </el-date-picker>
            </template>
            <template v-else-if="item.type === `year` || item.type === `week` || item.type === `day`">
              <el-date-picker
                v-model="form[item.model]"
                :type="item.type"
                placeholder="请选择"
                :format="`${item.type === 'year' ? 'yyyy' : item.type === 'week' ? 'MM' : 'dd'}`"
                :value-format="`${item.type === 'year' ? 'yyyy' : item.type === 'week' ? 'MM' : 'dd'}`"
                v-bind="item.options"
                style="width: 100%"
                @change="dataChange(item.model)"
              >
              </el-date-picker>
            </template>
            <template v-else-if="item.type === 'time'">
              <el-time-picker
                v-model="form[item.model]"
                placeholder="请选择时间"
                format="HH:mm"
                value-format="HH:mm"
                @change="dataChange(item.model)"
              ></el-time-picker>
            </template>
            <template v-else-if="item.type === 'radio'">
              <el-radio-group v-model="form[item.model]" size="mini" @change="dataChange(item.model)" v-bind="item.options">
                <slot :name="item.model" v-bind="{ item }"></slot>
              </el-radio-group>
            </template>
            <template v-else-if="item.type === 'checkbox'">
              <el-checkbox-group v-model="form[item.model]" @change="dataChange(item.model)" v-bind="item.options">
                <slot :name="item.model" v-bind="{ item }"></slot>
              </el-checkbox-group>
            </template>
            <template v-else-if="item.type === 'select'">
              <el-select
                v-model="form[item.model]"
                v-bind="item.options"
                filterable
                clearable
                @change="dataChange(item.model)"
                style="width: 100%"
                :disabled="item.readonly"
              >
                <slot :name="item.model" v-bind="{ item }"></slot>
              </el-select>
            </template>
            <template v-else-if="item.type === 'textarea'">
              <el-input clearable v-model="form[item.model]" type="textarea" :autosize="{ minRows: 3, maxRows: 5 }" @change="dataChange(item.model)"></el-input>
            </template>
            <template v-else-if="item.type === 'upload'">
            
            </template>
            <template v-else>
              <el-input
                clearable
                v-model="form[item.model]"
                :type="getField('type', item)"
                :placeholder="getField('placeholder', item)"
                :show-password="getField('type', item) === 'password'"
                v-bind="item.options"
                :readonly="item.readonly"
                @change="dataChange(item.model)"
              ></el-input>
            </template>
          </template>
          <template v-else>
            <slot :name="item.model" v-bind="{ item }"></slot>
          </template>
        </el-form-item>
      </template>
      <el-form-item label="" class="btn">
        <slot name="submit">
          <el-row type="flex" align="middle" justify="start">
            <el-col :span="6">
              <el-button type="primary" @click="save" v-use="'save'">{{ submitText }}</el-button>
            </el-col>
          </el-row>
        </slot>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  name: 'c-form',
  props: {
    fields: { type: Array, default: () => [{ readonly: false }] },
    rules: { type: Object, default: () => {} },
    labelWidth: { type: String, default: '120px' },
    submitText: { type: String, default: '保存' },
    form: null,
    reset: { type: Boolean, default: false },
  },
  model: {
    prop: 'form',
    event: 'change',
  },
  components: {},
  data: function () {
    return {};
  },
  methods: {
    getField(item, data) {
      let res = _.get(data, item, null);
      if (item === 'type') res = res === null ? `text` : res;
      if (item === 'placeholder') res = res === null ? `请输入${data.label}` : res;
      if (item === 'required') res = res === null ? false : res;
      if (item === `error`) res = res === null ? `${data.label}错误` : res;
      return res;
    },
    save() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          this.$emit(`save`, { data: JSON.parse(JSON.stringify(this.form)) });
          if (this.reset) this.$refs.form.resetFields();
        } else {
          console.warn('form validate error!!!');
        }
      });
    },
    display(field) {
      let dis = _.get(field, `display`);
      if (!_.isFunction(dis)) return true;
      else return dis(field, this.form);
    },
    dataChange(model) {
      const value = JSON.parse(JSON.stringify(this.form[model]));
      this.$emit('dataChange', { model, value });
    },
  },
};
</script>

<style lang="less" scoped></style>
