<template>
    <img :src="image_data" :title="title || (owner + ':' + src)" :alt="alt" :class="imgClass"
         :width="width" :height="height" :style="{objectFit: fit}"/>
</template>

<script>
import {mapActions, mapGetters} from "vuex";
import fileCache from "../fileCache";

export default {
    name: "AuthenticatedImage",
    props: {
        src: {
            type: String,
            required: false,
            default: null
        },
        owner: {
            type: String,
            required: true
        },
        title: {
            type: String,
            default: ''
        },
        alt: {
            type: String,
            default: 'image'
        },
        imgClass: {
            type: String,
            default: ''
        },
        fallbackSrc: {
            type: String,
            default: '/assets/img/avatars/avatar.png'
        },
        width: {
            type: [String, Number],
            default: null
        },
        height: {
            type: [String, Number],
            default: null
        },
        fit: {
            type: String,
            default: 'contain'
        },
        refreshKey: {
            type: [String, Number],
            default: null
        }
    },
    data() {
        return {
            image_data: "",
            servers: [],
            lastRequestId: 0
        }
    },
    computed: {
        ...mapGetters(["signAuth"])
    },
    methods: {
        ...mapActions(["getFriendServers"]),
        async loadImage() {
            const requestId = ++this.lastRequestId;
            if (!this.src) {
                if (requestId === this.lastRequestId) {
                    this.image_data = this.fallbackSrc;
                }
                return;
            }
            try {
                // Cached by src alone: content is hash-addressed and immutable (see fileCache.js),
                // so every instance showing the same file shares one fetch and blob.
                const url = await fileCache.get(this.src, async () => {
                    this.servers = await this.getFriendServers({username: this.owner});
                    const response = await this.servers.getRaw(this.signAuth, this.src);
                    if (!response || !response.ok) {
                        throw new Error('failed to fetch ' + this.src);
                    }
                    return await response.blob();
                });
                if (requestId === this.lastRequestId) {
                    this.image_data = url;
                }
            } catch (_e) {
                if (requestId === this.lastRequestId) {
                    this.image_data = this.fallbackSrc;
                }
            }
        }
    },
    watch: {
        src() {
            this.loadImage();
        },
        owner() {
            this.loadImage();
        },
        refreshKey() {
            this.loadImage();
        }
    },
    mounted() {
        this.loadImage();
    }
}
</script>