<!-- 系统/自定义组件 (category为system/custom) -->
<template>
  <div class="form-item">
    <!--  普通输入框  -->
    <van-field
      v-if="field.type === 'Input'"
      v-model="field.value"
      :name="field.label"
      :required="field.required"
      :disabled="field.disabled"
      :label="field.label"
      :maxlength="field.maxlength"
      :placeholder="`请填写${field.label}`"
      :rules="setRules(field)"
    />
    <!-- 多行输入框 -->
    <van-field
      v-if="field.type === 'TextArea'"
      v-model="field.value"
      :name="field.label"
      type="textarea"
      :required="field.required"
      :disabled="field.disabled"
      :value="field.value"
      :label="field.label"
      :maxlength="field.maxlength"
      :placeholder="`请填写${field.label}`"
      rows="2"
      autosize
      clearable
      show-word-limit
      :rules="setRules(field)"
    />
    <!-- 计数器精度 -->
    <van-field
      v-if="field.type === 'InputNumber'"
      :required="field.required"
      :disabled="field.disabled"
      :name="field.label"
      :label="field.label"
      :rules="setRules(field)"
    >
      <template #input>
        <van-stepper
          v-model="field.value"
          class="form-item-van-stepper"
          :decimal-length="field.precision"
          :min="field.min"
          :max="field.max"
          :disabled="field.disabled"
          :allow-empty="field.required ? false:true"
          :placeholder="`请填写${field.label}`"
          :show-plus="false"
          :show-minus="false"
          input-width="100%"
        />
      </template>
    </van-field>
    <!-- 单选 -->
    <van-field
      v-if="field.type === 'Radio'"
      :required="field.required"
      :disabled="field.disabled"
      :name="field.label"
      :label="field.label"
      :rules="setRules(field)"
    >
      <template #input>
        <van-radio-group
          v-model="field.value"
          direction="horizontal"
          :disabled="field.disabled"
          :icon-size="16"
        >
          <van-radio
            v-for="opt in field.options"
            :key="opt.value"
            :name="opt.value"
          >{{ opt.label }}
          </van-radio>
        </van-radio-group>
      </template>
    </van-field>
    <!-- 复选框 -->
    <van-field
      v-if="field.type === 'Checkbox'"
      :required="field.required"
      :disabled="field.disabled"
      :name="field.label"
      :label="field.label"
      :rules="setRules(field)"
    >
      <template #input>
        <van-checkbox-group
          v-model="field.value"
          direction="horizontal"
          :disabled="field.disabled"
          :icon-size="16"
        >
          <van-checkbox
            v-for="opt in field.options"
            :key="opt.value"
            :name="opt.value"
            shape="square"
          >{{ opt.label }}
          </van-checkbox>
        </van-checkbox-group>
      </template>
    </van-field>
    <!-- select单选选择器 -->
    <van-field
      v-if="field.type === 'Select' && !field.multiple"
      :name="field.label"
      :required="field.required"
      :disabled="field.disabled"
      :value="selectShowOptionLabel"
      :label="field.label"
      right-icon="arrow-down"
      :placeholder="`点击选择${field.label}`"
      :rules="setRules(field)"
      readonly
      :clickable="!field.disabled"
      @click="field.disabled ? () => {}:openSingleSelect(field)"
    />
    <!-- select单选选择器弹出框 -->
    <van-popup
      v-model="isOpenSingleSelect"
      position="bottom"
    >
      <van-picker
        title="请选择"
        show-toolbar
        :columns="field.options"
        value-key="label"
        @confirm="confirm"
        @cancel="cancel"
      />
    </van-popup>
    <!-- select多选选择器 -->
    <select-multiple
      v-if="field.type === 'Select' && field.multiple"
      :field="field"
      :rules="setRules"
    />
    <!-- 日期时间/仅日期/仅时间选择器 -->
    <form-date-time
      v-if="field.type === 'DateTime' || field.type === 'Date' || field.type === 'Time'"
      :field="field"
      :rules="setRules"
    />
    <!-- 省份选择器(地址) -->
    <area-select
      v-if="field.type === 'Area'"
      :field="field"
      :rules="setRules"
    />
    <!-- 开关 -->
    <van-field
      v-if="field.type === 'Switch'"
      class="form-item-switch"
      :name="field.label"
      :disabled="field.disabled"
      :label="field.label"
    >
      <template #input>
        <span :class="['show-switch', field.disabled ? 'disabled':'', field.value === field.options[1].value ? 'active':'']">{{ field.options[1].value }}</span>
        <van-switch
          v-model="field.value"
          :disabled="field.disabled"
          :active-value="field.options[0].value"
          :inactive-value="field.options[1].value"
          active-color="#3e8ddd"
          inactive-color="#cccccc"
        />
        <span :class="['show-switch', field.disabled ? 'disabled':'', field.value === field.options[0].value ? 'active':'']">{{ field.options[0].value }}</span>
      </template>
    </van-field>
    <!-- 扫码 -->
    <input-scan
      v-if="field.type === 'InputScan'"
      :field="field"
      :rules="setRules"
    />
  </div>
</template>

<script>
import SelectMultiple from './../components/SelectMultiple'
import FormDateTime from './../components/FormDateTime'
import AreaSelect from './../components/AreaSelect'
import InputScan from './../components/InputScan'
import { getDictByCode } from './../api'

export default {
  name: 'FormItem',
  components: {
    SelectMultiple,
    FormDateTime,
    AreaSelect,
    InputScan
  },
  props: {
    // 配置的每个组件的数据
    field: {
      type: Object,
      default () {
        return {
          type: '',
          label: '',
          required: true
        }
      }
    }
  },
  data () {
    return {
      isOpenSingleSelect: false
    }
  },
  computed: {
    // select单选选择器显示
    selectShowOptionLabel ({ field }) {
      const filterOption = field.options.filter(item => {
        return item.value === field.value
      })
      return filterOption.length > 0 ? filterOption[0].label : ''
    }
  },
  created () {
    this.initEmptyOptions()
  },
  methods: {
    /**
     * @description 初始化类型为(Select、Radio、Checkbox)的options为空的情况.目前升级单模板会调用到此逻辑,表单流程渲染的不会调用到此逻辑(因为表单options不为空)
     * @description 截至提交此注释的这个时刻,根据现有模板渲染配置数据只测试验证了(Select单选情况、Radio情况)下options为空的情况
     */
    initEmptyOptions () {
      const initTypes = ['Select', 'Radio', 'Checkbox']
      if (initTypes.includes(this.field.type)) {
        if (this.field.options.length === 0) {
          // 由于app和pc的数据字典链接是不一样的 因此此处不能直接使用，但是由于返回的没有直接返回字典的code，所以需要做截取来获取到字典的code
          const dictName = this.field.api.split('ItemList?categoryCode=')[1]
          getDictByCode(dictName).then(res => {
            if (res.code === 200) {
              res.data.forEach(item => {
                this.field.options.push({
                  id: item.paraID,
                  label: item[this.field.optionLabelKey],
                  value: item[this.field.optionValueKey]
                })
              })
            }
          })
        }
      }
    },
    // 通用的校验规则
    setRules (field) {
      const rules = []
      // 为空校验
      if (field.required) {
        rules.push({
          required: true,
          message: field.label + '不能为空',
          trigger: 'onChange'
        })
      }
      // 正则校验
      if (field.regexp) {
        const pattern = new RegExp(field.regexp)
        rules.push({
          pattern: pattern,
          message: field.label + '格式错误',
          trigger: 'onChange'
        })
      }
      return rules
    },
    // 弹出select单选框
    openSingleSelect (field) {
      this.isOpenSingleSelect = true
    },
    // select单选弹出框确认按钮
    confirm (item) {
      // 赋值
      this.field.value = item.value
      this.isOpenSingleSelect = false
    },
    // select单选弹出框取消按钮
    cancel () {
      this.isOpenSingleSelect = false
    }
  }
}
</script>
<style lang='scss' scoped>
  .form-item {
    ::v-deep .van-field--disabled {
      .van-field__value {
        .van-field__right-icon {
          color: #c8c9cc;
        }
      }
    }
    .form-item-van-stepper {
      flex: 1;
      background: #f8f8f8;
      ::v-deep .van-stepper__input {
        text-align: left;
        background-color: #f8f8f8;
        &::placeholder {
          color: #cccccc;
        }
      }
    }
    .form-item-switch {
      .show-switch {
        color: #646566;
        &.active {
          color: #3e8ddd;
        }
        &.disabled {
          opacity: 0.6;
        }
      }
      .van-switch {
        font-size: 16px;
        margin: 0 10px;
        ::v-deep .van-switch__node {
          font-size: 16px;
        }
      }
    }
  }
</style>
