<template>
    <el-form 
        :inline="inlineLayout"
        :model="formData"  
        ref="formRef" 
        :label-width="labelWidth"
    >
      <el-form-item 
        v-for="item in finalFormItemList" 
        :key="item.key"
        :label="item.label ?  (item.label + '：') : ''"
        :prop="item.key"
        :rules="item.rules"
        :class="[item.className,{'top_label':(item.type=='textarea'||item.type=='checkbox'||item.type=='file' || item.custom === true || item.type=='noDragFile' || item.type=='img')}]"
      >
        <template v-if="item.custom">
          <slot :name="item.key" :formRef="formRef" :formData="formData"></slot>
        </template>

        <template v-else>
          <!-- autocomplete="off" -->
          <!-- <template > -->
            <el-input v-if="item.type=='input'" v-model="formData[item.key]"  :disabled="item.disabled || props.formDisabled" :placeholder="item.placeholder" :style="item.style"/>
            <el-input v-else-if="item.type=='password'" type="password" v-model="formData[item.key]"  :disabled="item.disabled || props.formDisabled" :style="item.style"/>
            <el-input v-else-if="item.type=='textarea'" :autosize="{ minRows: item.rows, maxRows: item.rows }" v-model="formData[item.key]" type="textarea" :rows="item.rows"  :disabled="item.disabled || props.formDisabled" :placeholder="item.placeholder" :style="item.style"/>
            <el-input v-else-if="item.type=='number'" type="number"  v-model="formData[item.key]" :rows="item.rows"  :disabled="item.disabled || props.formDisabled" :placeholder="item.placeholder" :style="item.style"/>
            
            <el-radio-group 
              v-else-if="item.type=='radio'"  
              v-model="formData[item.key]" 
              :disabled="item.disabled || props.formDisabled" 
              :placeholder="item.placeholder"
              @change="(val)=>handleSelectChange(item.key,val,item.type)"
            >
              <el-radio v-for="radioItem in item.selectList" :key="radioItem.value" :value="radioItem.value">{{ radioItem.label }}</el-radio>
            </el-radio-group>
            
            <el-select 
              v-else-if="item.type=='select'"  
              @change="(val)=>handleSelectChange(item.key,val)"
              v-model="formData[item.key]"  :style="item.style" :disabled="item.disabled || props.formDisabled" :placeholder="item.placeholder"
            >
              <el-option
                v-for="selectItem in item.selectList"
                :key="selectItem.value"
                :label="selectItem.label"
                :value="selectItem.value"
              />
            </el-select>

            <el-select
              class="multipleSelect"
              v-else-if="item.type=='multipleSelect'"
              v-model="formData[item.key]"
              multiple
              @change="(val)=>handleSelectChange(item.key,val)"
              :disabled="item.disabled || props.formDisabled" :placeholder="item.placeholder"
            >
              <el-option
                v-for="selectItem in item.selectList"
                :key="selectItem.value"
                :label="selectItem.label"
                :value="selectItem.value"
                />
            </el-select>

            <el-select
              class="multipleSelect"
              v-else-if="item.type=='multipleSelectSearch'"
              v-model="formData[item.key]"
              multiple
              filterable
              @change="(val)=>handleSelectChange(item.key,val)"
              :disabled="item.disabled || props.formDisabled" :placeholder="item.placeholder"
            >
              <el-option
                v-for="selectItem in item.selectList"
                :key="selectItem.value"
                :label="selectItem.label"
                :value="selectItem.value"
                />
            </el-select>



            <template v-else-if="item.type == 'unionSelect'">
              <span style="display: flex;width: 100%;gap:20px">
                <el-select v-for="unionSubItem in item.unionSelectList"
                  :key="unionSubItem.key"
                  @change="(val)=>handleSelectChange(item.key,val,item.type,null,unionSubItem.key)"
                  :model-value="formData[item.key]?.[unionSubItem.key]"
                  :style="unionSubItem.style" :disabled="unionSubItem.disabled || props.formDisabled" :placeholder="unionSubItem.placeholder"
                >
                  <el-option
                    v-for="selectItem in unionSubItem.selectList"
                    :key="selectItem.value"
                    :label="selectItem.label"
                    :value="selectItem.value"
                  />
                </el-select>
              </span>
            </template>

            <template v-else-if="item.type=='checkbox'" >
              <el-checkbox
                v-if="item?.checkAll"
                :disabled="item.disabled || props.formDisabled"
                :model-value="formData[item.key]?.length === item.selectList?.length"
                :indeterminate="formData[item.key]?.length > 0 && formData[item.key]?.length < item.selectList?.length"
                @change="(val)=>handleCheckAllOrNot(val,item.key,item.selectList)"
              >
                全部
              </el-checkbox>

              <el-checkbox-group  
                class="check_group_list"
                :disabled="item.disabled || props.formDisabled"
                v-model="formData[item.key] "
                @change="(val)=>handleSelectChange(item.key,val,item.type,item.selectList)"
              >
                <el-checkbox 
                  v-for="checkItem in item.selectList" 
                  :key="checkItem.value"
                  :label="checkItem.label"
                  :value="checkItem.value"
                />
              </el-checkbox-group>

            </template>

            <template v-else-if="item.type == 'switch'">
              <div style="display: flex;align-items: center;gap:20px;">
                <el-switch
                  v-model="formData[item.key] "
                  class="ml-2"
                  style="--el-switch-on-color: #2e64fa; --el-switch-off-color: #E2E2E3"
                />
                <span style="color:#999999;font-size: 12px;">{{ item.tips }}</span>
              </div>
            </template>
          

            <el-date-picker
              v-else-if="item.type=='datePicker'"
              v-model="formData[item.key] "
              type="daterange"
              :range-separator="item.placeholder.rangeSeparator"
              :start-placeholder="item.placeholder.startPlaceholder"
              :end-placeholder="item.placeholder.endPlaceholder"
              size="default"
              :disabled="item.disabled || props.formDisabled"
              @change="(val)=>handleSelectChange(item.key,val,item.type)"
            />
            
            <el-date-picker
              v-else-if="item.type=='dateTimePicker'"
              v-model="formData[item.key]"
              :start-placeholder="item.placeholder.startPlaceholder"
              :end-placeholder="item.placeholder.endPlaceholder"
              type="datetimerange"
              format="YYYY-MM-DD HH:mm:ss"
              date-format="YYYY/MM/DD ddd"
              time-format="A hh:mm:ss"
              :range-separator="item.placeholder.rangeSeparator"
              size="default"
              @change="(val)=>handleSelectChange(item.key,val,item.type)"
              :disabled="item.disabled || props.formDisabled"
            />


            <el-date-picker
              v-else-if="item.type=='dateTimePickerNoRange'"
              v-model="formData[item.key]"
              type="datetime"
              :placeholder="item.placeholder"
              :disabled="item.disabled || props.formDisabled"
              style="width: 100%;"
              @change="(val)=>handleSelectChange(item.key,val,item.type)"
            />


            <el-upload
              v-else-if="item.type=='file'"
              class="upload-demo"
              action="#"
              drag
              :auto-upload="false"
              @change="(file)=>handleFileChange(file,item.key)"
              :disabled="item.disabled"
              >
                <span v-if="props.fileLoading" style="display: flex;flex-direction: row;align-items: center;gap: 3px;line-height: 1.5;color:#2e64fa">
                  上传中<el-icon class="is-loading">
                    <Loading />
                  </el-icon>
                </span>
                
                <span v-else-if="formData[item.key]?.name" class="file_list">
                  <span class="el-upload__tip">
                    <span  @click.stop.prevent="HandlePreviewFile(formData[item.key])">
                      {{ formData[item.key]?.name  }}   
                    </span> 
                    <img class="delete_item"  @click="HandleRemove(item.key)" :src="deleteIcon" alt="">
                  </span>
                  <i  class="iconfont hjx-dui"></i>
                </span>

                <img class="no_data" v-else :src="noDataBg" alt="">
                <el-button type="primary"><i class="iconfont hjx-daochu"></i> 上传文件</el-button>

            </el-upload>


            <el-upload
              v-else-if="item.type == 'noDragFile'"
              class="upload-demo"
              action="#"
              :auto-upload="false"
              @change="(file)=>handleFileChange(file,item.key)"
              :disabled="item.disabled"
              >
                <el-button type="primary"><i class="iconfont hjx-daochu"></i> 上传文件</el-button>
                
                <template #tip>
                  <div class="no_drag_content el-upload__tip ">
                    <span v-if="props.fileLoading" style="display: flex;flex-direction: row;align-items: center;gap: 3px;line-height: 1.5;color:#2e64fa">
                      上传中<el-icon class="is-loading">
                        <Loading />
                      </el-icon>
                    </span>
                    
                    <span v-else-if="formData[item.key]?.name" class="file_list">
                      <span class="el-upload__tip">
                        <span  @click.stop.prevent="HandlePreviewFile(formData[item.key])">
                          {{ formData[item.key]?.name  }}   
                        </span> 
                        <img class="delete_item"  @click="HandleRemove(item.key)" :src="deleteIcon" alt="">
                      </span>
                      <i  class="iconfont hjx-dui"></i>
                    </span>
                  </div>

                </template>
            </el-upload>


            <template  v-else-if="item.type=='imgFile'" >
              <div class="img_file_area">
                 <span v-if="props.fileLoading" class="cover"  style="gap: 3px;line-height: 1.5;color:#2e64fa">
                  上传中
                  <el-icon class="is-loading">
                    <Loading />
                  </el-icon>
                </span>
                <span v-else-if="formData[item.key]?.url">
                  <img class="cover"   :src="formData[item.key]?.url" alt="">
                  <img   class="close" @click="HandleRemove(item.key)" :src="closeFillImg">
                </span>
                <el-upload 
                  v-model:file-list="fileList"
                  action="#" 
                  :auto-upload="false"
                  @change="(file)=>handleFileChange(file,item.key)"
                  :on-preview="handlePictureCardPreview"
                  :on-remove="handleRemove"
                >
                  <div class="operation_area">
                    <i class="iconfont hjx-a-Folder-uploadwenjianjia-shangchuan"></i>
                  </div>
                </el-upload>
              </div>


            </template>

            <img  width="100%" v-else-if="item.type=='img'" :src="formData[item.key]?.url">
            

            <a v-else-if="item.type=='url'"  @click="HandlePreviewFile(formData[item.key])" >{{ formData[item.key]?.name }}</a>
          <!-- </template> -->

         

        </template>
      </el-form-item>

      <div style="width: 100%;">
        <slot name="submit" :formRef="formRef" :formData="formData"></slot>
      </div>

    </el-form>

</template>


<script lang="ts" setup>
import { ref, computed, watch } from 'vue'
import noDataBg from '@/assets/bg/table_no_data.png'
import deleteIcon from '@/assets/icon/delete.svg'
import {Loading} from '@element-plus/icons-vue'

import closeFillImg from '@/assets/icon/close_fill.svg'


const previewVisible = ref(false)
const fileList = ref([
   {
    name: 'food.jpeg',
    url: 'https://jtzx001.oss-accelerate.aliyuncs.com/huijiaoyan_test/20260114_50007/14091841_0834e935-5393-4981-ba53-3c37fda73a1f.jpeg',
  },
])

const handlePictureCardPreview = ()=>{
  console.log('预览')
}


const handleRemove = ()=>{
  console.log('移除')
}
type  ItemType = 
  |'input'|'password'|'textarea'|'number'|'radio'
  |'select'|'multipleSelect'| 'multipleSelectSearch' |'unionSelect' |'checkbox'|'datePicker' | 'dateTimePickerNoRange'
  |'dateTimePicker'|'url'|'file' | 'switch' | 'imgFile' | 'noDragFile' | 'img'


interface formItemProperty {
  key: String,
  label: String,
  type:ItemType,
  checkAll?:Boolean
  placeholder?:|String 
              | {
                rangeSeparator:String,
                startPlaceholder:String
                endPlaceholder:String
              },
  rules: any[],
  hidden?: Boolean,
  disabled?: Boolean,
  custom?:Boolean,
  style?: Record<string, any>,
  className?:String,
  unionSelectList?:{
    key:String,
    type:String,
    placeholder:String,
    disabled:Boolean,
    style:Record<string, any>,
    selectList: { label: string, value: any }[] | [],
  }[]
  selectList?: { label: string, value: any }[] | [],
  rows?:number,
  tips?:String,
}

const props = defineProps({
    width:{
      required:false,
    },
   
    formItemList:{
        type:Array<formItemProperty>,
        required:true,
        // default:()=>[]
    },
    
    defaultFormData:{
      type:Object,
      required:true,
    },
    formDisabled:{
      type:Boolean,
      default:false
    },
    fileLoading:{
      type:Boolean,
      default:false
    },
    inlineLayout:{
      type:Boolean,
      default:true
    },
    labelWidth:{
      type:String,
      default:'auto'
    }


})
const emit  = defineEmits(['close','confirm','formItemChange','fileUpload'])

const formRef = defineModel('formRef')


const fileMessage = ref({})
const formData = ref({})
// const formRef = ref()

const finalFormItemList = computed(()=>{
    return props.formItemList.filter(item=>!item.hidden)
})

// 是否全选

watch(()=>props.defaultFormData,(newVal)=>{
  formData.value = newVal
},{immediate:true})

const formSubmitCheck = async (formEl) => {
  if(props.formDisabled){
    closeDialog()
    return
  }
  if (!formEl) return
  await formEl.validate(async(valid) => {
    if (valid) {
      emit('confirm', {formData:formData.value,formRef:formEl})
    }
  }).catch(err=>{
    console.log('报错信息',err)
  })
}

const HandlePreviewFile = (file)=>{
  console.log('附件信息',file)
  previewVisible.value = true
  fileMessage.value  = {url:file.url,name:file.name}
}

const closeDialog = () => {
  formRef.value.resetFields()
  emit('close')
}

const HandClosePreview = ()=>{
  fileMessage.value = {}
  previewVisible.value = false
}

const handleSelectChange = (key,val,type,selectList,subKey) =>{
  if(type == 'unionSelect'){
    if(formData.value[key]){
      formData.value[key][subKey] = val
    }else{
      formData.value[key] = {}
      formData.value[key][subKey] = val
    }
  }
  emit('formItemChange',{key,val,formData:formData.value,subKey})
}

const handleCheckAllOrNot = (val,key,allData)=>{
  let allValue = allData.map(item=>item.value)
  let finalVal = val ? allValue : [] 
  formData.value = {...formData.value,[key]:finalVal}
  // 选项----
  emit('formItemChange',{key,val:finalVal,formData:formData.value})
}

const handleFileChange = (file,formKey)=>{
  emit('fileUpload',{key:formKey,file})
}

const HandleRemove = (formKey)=>{
  formData.value[formKey] = null
}

</script>  
<style lang="scss" scoped>
.img_file_area{
  width: 100%;
  display: flex;
  gap:10px;
  align-items: center;

  >span{
    position: relative;
    .close{
      width: 14px;
      height: 14px;
      color: #F56C6C;
      position:absolute;
      top:-5px;
      right: -2px;
    }
  }

  .cover,
  .operation_area{
    width: 90px;
    height: 60px;
    border-radius: 6px;
    background-color: #f0f4f8;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .operation_area{
    background-color: #F0F4F8;
    font-size: 24px;
  }
}

.multipleSelect{
  :deep(.el-select__wrapper){
     height: auto;
  }
}

.upload-demo{
  width: 100%;
  .file_list{
    // 拖拽
    width: 80%;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    gap:5px;

    .el-upload__tip{
      flex:1 1;
      display: flex;
      justify-content: space-between;
      align-items: center;

      margin-top: 0;
      // 拖拽
      background-color: white;
      padding:0 8px;
      > a{
        color: #666;
      }
      > img{
        width: 15px;
      }
    }

    .hjx-dui {
      color: #2dab85;
      font-size: 16px;
    }
  }
  .el-button{
    background-color: #2e64fa;
  }

 

  .no_drag_content{
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: flex-start;
    .file_list{
      width: 100%;
      background-color: #F5F7FC;
      .el-upload__tip{
        background-color: transparent;
      }
    }
  }

  :deep(.el-upload-dragger){
    background-color: #f0f4f7;
    border:dashed #9a9c9e 1px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 10px;
    .no_data{
      width: 60px;
    }
  }
}

.el-form{
  .el-form-item{
    margin-bottom: 20px;
  }
}


.check_group_list{
  width: 100%;
}

.delete_item{
  width: 96px;
  height: 36px !important;
  font-weight: 400;
  font-size: 14px;
  text-align: center;
  cursor: pointer;
}

.iconfont {
  margin-right: 5px;

  &.hjx-a-Folder-uploadwenjianjia-shangchuan{
    color: #999999;
    font-size: 24px;
  }
}

.page_dialog{
  :deep(.el-dialog__body){
    min-height: 156px;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  a{
    &:hover{
      cursor: pointer;
    }
  }
}

</style>

<style lang="scss">
//部分标签顶部对齐
.top_label{
  .el-form-item__label-wrap{
    // border:solid red 1px;
    align-self: flex-start;
  }
}


</style>