<template>
  <div class="hy-form">
    <div class="header">
      <slot name="header"></slot>
    </div>
    <el-form
      :label-width="labelWidth"
      :rules="rules"
      ref="ruleFormRef"
      :model="modelValue"
    >

      <el-row>
       
        <template v-for="(item, index) in formItems" :key="item.label">
          <el-col v-bind="colLayout">
            <!-- {{ `${item.isHidden}_${index}_${spanNum}_${getArrowDown}` }} -->
            <el-form-item
              v-if="!item.isHidden && !((index + 1) > (24 / spanNum) && getArrowDown)"
              :label="item.label"
              :style="itemStyle"
              :prop="item.field"
            >
              <template
                v-if="
                  item.type === 'input' ||
                  item.type === 'password' ||
                  item.type === 'textarea' ||
                  item.type === 'number'
                "
              >
                <el-input
                  :placeholder="item.placeholder"
                  :type="item.type"
                  :disabled="item.disabled"
                  :clearable="item.clearable || false"
                  v-bind="item.otherOptions"
                  :show-password="item.type === 'password'"
                  :model-value="modelValue[`${item.field}`]"
                  @update:modelValue="handleValueChange($event, item)"
                />
              </template>
              <!-- <template v-else-if="item.type === 'inputEditor'">
                <editor v-model="modelValue[`${item.field}`]" :min-height="192" />
              </template>-->
              <template v-else-if="item.type === 'inputNumber'">
                <el-input-number
                  :model-value="modelValue[`${item.field}`]"
                  v-bind="item.otherOptions"
                  :min="1"
                  @update:modelValue="handleValueChange($event, item)"
                >
                <template v-if="item.otherOptions?.suffix" #suffix>
                  <span>{{ item.otherOptions.suffix }}</span>
                </template>  
                <template v-if="item.otherOptions?.prefix" #prefix>
                  <span>{{ item.otherOptions.prefix }}</span>
                </template>  
              </el-input-number>
              </template>
              <template v-else-if="item.type === 'rate'">
                <el-rate
                  :model-value="modelValue[`${item.field}`]"
                  v-bind="item.otherOptions"
                  :min="1"
                  @update:modelValue="handleValueChange($event, item)"
                />
              </template>
              <template v-else-if="item.type === 'switch'">
                <el-switch
                  :model-value="modelValue[`${item.field}`]"
                  :active-value="item.activeValue || '1'"
                  :inactive-value="item.inactiveValue || '0'"
                  v-bind="item.otherOptions"
                  @update:modelValue="handleValueChange($event, item)"
                />
              </template>
              <template v-else-if="item.type === 'radio'">
                <el-radio
                  :model-value="modelValue[`${item.field}`]"
                  v-bind="item.otherOptions"
                  v-for="option in item.options"
                  :label="option.label" 
                  :value="option.value"
                  @update:modelValue="handleValueChange($event, item)"
                />
              </template>

              <template v-else-if="item.type === 'select'">
                <el-select
                  :placeholder="item.placeholder"
                  v-bind="item.otherOptions"
                  style="width: 100%"
                  :clearable="item.clearable || false"
                  :model-value="modelValue[`${item.field}`]"
                  @update:modelValue="handleValueChange($event, item)"
                >
                  <el-option
                    v-for="option in item.options"
                    :key="option.value"
                    :label="option.title"
                    :value="option.value"
                    >{{ option.title }}</el-option
                  >
                </el-select>
              </template>
              <template v-else-if="item.type === 'elCascader'">
                <el-cascader
                  :props="item.props ?? { checkStrictly: true }"
                  :placeholder="item.placeholder"
                  v-bind="item.otherOptions"
                  style="width: 100%"
                  :model-value="modelValue[`${item.field}`]"
                  :options="item.options"
                  @update:modelValue="handleValueChange($event, item)"
                ></el-cascader>
              </template>
              <template v-else-if="item.type === 'datepicker'">
                <el-date-picker
                  style="width: 100%"
                  :type="item.sontype"
                  v-bind="item.otherOptions"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  :format="item.format"
                  :value-format="item.valueformat"
                  :model-value="modelValue[`${item.field}`]"
                  @update:modelValue="handleValueChange($event, item)"
                ></el-date-picker>
              </template>
              <template v-else-if="item.type === 'treeSelect'">
                <el-tree-select
                  style="width: 100%"
                  :data="item.options"
                  check-strictly
                  v-bind="item.otherOptions"
                  :render-after-expand="false"
                  :model-value="modelValue[`${item.field}`]"
                  @update:modelValue="handleValueChange($event, item)"
                />
              </template>
              <template v-else-if="item.type === 'slotItem'">
                  <slot :name="item.slot"></slot>
                  <!-- <template v-for="item in item.slot">
                    <template v-if="item.slot">
                      <slot :name="item.slot"></slot>
                    </template>
                  </template> -->
              </template>
            </el-form-item>
          </el-col>
        </template>
      </el-row>
    </el-form>
    <div></div>
    <div class="footer">
      <!-- <slot name="otherslots"></slot> -->
      <slot name="footer"></slot>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watch } from 'vue'

export default defineComponent({
  props: {
    arrowDown: {
      type: Boolean,
      required: false
    },
    showArrowDown: {
      type: Boolean,
      required: false
    },
    spanNum: {
      type: Number,
      required: false,
      default: 6,
    },
    modelValue: {
      type: Object,
      required: true
    },
    formItems: {
      type: Array<any>,
      default: () => []
    },
    labelWidth: {
      type: String,
      default: '100px'
    },
    itemStyle: {
      type: Object,
      default: () => ({ padding: '10px 40px' })
    },
    colLayout: {
      type: Object,
      default: () => ({
        xl: 6, // >1920px 4个
        lg: 8,
        md: 12,
        sm: 24,
        xs: 24
      })
    }
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const getArrowDown = ref(props.arrowDown)
    watch(() => [props.arrowDown], (newValue, oldValue) => {
      getArrowDown.value = newValue[0]
    })

    let rules = ref({})
    
    const ruleFormRef = ref()

    for (let index = 0; index < props.formItems.length; index++) {
      const info = props.formItems[index]
      if (info.required) {
        if (!rules.value[`${info.field}`]) rules.value[`${info.field}`] = []

        rules.value[`${info.field}`].push({
          required: true,
          message: info.placeholder ? info.placeholder : `${info.label}不能为空`
        })
      }

      if (info.rules && info.rules.length > 0) {
        if (!rules.value[`${info.field}`]) rules.value[`${info.field}`] = []
        rules.value[`${info.field}`] = rules.value[`${info.field}`].concat(
          info.rules
        )
      }
    }

    const handleValueChange = (value: any, item: any) => {
      if (item.field == 'params') {
        emit('update:modelValue', {
          ...props.modelValue,
          [item.field]: value,
          beginTime: value[0],
          endTime: value[1]
        })
      } else {
        console.log(value)
        if (
          item.type === 'elCascader' &&
          (!item.props || !item.props['multiple'] || !item.props['multiple'])
        ) {
          value = value && value.length > 0 ? value[value.length - 1] : value[0]
          props.modelValue[`${item.field}`] = value
        }

        emit('update:modelValue', { ...props.modelValue, [item.field]: value })
      }
    }



    return {
      getArrowDown,
      rules,
      ruleFormRef,
      handleValueChange
    }
  }
})
</script>

<style scoped lang="scss">
.hy-form {
  padding-top: 22px;
}
</style>
