(function () {
    "use strict";

    function shellFor(video) {
        return video.closest(
            ".h4bs-video-player-shell, [data-h4bs-module='video'], [data-h4bs-background-video]"
        );
    }

    function showImageFallback(video) {
        var shell = shellFor(video);
        var fallback = shell ? shell.querySelector("[data-h4bs-video-fallback]") : null;
        video.setAttribute("data-h4bs-video-failed", "1");
        video.hidden = true;
        if (fallback) {
            fallback.hidden = false;
        }
    }

    function attemptPlayback(video) {
        if (!video.autoplay || typeof video.play !== "function") {
            return;
        }
        var playResult = video.play();
        if (playResult && typeof playResult.catch === "function") {
            playResult.catch(function () {
                // Browser autoplay policy may require a user gesture.
            });
        }
    }

    function useFallbackVideo(video) {
        var fallbackVideo =
            video.getAttribute("data-h4bs-fallback-video") ||
            video.getAttribute("data-h4bs-mp4") ||
            "";
        if (!fallbackVideo || video.getAttribute("data-h4bs-fallback-active") === "1") {
            showImageFallback(video);
            return;
        }
        video.setAttribute("data-h4bs-fallback-active", "1");
        video.removeAttribute("data-h4bs-video-failed");
        video.hidden = false;
        video.src = fallbackVideo;
        video.load();
        attemptPlayback(video);
    }

    function initialize(video) {
        if (!video || video.getAttribute("data-h4bs-video-ready") === "1") {
            return;
        }
        video.setAttribute("data-h4bs-video-ready", "1");
        var hlsSource = video.getAttribute("data-h4bs-hls") || "";
        var primaryVideo = video.getAttribute("data-h4bs-primary-video") || "";
        var networkRecoveryAttempts = 0;
        var mediaRecoveryAttempts = 0;

        video.addEventListener("error", function () {
            if (video.getAttribute("data-h4bs-fallback-active") === "1") {
                showImageFallback(video);
                return;
            }
            useFallbackVideo(video);
        });

        if (!hlsSource) {
            if (primaryVideo && !video.currentSrc) {
                video.src = primaryVideo;
                video.load();
            }
            attemptPlayback(video);
            return;
        }

        if (video.canPlayType("application/vnd.apple.mpegurl")) {
            video.src = hlsSource;
            video.load();
            attemptPlayback(video);
            return;
        }
        if (!window.Hls || !window.Hls.isSupported()) {
            useFallbackVideo(video);
            return;
        }

        var hls = new window.Hls({
            enableWorker: true,
            lowLatencyMode: true,
            backBufferLength: 90,
        });
        video.h4bsHls = hls;
        hls.loadSource(hlsSource);
        hls.attachMedia(video);
        hls.on(window.Hls.Events.MANIFEST_PARSED, function () {
            attemptPlayback(video);
        });
        hls.on(window.Hls.Events.ERROR, function (event, data) {
            if (!data || !data.fatal) {
                return;
            }
            if (
                data.type === window.Hls.ErrorTypes.NETWORK_ERROR &&
                networkRecoveryAttempts < 2
            ) {
                networkRecoveryAttempts += 1;
                window.setTimeout(function () {
                    hls.startLoad();
                }, networkRecoveryAttempts * 500);
                return;
            }
            if (
                data.type === window.Hls.ErrorTypes.MEDIA_ERROR &&
                mediaRecoveryAttempts < 1
            ) {
                mediaRecoveryAttempts += 1;
                hls.recoverMediaError();
                return;
            }
            hls.destroy();
            video.h4bsHls = null;
            useFallbackVideo(video);
        });
    }

    function boot(root) {
        var scope = root && typeof root.querySelectorAll === "function" ? root : document;
        scope
            .querySelectorAll(
                "video[data-h4bs-video-player], video[data-h4bs-lms-video]"
            )
            .forEach(initialize);
    }

    if (document.readyState === "loading") {
        document.addEventListener("DOMContentLoaded", function () {
            boot(document);
        });
    } else {
        boot(document);
    }

    if (typeof window.MutationObserver === "function" && document.documentElement) {
        var observer = new window.MutationObserver(function (mutations) {
            mutations.forEach(function (mutation) {
                mutation.addedNodes.forEach(function (node) {
                    if (!node || node.nodeType !== 1) {
                        return;
                    }
                    if (
                        node.matches &&
                        node.matches(
                            "video[data-h4bs-video-player], video[data-h4bs-lms-video]"
                        )
                    ) {
                        initialize(node);
                    }
                    boot(node);
                });
            });
        });
        observer.observe(document.documentElement, { childList: true, subtree: true });
    }

    window.h4bsInitVideoPlayers = boot;
    window.h4bsInitLmsVideo = boot;
}());
