<template>
  <image
    v-if="img_url"
    :src="img_url"
    :mode="mode"
    :lazy-load="lazyLoad"
    :fade-show="fadeShow"
    :webp="webp"
    :show-menu-by-longpress="showMenuByLongpress"
    :style="[style]"
    @tap="fnEvent('click', $event)"
    @error="fnEvent('error', $event)"
    @load="fnEvent('load', $event)"
  />
</template>

<script>
  import { storage,config,CHCHEPREFIX } from '@/util/index'
  // 获取全局唯一的文件管理器
  const fileSystemManager = uni.getFileSystemManager()
  /**
   * kingImageCache 图片缓存
   * @description 图片缓存
   * @property {string} imgSrc 图片资源地址
   * @property {string} mode 图片裁剪、缩放的模式
   * @property {boolean} lazyLoad 图片懒加载。只针对page与scroll-view下的image有效
   * @property {boolean} fade-show 图片显示动画效果
   * @property {boolean} webp 默认不解析 webP 格式，只支持网络资源
   * @property {boolean} show-menu-by-longpress 开启长按图片显示识别小程序码菜单
   * @property {string} prefixTxt 缓存的文件
   * @property {string} width 宽度，单位任意，如果为数值，则为 rpx 单位
   * @property {string} height 高度，单位任意，如果为数值，则为 rpx 单位
   * @property {object} custom-style 自定义样式
   * @property {object} defaultImg 默认图片
   * @event {Function} click 点击图片
   * @event {Function} error 错误发生
   * @event {Function} load 图片载入完毕
   */
  export default {
    props: {
      imgSrc: {
        type: String,
      },
      mode: {
        type: String,
        default: 'scaleToFill',
      },
      lazyLoad: {
        type: Boolean,
        default: false,
      },
      fadeShow: {
        type: Boolean,
        default: true,
      },
      webp: {
        type: Boolean,
        default: false,
      },
      showMenuByLongpress: {
        type: Boolean,
        default: false,
      },
      prefixTxt: {
        type: String,
        default: '',
      },
      width: {
        type: [String, Number],
      },
      height: {
        type: [String, Number],
      },
      customStyle: {
        type: Object,
        default: () => ({}),
      },
      defaultImg: {
        type: String,
        default: '',
      },
    },
    data() {
      return {
        img_url: '',
		prefix:'',
      }
    },
    computed: {
      style() {
        const style = {}
        // 判断传过来的值是否为 undefined null false ''
        const isEmpty = (val) => [undefined, null, false, ''].includes(val)
        !isEmpty(this.width) && (style.width = this.addUnit(this.width))
        !isEmpty(this.height) && (style.height = this.addUnit(this.height))
        return {
          ...style,
          ...this.customStyle,
        }
      },
    },
    watch: {
      img_url: {
        handler: async function (new_url, old_url) {
			console.log("url>>>>>", new_url, old_url);
          // 如果没有标识，默认一个
          if (!this.prefixTxt) {
            this.prefix = CHCHEPREFIX.default_temp
          }
          const prefixList = storage(this.prefix)
          // 获取缓存文件，没有直接下载
          if (prefixList) {
            const storageList = JSON.parse(prefixList) ? JSON.parse(prefixList) : prefixList
            // 存在图片缓存
            if (storageList[this.imgSrc]) {
              const imgSrcList = storageList[this.imgSrc]
              const hasSavedFile = await this.checkSaveFile(imgSrcList)
              // 如果本地文件还存在，防止用户自动清除本地缓存，而storage不存在的问题
              if (hasSavedFile) {
                this.img_url = imgSrcList
              } else {
                // 删除storage里面这一项
                delete storageList[this.imgSrc]
                // 如果是临时储存，有过期时间
                if (this.prefix.includes('temp')) {
                  storage(this.prefix, JSON.stringify(storageList), config.imageCacheTime)
                } else {
                  storage(this.prefix, JSON.stringify(storageList))
                }
                this.downImageFile()
              }
            } else {
              this.downImageFile()
            }
          } else {
            this.downImageFile()
          }
        },
        immediate: true,
      },
    },
    methods: {
      // 判断文件/目录是否存在
      checkSaveFile(path) {
        return new Promise((resolve) => {
          fileSystemManager.access({
            path,
            success: (res) => {
              // 如果本地储存文件
              if (res.errMsg === 'access:ok') {
                resolve(true)
              } else {
                resolve(false)
              }
            },
            fail: (err) => {
              resolve(false)
            },
          })
        })
      },
      // 添加单位，如果为数值则为rpx单位，否则直接返回
      addUnit(value) {
        value = String(value)
        return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value) ? `${value}rpx` : value
      },
      // 下载缓存文件
      downImageFile() {
        // 如果已经是缓存，不用做处理了
        if (this.img_url.includes('://tmp')) {
          return
        }
        // 下载文件
        uni.downloadFile({
          url: this.imgSrc,
          success: (ress) => {
            if (ress.statusCode === 200) {
              const prefixList = storage(this.prefix)
              // 如果存在缓存
              if (prefixList) {
                const storageList = JSON.parse(prefixList) ? JSON.parse(prefixList) : prefixList
                // 如果不存在图片缓存
                if (!storageList[this.imgSrc]) {
                  // 设置图片缓存
                  storageList[this.imgSrc] = ress.tempFilePath
                  // 如果是临时储存，有过期时间
                  if (this.prefix.includes('temp')) {
                    storage(this.prefix, JSON.stringify(storageList), config.imageCacheTime)
                  } else {
                    storage(this.prefix, JSON.stringify(storageList))
                  }
                }
              } else {
                const params = {}
                params[this.imgSrc] = ress.tempFilePath
                // 如果是临时储存，有过期时间
                if (this.prefix.includes('temp')) {
                  storage(this.prefix, JSON.stringify(params), config.imageCacheTime)
                } else {
                  storage(this.prefix, JSON.stringify(params))
                }
              }
              this.img_url = ress.tempFilePath
            } else {
              this.img_url = ''
            }
          },
          fail: () => {
            this.img_url = ''
          },
        })
      },
      // 发送事件
      fnEvent(emit, event) {
        this.$emit(emit, event)
      },
    },
  }
</script>
