(function () {
    'use strict';

    var workerReady = false;
    var activeRenderToken = 0;

    function loadScript(src) {
        return new Promise(function (resolve, reject) {
            if (document.querySelector('script[data-karvi-pdfjs="1"]')) {
                if (window.pdfjsLib) {
                    resolve(window.pdfjsLib);
                    return;
                }
            }

            var existing = document.querySelector('script[src="' + src + '"]');
            if (existing) {
                existing.addEventListener('load', function () {
                    resolve(window.pdfjsLib);
                });
                existing.addEventListener('error', reject);
                return;
            }

            var script = document.createElement('script');
            script.src = src;
            script.async = true;
            script.dataset.karviPdfjs = '1';
            script.onload = function () {
                resolve(window.pdfjsLib);
            };
            script.onerror = reject;
            document.head.appendChild(script);
        });
    }

    function ensurePdfJs() {
        var pdfJs = (window.karviAsset || function (p) { return '/assets/' + p; })('vendor/pdfjs/pdf.min.js');
        var workerJs = (window.karviAsset || function (p) { return '/assets/' + p; })('vendor/pdfjs/pdf.worker.min.js');
        return loadScript(pdfJs).then(function (lib) {
            if (!workerReady && lib) {
                lib.GlobalWorkerOptions.workerSrc = workerJs;
                workerReady = true;
            }
            return lib;
        });
    }

    function clearHost(host) {
        if (!host) {
            return;
        }
        while (host.firstChild) {
            host.removeChild(host.firstChild);
        }
    }

    function renderPdf(url, host) {
        var renderToken = ++activeRenderToken;
        clearHost(host);

        return ensurePdfJs().then(function (pdfjsLib) {
            return pdfjsLib.getDocument({ url: url, withCredentials: true }).promise;
        }).then(function (pdf) {
            if (renderToken !== activeRenderToken) {
                return;
            }

            var chain = Promise.resolve();
            for (var pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
                (function (num) {
                    chain = chain.then(function () {
                        if (renderToken !== activeRenderToken) {
                            return;
                        }

                        return pdf.getPage(num).then(function (page) {
                            var baseViewport = page.getViewport({ scale: 1 });
                            var containerWidth = Math.max(host.clientWidth || window.innerWidth, 320) - 24;
                            var scale = Math.min(2.5, containerWidth / baseViewport.width);
                            var viewport = page.getViewport({ scale: scale });
                            var canvas = document.createElement('canvas');
                            canvas.className = 'reg-pdf-page-canvas';
                            canvas.width = Math.floor(viewport.width);
                            canvas.height = Math.floor(viewport.height);
                            host.appendChild(canvas);
                            return page.render({
                                canvasContext: canvas.getContext('2d'),
                                viewport: viewport,
                            }).promise;
                        });
                    });
                })(pageNum);
            }

            return chain;
        });
    }

    window.KarviPdfViewer = {
        renderInto: renderPdf,
        ensureReady: ensurePdfJs,
        cancel: function () {
            activeRenderToken++;
        },
    };
})();
