import { NButton, NModal, NUpload, UploadFileInfo, useMessage } from 'naive-ui';
import { defineComponent, watch, PropType, reactive, ref } from 'vue';
import { policy } from './api';
import Copper from './copper';
import axios from 'axios';

export default defineComponent({
  name: 'upload-file',
  props: {
    fileList: {
      type: String,
      default: ''
    },
    imageList: {
      type: Array,
      default: () => []
    },
    accept: {
      // 支持类型
      type: String,
      default: '.jpg,.png,.jpeg,.gif'
    },
    listType: {
      type: String as PropType<'image' | 'image-card'>,
      default: 'image-card'
    },
    showType: {
      type: String as PropType<'default' | 'custom'>,
      default: 'default'
    },
    showFileList: {
      type: Boolean,
      default: true
    },
    // width: {
    //   type: Number,
    //   default: 96
    // },
    // height: {
    //   type: Number,
    //   default: 96
    // },
    text: {
      type: String as PropType<string>,
      default: '上传文件'
    },
    size: {
      // 文件大小
      type: Number as PropType<number>,
      default: 5
    },
    max: {
      type: Number as PropType<number>,
      default: 1
    },
    multiple: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    disabled: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    tips: {
      type: String as PropType<string>,
      default: ''
    },
    bucketName: {
      type: String,
      default: 'gyt'
    },
    path: {
      type: String,
      default: ''
    },
    fileName: {
      type: String,
      default: ''
    },
    cropper: {
      // 是否裁切， 只有图片才支持
      type: Boolean as PropType<boolean>,
      default: false
    },
    options: {
      type: Object,
      default: () => {
        return {
          viewMode: 0,
          autoCrop: true, //是否默认生成截图框
          enlarge: 1, //  图片放大倍数
          autoCropWidth: 200, //默认生成截图框宽度
          autoCropHeight: 200, //默认生成截图框高度
          fixedBox: false, //是否固定截图框大小 不允许改变
          previewsCircle: true, //预览图是否是原图形
          title: '上传图片'
        };
      }
    }
  },
  // readFileInputEventAsArrayBuffer 只会在文件的时间回调
  emits: [
    'update:fileList',
    'close',
    'readFileInputEventAsArrayBuffer',
    'remove'
  ],
  setup(props, { emit, expose, slots }) {
    const ossUploadUrl = `https://${props.bucketName}.ks3-cn-beijing.ksyuncs.com/`;
    const message = useMessage();
    const visiable = ref<boolean>(false);
    const btnLoading = ref<boolean>(false);
    const tempFiileBuffer = ref();
    const uploadRef = ref();
    const state = reactive({
      policy: '',
      signature: '',
      key: '',
      KSSAccessKeyId: '',
      acl: 'public-read',
      name: ''
    }) as any;

    const fileListRef = ref<UploadFileInfo[]>([]);
    const initFileList = () => {
      if (props.fileList) {
        const splitName = props.fileList.split('/');
        fileListRef.value = [
          {
            id: new Date().getTime().toString(),
            name: splitName[splitName.length - 1],
            status: 'finished',
            url: props.fileList
          }
        ];
      } else if (Array.isArray(props.imageList)) {
        const list: any = [];
        props.imageList.forEach((n: any) => {
          const splitName = n.split('/');
          list.push({
            id: Date.now().toString(),
            name: splitName[splitName.length - 1],
            status: 'finished',
            url: n
          });
        });
        fileListRef.value = list;
      } else {
        fileListRef.value = [];
      }
    };
    initFileList();
    watch(
      () => props.imageList,
      () => {
        initFileList();
      }
    );
    watch(
      () => props.fileList,
      () => {
        console.log('list');
        initFileList();
      }
    );
    const handleClearFile = () => {
      uploadRef.value?.clear();
      console.log('清空', uploadRef.value);
    };
    expose({
      handleClearFile
    });

    const CropperModal = ref();
    const onBeforeUpload = async (options: any) => {
      const file = options.file;
      // 文件大小
      let isLt2M = true;
      if (props.size) {
        isLt2M = file.file.size / 1024 / 1024 < props.size;
        if (!isLt2M) {
          message.error(`文件大小不能超过${props.size}M`);
          return false;
        }
      }

      if (!isLt2M) {
        return isLt2M;
      }
      // 是否裁切
      if (props.cropper) {
        getBase64(file.file, (imageUrl: any) => {
          const target = Object.assign({}, props.options, {
            img: imageUrl,
            name: file.file.name // 上传文件名
          });
          visiable.value = true;

          setTimeout(() => {
            CropperModal.value?.edit(target);
            console.log(CropperModal.value, 'cropper');
          }, 100);
        });
        return false;
      }
      try {
        btnLoading.value = true;
        console.log(props.path, file.file);
        const name = file.file.name;
        const suffix = name.slice(name.lastIndexOf('.'));
        // const months = dayjs().format('MM')
        const fileName = `${props.path}${
          props.fileName || Date.now() + suffix
        }`;
        const obj = {
          filename: fileName,
          bucketName: props.bucketName,
          postData: {
            filename: fileName,
            acl: 'public-read',
            key: fileName,
            unknowValueField: []
          }
        };
        const { data } = await policy(obj);

        state.policy = data.policy;
        state.signature = data.signature;
        state.key = fileName;
        state.KSSAccessKeyId = data.kssAccessKeyId;
        state.name = fileName;

        tempFiileBuffer.value = file.file;
      } catch {
        //
        // message.error('上传失败')
        btnLoading.value = false;
        return false;
      }
      return true;
    };
    const getBase64 = async (img: any, callback: any) => {
      const reader = new FileReader();
      reader.addEventListener('load', () => callback(reader.result));
      reader.readAsDataURL(img);
    };
    const onFinish = (options: any) => {
      const url = ossUploadUrl + state.key;
      console.log(url, 'url');
      emit('update:fileList', url);
      emit('readFileInputEventAsArrayBuffer', tempFiileBuffer.value);
      options.file.url = url;
      visiable.value = false;
      btnLoading.value = false;
    };
    const onRemove = async (options: any) => {
      console.log('🚀 ~ options', options);
      emit('update:fileList', '');
      emit('remove');
      btnLoading.value = false;
    };

    // 裁切失败
    // const cropperNo = () => {}
    // 裁切成功
    const cropperOk = async (blob: any) => {
      try {
        // const months = dayjs().format('MM')
        const fileName = `${props.path}${
          props.fileName || new Date().getTime() + '.png'
        }`;
        const obj = {
          filename: fileName,
          bucketName: props.bucketName,
          postData: {
            filename: fileName,
            acl: 'public-read',
            key: fileName,
            unknowValueField: []
          }
        };
        const { data } = await policy(obj);

        state.policy = data.policy;
        state.signature = data.signature;
        state.key = fileName;
        state.KSSAccessKeyId = data.kssAccessKeyId;
        state.name = fileName;

        const formData = new FormData();
        for (const key in state) {
          formData.append(key, state[key]);
        }
        formData.append('file', blob);

        await axios.post(ossUploadUrl, formData).then(() => {
          const url = ossUploadUrl + state.key;
          console.log(url, 'url');
          const splitName = url.split('/');
          fileListRef.value = [
            {
              id: new Date().getTime().toString(),
              name: splitName[splitName.length - 1],
              status: 'finished',
              url: url
            }
          ];
          emit('update:fileList', url);
          visiable.value = false;
        });
      } catch {
        //
        // message.error('上传失败')
        return false;
      }
    };
    return () => (
      <div>
        <NUpload
          ref={uploadRef}
          action={ossUploadUrl}
          data={state}
          v-model:fileList={fileListRef.value}
          listType={props.listType}
          accept={props.accept}
          multiple={props.multiple}
          max={props.max}
          disabled={props.disabled}
          showFileList={props.showFileList}
          showPreviewButton
          onBeforeUpload={(options: any) => onBeforeUpload(options)}
          onFinish={(options: any) => onFinish(options)}
          onRemove={(options: any) => onRemove(options)}>
          {props.showType === 'default' && props.listType === 'image' && (
            <NButton loading={btnLoading.value} type="primary">
              {props.text}
            </NButton>
          )}
          {props.showType === 'custom' && slots.custom && slots.custom()}
        </NUpload>
        {props.tips && (
          <p style="font-size: 13px; color: #666; padding-top: 4px;">
            {props.tips}
          </p>
        )}

        <NModal
          v-model:show={visiable.value}
          preset="dialog"
          showIcon={false}
          class={['modalTitle background']}
          title="上传图片"
          style={{ width: '800px' }}>
          {/* @cropper-no="error" @cropper-ok="success" */}
          <Copper
            // ref="CropperModal"
            ref={CropperModal}
            onClose={() => (visiable.value = false)}
            onCropperOk={cropperOk}
          />
        </NModal>
      </div>
    );
  }
});
