<template>
  <div>
    <div style="display: flex;">
      <UploadDragger
        class="upload-file"
        v-bind="$attrs"
        :list-type="listType"
        :accept="getStringAccept"
        :multiple="multiple"
        :showUploadList="false"
        :maxCount="maxNumber"
        :before-upload="beforeUpload"
        :custom-request="customRequest"
        @preview="handlePreview"
        @remove="handleRemove"
      >
        <p class="ant-upload-drag-icon">
          <inbox-outlined></inbox-outlined>
        </p>
        <p class="ant-upload-text">单击或拖动文件到此区域进行上传</p>
        <p class="ant-upload-hint"> 支持单次或批量上传。 </p>
      </UploadDragger>
      <div :class="`copy-other ${$attrs.disabled? 'copy-other-disabled': ''}`" @click="openSelectOther">历史举证</div>
    </div>

    <div class="file-item" v-for="(item, index) in fileList" :key="index">
      {{ handlerDealFileName(item.name) }}
      <span class="delete-btn" @click="handlerDelete(index)" v-if="!$attrs.disabled"
        ><DeleteOutlined
      /></span>
      <span class="delete-btn" @click="handlerPreviewFile(item.url)"
        ><CloudDownloadOutlined
      /></span>
      <span class="delete-btn" @click="openFile(item.url)" v-if="showIcon(item.url)"
        ><FolderOpenOutlined
      /></span>
    </div>
    <Modal :open="previewOpen" :title="previewTitle" :footer="null" @cancel="handleCancel">
      <img alt="" style="width: 100%" :src="previewImage" />
    </Modal>
    <a-modal v-model:open="openSelectOtherModal" title="历史举证" :footer="null" :destroyOnClose="true">
      <FileUploadSelectOtherModal
        :server="props.server"
        @save="saveOtherFile"
      />
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import { ref, toRefs, watch, useAttrs } from 'vue';
  import {
    PlusOutlined,
    InboxOutlined,
    DeleteOutlined,
    CloudDownloadOutlined,
    FolderOpenOutlined,
  } from '@ant-design/icons-vue';
  import type { UploadFile, UploadProps } from 'ant-design-vue';
  import { Modal, UploadDragger } from 'ant-design-vue';
  import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
  import { useMessage } from '@/hooks/web/useMessage';
  import { isArray, isFunction, isObject, isString } from '@/utils/is';
  import { warn } from '@/utils/log';
  import { useI18n } from '@/hooks/web/useI18n';
  import { useUploadType } from '../hooks/useUpload';
  import { uploadContainerProps } from '../props';
  import { isImgTypeByName } from '../helper';
  import { UploadResultStatus } from '@/components/Upload/src/types/typing';
  import { fileUploadApi } from '@/api/sys/upload';
  import axios from 'axios';
  import FileUploadSelectOtherModal from './FileUploadSelectOtherModal.vue'

  defineOptions({ name: 'ImageUpload' });

  const emit = defineEmits(['change', 'update:value', 'delete']);
  const props = defineProps({
    ...uploadContainerProps,
  });
  const attrs = useAttrs()
  const { t } = useI18n();
  const { createMessage } = useMessage();
  const { accept, helpText, maxNumber, maxSize } = toRefs(props);
  const isInnerOperate = ref<boolean>(false);
  const { getStringAccept } = useUploadType({
    acceptRef: accept,
    helpTextRef: helpText,
    maxNumberRef: maxNumber,
    maxSizeRef: maxSize,
  });
  const previewOpen = ref<boolean>(false);
  const previewImage = ref<string>('');
  const previewTitle = ref<string>('');

  const fileList = ref<UploadProps['fileList']>([]);
  const isLtMsg = ref<boolean>(true);
  const isActMsg = ref<boolean>(true);
  const openSelectOtherModal = ref(false)

  watch(
    () => props.value,
    (v) => {
      if (isInnerOperate.value) {
        isInnerOperate.value = false;
        return;
      }

      if (v) {
        let value: string[] = [];
        if (isArray(v)) {
          value = v;
        } else {
          value.push(v);
        }
        fileList.value = value.map((item, i) => {
          if (item && isString(item)) {
            return {
              uid: -i + '',
              name: item.substring(item.lastIndexOf('/') + 1),
              status: 'done',
              url: item,
            };
          } else if (item && isObject(item)) {
            return item;
          } else {
            return;
          }
        }) as UploadProps['fileList'];
      }

      let arr = props.value?.split(',') as [];
      fileList.value = [];
      const { server } = props;
      arr?.forEach((item, index) => {
        if (item) {
          fileList.value?.push({
            uid: '-1',
            name: item,
            status: 'done',
            url: server + '/' + item,
          });
        }
      });
    },
  );
  const openFile = (url) => {
    console.log(url)
    if(url.indexOf('.pdf') !== -1){
      axios({
        method: 'get',
        url: url,
        responseType: 'blob',
        headers: {
          'Content-Disposition': 'inline',
        }
      })
      .then(response => {
        let blob = new Blob([response.data], {type: 'application/pdf'});
        let pdfUrl = window.URL.createObjectURL(blob)
        window.open(pdfUrl);
      })
      .catch(error => {
        console.error(error);
      });
    }else{
      window.open(url, '_blank');
    }
    
  }

  function handlerDealFileName(path){
    const regex = /([^/\\]+)(?=\.[^/\\]*$|$)/;
    const matchStr = path.match(regex);
    if(matchStr?.length){
      return matchStr[0];
    }
  }
  const showIcon = (url) => {
    if(
      url.indexOf('.png') !== -1 || 
      url.indexOf('.pdf') !== -1 || 
      url.indexOf('.jpg') !== -1 || 
      url.indexOf('.jpeg') !== -1
    ){
      return true;
    }
    return false
  }
  function getBase64<T extends string | ArrayBuffer | null>(file: File) {
    return new Promise<T>((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => {
        resolve(reader.result as T);
      };
      reader.onerror = (error) => reject(error);
    });
  }

  const handlePreview = async (file: UploadFile) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64<string>(file.originFileObj!);
    }
    previewImage.value = file.url || file.preview || '';
    previewOpen.value = true;
    previewTitle.value =
      file.name || previewImage.value.substring(previewImage.value.lastIndexOf('/') + 1);
  };

  const handleRemove = async (file: UploadFile) => {
    if (fileList.value) {
      const index = fileList.value.findIndex((item) => item.uid === file.uid);
      index !== -1 && fileList.value.splice(index, 1);
      const value = getValue();
      isInnerOperate.value = true;
      emit('change', value);
      emit('delete', file);
    }
  };

  const handlerDelete = (index) => {
    fileList.value.splice(index, 1);
    let value = getValue();
    emit('change', value);
  };

  const handlerPreviewFile = (path) => {
    window.open(path, '_blank');
  };

  const handleCancel = () => {
    previewOpen.value = false;
    previewTitle.value = '';
  };

  const beforeUpload = (file: File) => {
    const { maxSize, accept } = props;
    const { name } = file;
    // const isAct = isImgTypeByName(name);
    const isAct = true;
    if (!isAct) {
      createMessage.error(t('component.upload.acceptUpload', [accept]));
      isActMsg.value = false;
      // 防止弹出多个错误提示
      setTimeout(() => (isActMsg.value = true), 1000);
    }
    const isLt = file.size / 1024 / 1024 > 50;
    if (isLt) {
      createMessage.error(t('component.upload.maxSizeMultiple', [50]));
      isLtMsg.value = false;
      // 防止弹出多个错误提示
      setTimeout(() => (isLtMsg.value = true), 1000);
    }
    return (isAct && !isLt) || Upload.LIST_IGNORE;
    // return isAct || Upload.LIST_IGNORE;
  };

  async function customRequest(info: UploadRequestOption<any>) {
    const { api, server, action } = props;

    // if (!api || !isFunction(api)) {
    //   return warn('upload api must exist and be a function');
    // }

    try {
      const res = await fileUploadApi?.(
        {
          data: {
            ...(props.uploadParams || {}),
          },
          file: info.file,
          name: props.name,
          filename: props.filename,
        },
        server + action,
      );
      fileList.value?.push({
        uid: '-1',
        name: info.file.name,
        status: 'done',
        url: server + '/' + res.data.result[0].filePath,
      });
      info.onSuccess!();
      const value = getValue();
      // isInnerOperate.value = true;
      emit('change', value);
    } catch (e: any) {
      info.onError!(e);
    }
  }

  function getValue() {
    let path = '';
    const { server } = props;
    fileList.value?.forEach((item, index) => {
      path += item.url?.replace(server + '/', '') + ',';
    });
    return path;
  }
  const openSelectOther = () => {
    if(attrs.disabled) return
    openSelectOtherModal.value = true
  }
  const saveOtherFile = (list:string[]) => {
    const { server } = props;
    list.forEach(item => {
      fileList.value?.push({
        uid: '-1',
        name: item,
        status: 'done',
        url: server + '/' + item,
      });
    })
    const value = getValue();
    emit('change', value);
    openSelectOtherModal.value = false
  }
</script>

<style lang="less">
  .ant-upload-select-picture-card i {
    color: #999;
    font-size: 32px;
  }

  .ant-upload-select-picture-card .ant-upload-text {
    margin-top: 8px;
    color: #666;
  }

  .file-item {
    width: 100%;
    height: 40px;
    padding: 10px;
    border-radius: 6px;
    border: 1px dashed #d9d9d9;
    margin: 10px 0px;
  }
  .delete-btn {
    float: right;
    color: #d9d9d9;
    cursor: pointer;
    margin: 0px 8px;
  }
  .delete-btn:hover {
    color: #999;
  }
</style>
<style lang="scss" scoped>
.upload-file{
  width: calc(100% - 161px);
}
.copy-other{
  width: 161px;
  // height: 100px;
  border: 1px dashed #d9d9d9;
  background-color: rgba(0, 0, 0, 0.02);
  cursor: pointer;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-left: 10px;
}
.copy-other:hover{
  border-color: #0960bd;
}
.copy-other-disabled{
  cursor: no-drop;
  border-color: #d9d9d9 !important;
}
</style>
