<template>
  <div class="comp-content" :class="{ 'auto-width': !clearable }">
    <div class="content">
      <template v-if="clearable">
        <div v-if="fileId" class="preview">
          <div class="file-name" @click="downloadFun">{{ fileName }}</div>
          <div v-if="clearable" class="close" @click="removeFun">
            <el-icon :size="20"><Delete /></el-icon>
          </div>
        </div>
        <div v-else class="upload">
          <el-upload :show-file-list="false" :before-upload="beforeUploadFun">
            <div v-if="!uploading" class="btn">
              <el-button type="primary">上传文件</el-button>
            </div>
            <div v-else class="progress">
              <el-progress :stroke-width="8" :percentage="percentage" />
            </div>
          </el-upload>
        </div>
      </template>
      <div v-else class="download">
        <div class="file-name" @click="downloadFun">{{ fileName }}</div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
import { Delete } from '@element-plus/icons-vue';
import { dataUploadFilesApi } from '@/api/data/data';
import { ElMessage } from 'element-plus';
import { downloadFileById } from '@/utils/file';

interface Props {
  modelValue: any;
  name?: string;
  clearable?: boolean;
  dirId?: number | string;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  name: '',
  clearable: false,
  dirId: '',
});

const emit = defineEmits(['update:modelValue']);

const fileId = ref('');
const fileName = ref(props.name);
const uploading = ref(false);
const percentage = ref(0);

watch(
  () => props.modelValue,
  (val: any) => {
    if (val) {
      fileId.value = val;
      fileName.value = fileName.value || '文件下载';
    } else {
      fileId.value = '';
      fileName.value = '';
    }
  },
  { deep: true, immediate: true }
);

const beforeUploadFun = (file: any) => {
  uploading.value = true;
  const { name } = file;
  const params = {
    fileName: name,
    dirId: props.dirId,
    file: file,
  };
  dataUploadFilesApi(params, (event: any) => {
    const { loaded, total } = event;
    const percent = (loaded / total) * 100;
    percentage.value = Number(percent.toFixed(2));
  })
    .then((res: any) => {
      if (res.code === 200) {
        fileId.value = res.data.fileId;
        fileName.value = name;
        emit('update:modelValue', res.data.fileId);
        ElMessage.success('上传成功');
      }
    })
    .finally(() => {
      uploading.value = false;
      percentage.value = 0;
    });
  return false;
};

const downloadFun = () => {
  const id: any = fileId.value;
  downloadFileById(id);
};

const removeFun = () => {
  fileId.value = '';
  fileName.value = '';
  emit('update:modelValue', '');
};
</script>

<style lang="scss" scoped>
.comp-content {
  width: 100%;
  height: 100%;
  margin: 0 var(--margin-tiny);
  &.auto-width {
    width: auto;
  }
  .content {
    width: 100%;
    height: 100%;
    .preview {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      .file-name {
        max-width: calc(100% - 30px);
        height: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        color: var(--el-color-primary);
        cursor: pointer;
        &:hover {
          text-decoration: underline;
        }
      }
      .close {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 24px;
        height: 24px;
        color: var(--el-color-danger);
        padding-left: var(--padding-small);
        cursor: pointer;
      }
    }
    .download {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      .file-name {
        height: 100%;
        color: var(--el-color-primary);
        cursor: pointer;
        &:hover {
          text-decoration: underline;
        }
      }
    }
    .upload {
      width: 100%;
      > div {
        width: 100%;
        .btn {
          width: 100%;
        }
        .progress {
          width: 100%;
        }
      }
    }
  }
}
</style>
