<template>
  <div class="ai-uploader">
    <div class="imgList" v-if="type == 'image'">
      <div class="item" v-for="(item, i) in fileList" :key="i">
        <ai-image :src="item.url" :preview="preview"/>
        <u-icon class="delBtn" color="#f46" name="close-circle-fill" size="40" @click="remove(i)"/>
      </div>
      <div v-if="!disabled&&(fileList.length == 0 || (multiple && fileList.length < limit))" class="default"
           @click="upload">
        <u-icon name="photo" size="64" :label="placeholder" label-pos="bottom" label-color="#89b"/>
      </div>
    </div>
    <div class="fileList" v-else>
      <div class="item" v-for="(item, i) in fileList" :key="i">
        <ai-image :preview="preview" :file="item"/>
        <div class="info">
          <span>{{ item.name }} </span>
          <i>{{ item.fileSizeStr }}</i>
        </div>
        <template v-if="!disabled">
          <div class="btn" @tap="handleReUpload(i)">
            重新上传
          </div>
          <div class="btn" @tap="remove(i)">
            删除
          </div>
        </template>
      </div>
      <div v-if="!disabled&&(fileList.length == 0 || (multiple && fileList.length < limit))" class="default"
           @click="upload">
        <u-icon name="photo" size="64" :label="placeholder" label-pos="bottom" label-color="#89b"/>
      </div>
    </div>
  </div>
</template>

<script>
import {mapState} from 'vuex'
import AiImage from '../AiImage/AiImage'

export default {
  name: 'AiUploader',
  components: {AiImage},
  props: {
    limit: {default: 1}, //数量
    placeholder: {default: '添加图片'}, // 文字提示
    type: {default: 'image'}, // 文件类型，image还是file
    multiple: {
      type: Boolean,
      default: false,
    },
    fileId: String,
    mediaId: String,
    def: {default: () => []},
    action: {default: '/admin/file/add'},
    preview: Boolean,
    size: {default: 10 * 1024 * 1024},
    disabled: Boolean,
  },
  computed: {
    ...mapState(['token']),
    errorImage() {
      return this.$cdn + 'file.png'
    },
  },
  watch: {
    def: {
      handler(v) {
        if (!!v?.toString()) {
          if (this.multiple) {
            this.fileList = v
          } else if (v?.url) {
            this.fileList = [v]
          }
        }
      },
      immediate: true,
    },
  },
  data() {
    return {
      fileList: [],
    }
  },
  methods: {
    remove(index) {
      this.fileList.splice(index, 1)
      this.$emit('list', this.fileList)
    },
    upload(wait) {
      let params = {
        count: this.limit,
        sizeType: ['compressed'],
        sourceType: ['album', 'camera'],
        success: (res) => {
          let count = this.fileList?.length + (res.tempFiles?.length || res.tempFile ? 1 : 0)
          if (count > this.limit && this.limit !== 1) {
            return this.$u.toast(`不能超过${this.limit}个`)
          }
          if (res.tempFiles) {
            res.tempFiles?.map((item) => {
              this.uploadFile(item)
            })
          } else if (res?.tempFile) {
            this.uploadFile(res.tempFile)
          }
        },
      }
      typeof wait == 'function' && wait()
      if (this.type == 'image') {
        uni.chooseImage(params)
      } else if (this.type == 'video') {
        uni.chooseVideo(params)
      } else {
        uni.chooseFile(params)
      }
    },
    uploadFile(img) {
      if (this.size > 0 && img.size > this.size) {
        return this.$u.toast(`不能超过${Math.ceil(this.size / 1024 / 1024)}MB`)
      }
      uni.showLoading({title: '上传中'})
      if (this.manual) {
        this.$emit('manual', img)
        uni.hideLoading()
      } else {
        uni.uploadFile({
          url: this.$instance.config.baseURL + this.action,
          filePath: img.path,
          name: 'file',
          header: {
            'Content-Type': 'multipart/form-data',
            Authorization: uni.getStorageSync('token'),
          },
          success: response => {
            uni.hideLoading()
            const res = JSON.parse(response.data)
            if (res?.data) {
              this.$emit('data', res.data)
              this.$u.toast('上传成功!')
              if (this.action.endsWith('/file/add')) {
                this.fileList.push({url: res.data?.[0]?.split(";")?.[0], id: res.data?.[0]?.split(";")?.[1]})
                this.$emit('input', [...this.fileList])
                this.$emit('change', [...this.fileList])
              } else if (this.action == '/admin/file/add2') {
                let info = res.data
                this.$emit('update:fileId', info?.id)
                this.fileList.push(res.data)
              } else if (this.action == '/admin/file/add-portrait') {
                this.fileList.push({url: res.data?.split(";")?.[0], id: res.data?.split(";")?.[1]})
              }
              this.$emit("update:def", this.fileList)
              this.$emit("list", this.fileList)
            } else {
              this.$u.toast(res.msg)
            }
          },
          fail: err => {
            console.log(err)
            uni.hideLoading()
          }
        })
      }

    },
    handleReUpload(i) {
      this.upload(() => this.remove(i))
    },
  },
}
</script>

<style lang="scss" scoped>
.ai-uploader {
  width: 100%;
  line-height: normal;
  margin-bottom: 16px;

  ::v-deep.imgList {
    display: flex;
    flex-wrap: wrap;

    .item {
      position: relative;

      .delBtn {
        position: absolute;
        right: -8px;
        top: -8px;
        z-index: 999;
        border-radius: 50%;
        overflow: hidden;
        background-color: #fff;
      }
    }


    image {
      width: 30vw;
      height: 30vw;
      margin: 0 2px 2px 0;
    }
  }

  .fileList {
    .item {
      display: flex;
      align-items: center;
      margin-bottom: 10px;

      image {
        width: 160px;
        height: 160px;
      }

      i {
        font-style: normal;
        color: #9b9b9b;
      }

      .info {
        flex: 1;
        min-width: 0;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        overflow: hidden;
        text-overflow: ellipsis;

        & > span {
          flex: 1;
          min-width: 0;
        }
      }

      div.btn {
        color: $uni-color-primary;
        margin-right: 16px;

      }

      div:nth-child(4) {
        color: #f72c27;
      }

      & > * + * {
        margin-left: 20px;
      }
    }


  }

  .default {
    width: 30vw;
    height: 30vw;
    box-sizing: border-box;
    border-radius: 8px;
    background: #f3f4f7;
    color: #89b;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;

    .iconfont-iconAdd {
      font-size: 64px;
    }
  }
}
</style>
