<template>
  <BaseDialog v-bind="$attrs" v-on="listeners" @submit="onSubmit" width="876px" top="7vh">
    <BaseTitle>设备基本信息</BaseTitle>
    <el-row :gutter="20">
      <el-col :span="12">
        <el-form
          class="form"
          ref="form"
          v-bind="{ labelWidth: '8em', size: 'medium' }"
          :model="formData"
          :rules="rules"
        >
          <el-form-item
            v-for="{ name, label, type, required, options, onChange, disabled, ...rest } of formItems"
            :key="name"
            :required="required"
            :label="label"
            :prop="name"
          >
            <el-date-picker
              v-if="type === 'date'"
              v-model="formData[name]"
              value-format="yyyy-MM-dd"
              format="yyyy-MM-dd"
              :disabled="disabled"
              :placeholder="`请选择${label}`"
              clearable
              size="small"
              v-bind="rest"
            />
            <el-select
              v-else-if="type === 'select'"
              v-model="formData[name]"
              filterable
              :placeholder="`请选择${label}`"
              size="small"
              clearable
              v-bind="rest"
              @change="onChange"
              style="width:100%"
            >
              <el-option v-for="item in options" :key="item.id" :label="item.deviceTypeName" :value="item.id" />
            </el-select>
            <el-input
              v-else
              v-model="formData[name]"
              :type="type || 'text'"
              :disabled="disabled"
              :placeholder="name === 'no' ? '系统自动添加' : `请输入${label}`"
              size="small"
              clearable
              v-bind="rest"
            />
          </el-form-item>
        </el-form>
      </el-col>
      <el-col :span="12">
        设备照片
        <span style="margin-left:5px; color:#ccc">(最多上传9张)</span>
        <div style="margin-top:20px" class="upload">
          <el-upload
            list-type="picture-card"
            :on-preview="handlePictureCardPreview"
            :on-remove="handleRemovePic"
            multiple
            :auto-upload="false"
            :file-list="formData.filesPath"
            :on-change="onFileChange"
            action="whatever"
            accept=".jpg,.jpeg,.png"
          >
            <i class="el-icon-plus"></i>
          </el-upload>
        </div>

        <el-dialog :visible.sync="dialogVisible" title="" append-to-body class="preview">
          <img width="100%" :src="dialogImageUrl" alt="" />
        </el-dialog>
      </el-col>
    </el-row>
  </BaseDialog>
</template>

<script lang="ts">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
import BaseDialog from '@/components/BaseDialog/index.vue'
import BaseTitle from '@/components/BaseTitle/index.vue'
import { ElForm } from 'element-ui/types/form'
import { getRemoteImg } from '@/api/ftp'
import { ElUploadInternalFileDetail } from 'element-ui/types/upload'
import { deviceTypeParamPage } from '../api/deviceType'
import { IDevice, IDeviceType } from '../api/common'
import { telAndMobileReg } from '@/utils/constant'

const getDefaultValue = (): Partial<IDevice> => ({
  deviceName: undefined,
  deviceSn: undefined,
  deviceModel: undefined,
  deviceType: undefined,
  deviceFirm: undefined,
  firmLiaison: undefined,
  liaisonPhone: undefined,
  buyTime: undefined,
  remark: undefined
})

@Component({ name: 'TypeForm', components: { BaseDialog, BaseTitle } })
export default class TypeForm extends Vue {
  @Prop({ type: Object, default: () => ({}) }) data!: object
  @Prop({ type: Array, default: () => [] }) types!: IDeviceType[]
  $refs!: { form: ElForm }
  dialogVisible = false
  dialogImageUrl = ''
  formData: Partial<Omit<IDevice, 'filesPath'>> & {
    filesPath?: Partial<ElUploadInternalFileDetail>[]
    param?: string
  } = {
    ...getDefaultValue(),
    filesPath: [],
    param: ''
  }

  get listeners() {
    const { submit, ...rest } = this.$listeners
    return rest
  }

  get formItems() {
    return [
      {
        label: '设备名称',
        name: 'deviceName',
        required: true,
        maxlength: 50
      },
      {
        /** ②	设备出厂唯一编号: 必填，自定义录入文本，要求与设备上的信息一致。 */
        label: '设备SN码',
        name: 'deviceSn',
        maxlength: 64
      },
      {
        /** ③	设备型号: 必填，自定义录入文本。 */
        label: '设备型号',
        name: 'deviceModel',
        maxlength: 50
      },
      {
        /** ④	设备类型: 必填，下拉框，在【设备类型配置】中配置的设备类型。 */
        label: '设备类型',
        name: 'deviceType',
        type: 'select',
        required: true,
        options: this.types,
        onChange: this.getAllTypeParams
      },
      {
        /** ⑤	监测参数: 系统自动显示，根据设备类型关联显示该设备监测参数。 */
        label: '监测指标',
        name: 'param',
        type: 'textarea',
        rows: 3,
        disabled: true
      },
      {
        /** ⑥	设备厂商: 必填，自定义录入文本。 */
        label: '设备厂家',
        name: 'deviceFirm',
        maxlength: 50
      },
      {
        /** ⑦	厂家联系人: 必填，自定义录入文本。 */
        label: '厂家联系人',
        name: 'firmLiaison',
        maxlength: 50
      },
      {
        /** ⑧	联系方式: 必填，自定义录入文本。 */
        label: '联系方式',
        name: 'liaisonPhone',
        maxlength: 50
      },
      {
        /** ⑨	采购时间: 必填，自定义录入文本。 */
        label: '采购时间',
        name: 'buyTime',
        type: 'date',
        style: 'width:100%'
      },
      {
        label: '备注',
        name: 'remark',
        type: 'textarea',
        maxlength: 256
      }
    ]
  }

  rules = {
    deviceName: [
      { required: true, message: '设备名称不能为空！' },
      { max: 50, message: '设备名称不超过50个字符' },
      { pattern: /^[\u4e00-\u9fa5\w -]+$/, message: '允许输入汉字、英文、数字' }
    ],
    deviceType: [{ required: true, message: '请选择设备类型' }],
    deviceFirm: [{ required: true, message: '请输入设备厂家' }],
    deviceModel: [{ required: true, message: '请输入设备型号' }],
    deviceSn: [{ required: true, message: '请输入设备SN码' }],
    firmLiaison: [{ required: true, message: '请输入厂家联系人' }],
    liaisonPhone: [
      { required: true, message: '请输入联系方式' },
      { pattern: telAndMobileReg(), message: '请输入正确的联系方式' }
    ],
    buyTime: [{ required: true, message: '请选择采购时间' }]
  }
  /** 没有查询全部类型参数的接口, 暂用分页接口 */
  async getAllTypeParams(typeId: number) {
    try {
      const {
        result: { records }
      } = await deviceTypeParamPage({ typeId, current: 1, size: 9999 })
      this.formData = {
        ...this.formData,
        param: records.length ? records.map((item) => item.targetName).join(', ') : '无'
      }
    } catch (error) {
      console.log(error)
    }
  }

  onSubmit() {
    this.$refs.form.validate((valid) => {
      if (valid) {
        const { param, filesPath, ...rest } = this.formData
        this.$emit('submit', { ...rest, filesPath: filesPath.map(({ raw }) => raw) })
      }
    })
  }

  onFileChange(file, filesPath) {
    console.log(filesPath)
    const isJPG = file.raw.type === 'image/jpeg'
    const isPng = file.raw.type === 'image/png'
    const isLt2M = file.size / 1024 / 1024 < 2
    let needRemove = false
    if (!isJPG && !isPng) {
      this.$message.error('上传图片只能是 JPG/JPEG或png 格式!')
      needRemove = true
    }
    if (!isLt2M) {
      this.$message.error('上传头像图片大小不能超过 2MB!')
      needRemove = true
    }
    if (filesPath.length > 9) {
      this.$message.error('最多可以上传9张图片!')
      needRemove = true
    }

    this.formData.filesPath = needRemove ? filesPath.filter((item) => item.uid !== file.uid) : [...filesPath]
  }

  handleRemovePic(file, filesPath) {
    this.formData.filesPath = filesPath.filter((item) => item.uid !== file.uid)
  }

  handlePictureCardPreview(file) {
    this.dialogImageUrl = file.url
    this.dialogVisible = true
  }

  @Watch('data', { immediate: true })
  setDefaultData(val: IDevice) {
    this.formData = val.id
      ? {
          ...val,
          filesPath: (val.thumbnailUploadFiles || []).map((file) => ({
            name: file.fileName || file.filePath,
            url: getRemoteImg(file.filePath),
            uid: file.id
          }))
        }
      : { ...getDefaultValue(), param: '', filesPath: [] }
    if (val.deviceType) this.getAllTypeParams(val.deviceType)
  }
}
</script>
<style lang="scss" scoped>
.upload {
  /deep/ .el-upload-list--picture-card .el-upload-list__item,
  /deep/ .el-upload--picture-card {
    width: 120px;
    height: 120px;
  }
  /deep/ .el-upload--picture-card {
    line-height: normal;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}
.preview {
  /deep/ .el-dialog .el-dialog__header {
    border-bottom: 0;
  }
}
</style>
