<template>
    <div class="kds-video-js" :id="id" v-once />
</template>

<script>
import { debounce } from "lodash-es";
import $ from "jquery";
import { getScrollParent } from "popper.js/dist/esm/popper-utils";

export default {
    name: "VideoJS",
    props: {
        id: {
            type: [String, Number],
            default: "",
        },
        src: {
            type: String,
            required: "",
        },
        type: {
            type: String,
            default: "video",
        },
        provider: {
            type: String,
            default: "",
        },
        poster: {
            type: [String, Object],
            default: "",
        },
        accessibility: {
            type: Object,
            default: null,
        },
        media: {
            type: Object,
            default: null,
        },
    },
    data() {
        return {
            videoTemplate: "<video class='video-js kb-vjs-video vjs-default-skin'></video>",
            audioTemplate: "<audio class='video-js kb-vjs-audio vjs-default-skin' controls></audio>",
            player: null,
            scrollPos: 0,
            progress: 0,
        };
    },
    watch: {
        src(value, oldValue) {
            if (value === oldValue) {
                return;
            }
            if (!this.player) {
                this.startVideoJS();
            } else if (this.type === "video") {
                this.player.src(value);
            } else {
                this.debouncedRestartVideoJS();
            }
        },
        type(value, oldValue) {
            if (value === oldValue) {
                return;
            }
            this.debouncedRestartVideoJS();
        },
        provider(value, oldValue) {
            if (value === oldValue) {
                return;
            }
            this.debouncedRestartVideoJS();
        },
    },
    beforeDestroy() {
        this.videojsUtils.destroyVideoJS({ container: this.$el });
        this.player = null;
    },
    mounted() {
        this.startVideoJS();
        this.debouncedRestartVideoJS = debounce(this.restartVideoJS, 100);
    },
    computed: {
        attrs() {
            const defaultMedia = {
                provider: this.provider,
                url: this.src,
                poster: this.poster,
                type: this.type,
                a11y: this.accessibility,
            };
            const media = this.videojsUtils.vjsEncode(this.media || defaultMedia);

            return {
                "src": this.src,
                "data-media": media,
            };
        },
    },
    methods: {
        async startVideoJS() {
            await this.videojsUtils.destroyVideoJS({ container: this.$el });
            const $el = $(this.$el);
            $el.html("");

            if (this.type === "video") {
                const $video = $(this.videoTemplate).attr(this.attrs);
                $el.prepend($video);
            } else if (this.type === "audio") {
                $el.prepend($(this.audioTemplate).attr(this.attrs));
            }

            const videojsStack = await this.videojsUtils.startVideoJS({
                container: $el,
                isEdit: true,
                fromFroala: false,
                onFullscreenChange: this.fixScrollPosition,
                onProgress: this.onProgress,
            });
            this.player = videojsStack.playersStarted[0];
        },
        async restartVideoJS() {
            await this.videojsUtils.destroyVideoJS({ container: this.$el });
            this.player = null;
            this.startVideoJS();
        },
        onProgress(player, eventName) {
            let calculatedProgress = 0;
            const currentTime = this.player.currentTime();
            if (!isNaN(currentTime) && currentTime > 0) {
                calculatedProgress = (currentTime * 100) / this.player.duration();
            }
            if (eventName === "ended") {
                calculatedProgress = 100;
            }

            if (calculatedProgress >= this.progress) {
                this.progress = calculatedProgress > 100 ? 100 : Math.floor(calculatedProgress);
                return this.$emit("progress", this.progress);
            }
        },
        fixScrollPosition() {
            const scrollContainer = getScrollParent(this.$el);
            if (scrollContainer) {
                const video = this.$el.querySelector(".video-js");
                if (video && video.classList.contains("vjs-fullscreen")) {
                    this.scrollPos = scrollContainer.scrollTop;
                }
                scrollContainer.scrollTop = this.scrollPos;
            }
        },
    },
};
</script>
