<template>
  <van-form
    ref="form"
    class="form"
    label-width="100%"
    validate-trigger="onChange"
    v-bind="$attrs"
    v-on="$listeners"
  >
    <template v-for="(item, index) in fields">
      <div class="form-item" :key="index">
        <!-- 时间 -->
        <template v-if="item.fieldType === 'datetime'">
          <van-field
            readonly
            clickable
            right-icon="arrow-down"
            :border="false"
            :required="false"
            v-bind="item"
            v-model="ruleForm[item.name]"
            @click="showPicker(item)"
            v-if="item.isShow ? item.isShow(ruleForm) : true"
          >
            <template #label>
              {{ item.label }}
              <span class="red" v-if="item.required">*</span>
            </template>
          </van-field>
        </template>

        <!-- 地区 -->
        <template v-else-if="item.fieldType === 'area'">
          <van-field
            readonly
            clickable
            right-icon="arrow-down"
            :border="false"
            :required="false"
            v-bind="item"
            v-model="ruleForm[item.name]"
            @click="showPicker(item)"
            v-if="item.isShow ? item.isShow(ruleForm) : true"
          >
            <template #label>
              {{ item.label }}
              <span class="red" v-if="item.required">*</span>
            </template>
          </van-field>
        </template>

        <!-- 选择 -->
        <template v-else-if="item.fieldType === 'select'">
          <van-field
            readonly
            clickable
            right-icon="arrow-down"
            :border="false"
            :required="false"
            :value="ruleForm[item.name] | pickerValueText(item)"
            v-bind="item"
            @click="showPicker(item)"
            v-if="item.isShow ? item.isShow(ruleForm) : true"
          >
            <template #label>
              {{ item.label }}
              <span class="red" v-if="item.required">*</span>
            </template>
          </van-field>
        </template>

        <!-- 上传图片 -->
        <template v-else-if="item.fieldType === 'uploader'">
          <van-field
            :border="false"
            :required="false"
            v-bind="item"
            v-model="ruleForm[item.name]"
            v-if="item.isShow ? item.isShow(ruleForm) : true"
          >
            <template #label>
              {{ item.label }}
              <span class="red" v-if="item.required">*</span>
            </template>
            <template #input>
              <upload v-model="ruleForm[item.name]" :max-count="1" />
            </template>
          </van-field>
        </template>

        <!-- 上传多个图片 -->
        <template v-else-if="item.fieldType === 'upliadMultiple'">
          <van-field
            :border="false"
            :required="false"
            v-bind="item"
            v-if="item.isShow ? item.isShow(ruleForm) : true"
          >
            <template #label>
              {{ item.label }}
              <span class="red" v-if="item.required">*</span>
            </template>
            <template #input>
              <UpliadMultiple v-model="ruleForm[item.name]" />
            </template>
          </van-field>
        </template>

        <!-- 上传视频 -->
        <template v-else-if="item.fieldType === 'video'">
          <van-field
            :border="false"
            :required="false"
            v-bind="item"
            v-if="item.isShow ? item.isShow(ruleForm) : true"
          >
            <template #label>
              {{ item.label }}
              <span class="red" v-if="item.required">*</span>
            </template>
            <template #input>
              <UploadVideo
                v-on="$listeners"
                v-model="ruleForm[item.name]"
                accept="video/*"
              />
            </template>
          </van-field>
        </template>

        <!-- 单选 -->
        <template v-else-if="item.fieldType === 'radio'">
          <van-field
            :border="false"
            :required="false"
            v-bind="item"
            v-model="ruleForm[item.name]"
            v-if="item.isShow ? item.isShow(ruleForm) : true"
          >
            <template #label>
              {{ item.label }}
              <span class="red" v-if="item.required">*</span>
            </template>
            <template #input>
              <van-radio-group
                v-model="ruleForm[item.name]"
                direction="horizontal"
              >
                <van-radio
                  :name="item.name"
                  v-for="item in item.values"
                  :key="item.name"
                  >{{ item.text }}</van-radio
                >
              </van-radio-group>
            </template>
          </van-field>
        </template>

        <!-- 文本框 -->
        <template v-else>
          <van-field
            :border="false"
            :required="false"
            v-bind="item"
            v-model="ruleForm[item.name]"
            v-if="item.isShow ? item.isShow(ruleForm) : true"
          >
            <template #label>
              {{ item.label }}
              <span class="red" v-if="item.required">*</span>
            </template>
          </van-field>
        </template>

        <van-popup v-model="picker.visible" position="bottom">
          <van-datetime-picker
            type="datetime"
            :value="picker.value"
            :min-date="minDate"
            @confirm="onTimePickerConfirm"
            @cancel="picker.visible = false"
            v-if="picker.fieldType === 'datetime'"
          />
          <van-picker
            show-toolbar
            :value-key="picker.labelKey"
            :columns="picker.values"
            @confirm="onPickerConfirm"
            @cancel="picker.visible = false"
            v-if="picker.fieldType === 'select'"
          />
          <van-area
            :area-list="areaList"
            :columns-num="2"
            @confirm="onAreaPickerConfirm"
            @cancel="picker.visible = false"
            v-if="picker.fieldType === 'area'"
          />
        </van-popup>
      </div>
    </template>
    <slot></slot>
  </van-form>
</template>

<script>
import dayjs from 'dayjs'
import Upload from '@/components/Upload'
import areaList from '@/utils/area.js'
import UploadVideo from '@/components/UploadVideo'
import UpliadMultiple from '@/components/UpliadMultiple'

export default {
  name: 'VForm',
  components: { Upload, UploadVideo, UpliadMultiple },
  props: {
    model: {
      type: Object,
      default() {
        return {}
      }
    },
    fields: {
      type: Array,
      required: true,
      default() {
        return []
      }
    }
  },
  watch: {
    model: {
      immediate: true,
      deep: true,
      handler(value) {
        this.ruleForm = value
      }
    }
  },
  data() {
    return {
      ruleForm: this.model,
      picker: {
        visible: false,
        fieldType: '',
        name: '',
        value: '',
        valueKey: 'value',
        labelKey: 'text',
        values: [],
        remote: null
      },
      minDate: new Date(),
      pickerActive: {},
      areaList
    }
  },
  filters: {
    pickerValueText(value, field) {
      if (!value || !field.values) {
        return ''
      }
      const valueKey = field.valueKey || 'value'
      const labelKey = field.labelKey || 'text'
      const found = field.values.find(item => item[valueKey] === value)
      return found ? found[labelKey] : ''
    }
  },
  methods: {
    showPicker(field) {
      this.picker = Object.assign(
        {
          visible: true,
          fieldType: '',
          name: '',
          value: '',
          valueKey: 'value',
          labelKey: 'text',
          values: [],
          remote: null
        },
        field
      )
      this.picker.value = this.ruleForm[name]
      if (field.fieldType === 'select' && field.remote && !field.values) {
        this.getPickerOptions(field)
      }
    },
    // 选择确定
    onPickerConfirm(data) {
      this.ruleForm[this.picker.name] = data[this.picker.valueKey]
      this.picker.visible = false
      if (this.picker.remote && this.picker.remote.change) {
        this.pickerActive = data
      }
    },
    // 时间选择确定
    onTimePickerConfirm(time) {
      this.ruleForm[this.picker.name] = dayjs(time)
        .second(0)
        .format('YYYY-MM-DD HH:mm:ss')
      this.picker.visible = false
    },
    // 地区选择确定
    onAreaPickerConfirm(values) {
      this.ruleForm[this.picker.name] = values.map(item => item.name).join('-')
      this.picker.visible = false
    },
    submit() {
      return this.$refs.form.submit()
    },
    getPickerOptions(field) {
      const remote = field.remote
      if (!remote) {
        return
      }
      remote.method(this.pickerActive).then(response => {
        if (remote.callback) {
          response = remote.callback(response)
        }
        field.values = response
        this.$set(this.picker, 'values', response)
      })
    }
  }
}
</script>
