<template>
  <el-form-item v-if="mode === 'form'" :label="label" :prop="prop">
    <div :class="[`${classPrefix}-uploader`, { [`${classPrefix}-uploader--large`]: large }]">
      <el-upload
        ref="uploadRef"
        class="upload-inner"
        action="/api/blade-resource/oss/endpoint/put-file"
        name="file"
        :headers="uploadHeaders"
        :show-file-list="false"
        :disabled="readonly"
        :before-upload="beforeUpload"
        :on-progress="handleProgress"
        :on-success="handleSuccess"
        :on-error="handleError"
      >
        <el-image
          v-if="value"
          :src="value"
          :class="`${classPrefix}-uploader__image`"
          :preview-src-list="[value]"
          fit="contain"
          preview-teleported
          :z-index="3000"
          @click.stop
        />
        <div v-else :class="`${classPrefix}-uploader__empty`">{{ emptyText }}</div>
      </el-upload>
      <el-link
        v-if="value && !readonly"
        type="primary"
        class="upload-replace-link"
        @click.stop="triggerUpload"
      >
        更换
      </el-link>
    </div>
  </el-form-item>
  <el-form-item v-else :prop="prop" :class="`${classPrefix}-upload-item`">
    <div :class="[`${classPrefix}-upload-card`, { [`${classPrefix}-upload-card--large`]: large }]">
      <div v-if="label" :class="`${classPrefix}-upload-card__head`">
        <span :class="`${classPrefix}-upload-card__label`">{{ label }}</span>
        <el-link
          v-if="!readonly"
          type="primary"
          :class="`${classPrefix}-upload-card__action`"
          @click.stop="triggerUpload"
        >
          {{ actionText }}
        </el-link>
        <span v-else :class="`${classPrefix}-upload-card__action`">{{ actionText }}</span>
      </div>
      <el-upload
        ref="uploadRef"
        :class="`${classPrefix}-upload-card__uploader`"
        action="/api/blade-resource/oss/endpoint/put-file"
        name="file"
        :headers="uploadHeaders"
        :show-file-list="false"
        :disabled="readonly"
        :before-upload="beforeUpload"
        :on-progress="handleProgress"
        :on-success="handleSuccess"
        :on-error="handleError"
      >
        <el-image
          v-if="value"
          :src="value"
          :class="`${classPrefix}-upload-card__image`"
          :preview-src-list="[value]"
          fit="contain"
          preview-teleported
          :z-index="3000"
          @click.stop
        />
        <div v-else :class="`${classPrefix}-upload-card__empty`">{{ emptyText }}</div>
      </el-upload>
    </div>
  </el-form-item>
</template>

<script>
import { ElLoading } from 'element-plus';
import { getUploadHeaders } from '@/utils/upload';

export default {
  name: 'ImageUploadField',
  props: {
    label: String,
    prop: String,
    value: String,
    readonly: Boolean,
    headers: Object,
    large: Boolean,
    mode: {
      type: String,
      default: 'form',
    },
    classPrefix: {
      type: String,
      default: 'driver',
    },
    emptyText: {
      type: String,
      default: '上传证件图片',
    },
    actionText: {
      type: String,
      default: '点击上传',
    },
  },
  computed: {
    uploadHeaders() {
      return getUploadHeaders(this.headers || {});
    },
  },
  emits: ['success'],
  data() {
    return {
      uploadLoading: null,
    };
  },
  beforeUnmount() {
    this.closeUploadLoading();
  },
  methods: {
    triggerUpload() {
      const uploadEl = this.$refs.uploadRef && this.$refs.uploadRef.$el;
      const input = uploadEl && uploadEl.querySelector('.el-upload__input');
      if (input) input.click();
    },
    showUploadLoading() {
      if (this.uploadLoading) {
        return;
      }
      this.uploadLoading = ElLoading.service({
        lock: true,
        text: '上传中',
        background: 'rgba(255, 255, 255, 0.7)',
      });
    },
    closeUploadLoading() {
      if (!this.uploadLoading) {
        return;
      }
      this.uploadLoading.close();
      this.uploadLoading = null;
    },
    handleProgress() {
      this.showUploadLoading();
    },
    handleSuccess(res) {
      this.closeUploadLoading();
      if (res.code === 200 && res.data) {
        this.$message.success('上传完成');
        this.$emit('success', res.data.link || res.data.url || res.data.domain || '', res.data);
      } else {
        this.$message.error(res.msg || '上传失败');
      }
    },
    handleError() {
      this.closeUploadLoading();
      this.$message.error('上传失败');
    },
    beforeUpload(file) {
      const validType = ['image/jpeg', 'image/png', 'image/jpg', 'image/bmp'].includes(file.type);
      const validSize = file.size / 1024 / 1024 < 5;
      if (!validType) {
        this.$message.error('仅支持 JPG、PNG、BMP 图片');
      }
      if (!validSize) {
        this.$message.error('图片大小不能超过 5MB');
      }
      const valid = validType && validSize;
      if (valid) {
        this.showUploadLoading();
      }
      return valid;
    },
  },
};
</script>
