import {
  NButton,
  NModal,
  NUpload,
  UploadCustomRequestOptions,
  UploadFileInfo,
  useMessage
} from 'naive-ui'
import { defineComponent, watch, PropType, reactive, ref } from 'vue'
import Copper from './copper'
import { getUploadSign, onFileUpload, onOnlyFileUpload } from '@/utils/oss-file-upload'

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'
    },
    showFileList: {
      type: Boolean,
      default: true
    },
    desc: {
      type: String,
      default: ''
    },
    // 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',
    'upload:success',
    'close',
    'readFileInputEventAsArrayBuffer',
    'remove'
  ],
  setup(props, { slots, attrs, emit, expose }) {
    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 = () => {
      console.log('desc', props.desc)
      if (props.fileList) {
        console.log('downloadUrl', 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)) {
        // console.log(Array.isArray(props.imageList), props.imageList, 'Array.isArray(props.imageList)')
        let 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()
      },
      { deep: true }
    )
    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)
        const { data } = await getUploadSign(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 onCustomRequest = ({
      file,
      // data,
      // headers,
      // withCredentials,
      action,
      onFinish,
      onError,
      onProgress
    }: UploadCustomRequestOptions) => {
      const item = state

      item.file = file
      onFileUpload({ file, action, data: item, onProgress, onFinish, onError })
    }

    const onFinish = (options: any) => {
      emit('update:fileList', options.file.url)
      emit('upload:success', {
        url: options.file.url,
        name: options.file.name
      })
      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('upload:success', {})
      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)
        const { data } = await getUploadSign(obj)

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

        const fileParams = {
          ...state,
          file: blob
        } as any
        await onOnlyFileUpload(ossUploadUrl, fileParams).then((url: string) => {
          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 {
        //
        return false
      }
    }
    return () => (
      <div>
        <NUpload
          ref={uploadRef}
          action={ossUploadUrl}
          customRequest={onCustomRequest}
          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.listType === 'image' && (
            <NButton loading={btnLoading.value} type="primary">
              {props.text}
            </NButton>
          )}
        </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}
          title="上传图片"
          style={{ width: '800px' }}
        >
          {/* @cropper-no="error" @cropper-ok="success" */}
          <Copper
            ref={CropperModal}
            onClose={() => (visiable.value = false)}
            onCropperOk={cropperOk}
          />
        </NModal>
      </div>
    )
  }
})
