<template>
  <div>
    <img :class="_classSrc" 
        :src="srcUrl" 
        :width="_width"
        :height="_height" 
        :alt="_alt"  
    />
    <img :class="_classBase64" 
        :src="srcBase64Url" 
        :width="_width"
        :height="_height" 
        :alt="_alt"  
    />
  </div>
</template>

<script lang="ts">
import Vue from 'vue';

const isDev = (process.env.NODE_ENV !== 'production')
let observer!: any;

export default Vue.extend({
  name: 'ImgSwap',
  props: {
    classe: {
      type: String
    },
    src: {
      type: String
    },
    height: {
      type: Number
    },
    width: {
      type: Number
    },
    alt: {
      type: String
    },
    base64: {
      type: String
    },
    nolazy: {
      type: String
    },
    lazydistance: {
      type: Number
    }
  },
  data() {
    return {
      intersected : false,
      srcData : '',
      srcBase64Data: '',
      classBase64: '',
      classSrc: ''
    }
  },
  computed: {
    _classBase64():any {
        return this.classBase64
    },
    _classSrc():any {
        return this.classe + ' img_default'
    },
    _src():any {
        return this.src
    },
    _alt():any {
        return this.alt
    },
    _width():any {
        return this.width
    },
    _height():any {
        return this.height
    },
    srcUrl():any {
        return this.srcData
    },
    srcBase64Url():any {
        return this.srcBase64Data
    }
  },
  mounted() {
    this.classBase64 = this.classe + ' img_base64'

    let lazydistance = (this.lazydistance === undefined || this.lazydistance === null) ? "0px" : this.lazydistance + "px"
    const options = { rootMargin: lazydistance };

    if(!isDev) {

        observer = new IntersectionObserver(entries => {
            const entry = entries[0];

            if (entry.isIntersecting) {
                this.intersected = true;
                observer.disconnect();

                this.loadImage().then((base:any) => {
                    this.srcData = base
                    this.classBase64 += ' hide64'
                })
            }
        }, options);

        observer.observe(this.$el);
    }

    if (this.base64 === undefined || this.base64 === null) {
    } else {
        if( this.base64.startsWith("data:image") ) {
            this.srcData = this.base64
        } else {
            this.srcData = 'data:image/jpeg;base64,' + this.base64
        }
    }
  },
  destroyed() {
    if(observer)
        observer.disconnect();
  },
  methods: {
    loadImage(){
        return new Promise((resolve) => {
            if(typeof this.src === 'string') {
            fetch(this.src)
                .then(response => response.blob())
                .then(blob => {
                const reader = new FileReader()
                reader.onloadend = () => {
                    return resolve(reader.result)
                }
                reader.readAsDataURL(blob)
                })
            } else {
            return ""
            }
        })
    },
  }
})
</script>

<style scoped>
img {
  -webkit-transition: all 0.5s ease-in-out;
  -moz-transition: all 0.5s ease-in-out;
  -o-transition: all 0.5s ease-in-out;
  transition: all 0.5s ease-in-out;
}
</style>