/* global pdfjsLib animateSpinner dropdownSelector pdfjsLibUtils PerfectScrollbar */
/* eslint-disable no-param-reassign, no-use-before-define */

var PdfPreview = (function() {
  const MIN_ZOOM = 0.25;
  const MAX_ZOOM = 3;
  const DEFAULT_ZOOM = 1;
  const ZOOM_STEP = 0.25;
  const MAX_LOAD_ATTEMPTS = 5;

  var pageRendering = false;

  function initActionButtons() {
    $(document)
      // Next page
      .on('click', '.pdf-viewer .next-page', function() {
        var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
        renderPdfPage($canvas[0], $canvas.data('current-page') + 1);
      })
      // Previous field
      .on('click', '.pdf-viewer .prev-page', function() {
        var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
        renderPdfPage($canvas[0], $canvas.data('current-page') - 1);
      })
      // Page change field
      .on('change', '.pdf-viewer .current-page', function() {
        var page = parseInt($(this).val(), 10) || 1;
        var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
        var totalPage = $canvas.data('total-page');
        if (page < 1) page = 1;
        if (page > totalPage) page = totalPage;
        renderPdfPage($canvas[0], page);
      })
      // Zoom out button
      .on('click', '.pdf-viewer .zoom-out', function() {
        var zoomSelector = $(this).closest('.pdf-viewer').find('.zoom-page-selector');
        var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
        if (zoomSelector.val() === 'auto') {
          dropdownSelector.selectValues(zoomSelector, DEFAULT_ZOOM);
        } else {
          dropdownSelector.selectValues(zoomSelector, parseFloat(zoomSelector.val()) - ZOOM_STEP);
        }
        renderPdfPage($canvas[0], $canvas.data('current-page'));
      })
      // Zoom in button
      .on('click', '.pdf-viewer .zoom-in', function() {
        var zoomSelector = $(this).closest('.pdf-viewer').find('.zoom-page-selector');
        var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
        if (zoomSelector.val() === 'auto') {
          dropdownSelector.selectValues(zoomSelector, DEFAULT_ZOOM);
        } else {
          dropdownSelector.selectValues(zoomSelector, parseFloat(zoomSelector.val()) + ZOOM_STEP);
        }
        renderPdfPage($canvas[0], $canvas.data('current-page'));
      })
      // Zoom dropdown
      .on('change', '.pdf-viewer .zoom-page-selector', function() {
        var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
        renderPdfPage($canvas[0], $canvas.data('current-page'));
      })
      // Load big pdf
      .on('click', '.pdf-viewer .load-blocked-pdf', function() {
        var $viewer = $(this).closest('.pdf-viewer');
        $viewer.removeClass('blocked');
        $viewer.find('.pdf-canvas').addClass('ready');
        PdfPreview.initCanvas();
      });
  }

  function initZoomDropdown($canvas) {
    var zoomSelector = $canvas.closest('.pdf-viewer').find('.zoom-page-selector');
    dropdownSelector.init(zoomSelector, {
      noEmptyOption: true,
      singleSelect: true,
      closeOnSelect: true,
      selectAppearance: 'simple',
      disableSearch: true
    });
  }

  function refreshPageCounter(canvas) {
    var $canvas = $(canvas);
    var currentPage = $canvas.data('current-page');
    var totalPage = $canvas.data('total-page');
    var counterContainer = $canvas.closest('.pdf-viewer').find('.page-counter');
    counterContainer.find('.current-page').val(currentPage);
    counterContainer.find('.total-page').text(totalPage);
    $canvas.closest('.pdf-viewer').find('.prev-page')
      .attr('disabled', currentPage === 1);
    $canvas.closest('.pdf-viewer').find('.next-page')
      .attr('disabled', currentPage === totalPage);
  }

  function refreshZoomButtons(canvas) {
    var $viewer = $(canvas).closest('.pdf-viewer');
    var zoomSelector = $viewer.find('.zoom-page-selector');
    $viewer.find('.zoom-out').attr('disabled', parseFloat(zoomSelector.val()) === MIN_ZOOM);
    $viewer.find('.zoom-in').attr('disabled', parseFloat(zoomSelector.val()) === MAX_ZOOM);
  }

  function renderPdfPreview(canvas) {
    $(canvas).removeClass('ready');
    initZoomDropdown($(canvas));
    animateSpinner($(canvas).closest('.pdf-viewer'), true);
    $(canvas).data(
      'custom-scrollbar',
      new PerfectScrollbar($(canvas).closest('.page-container')[0])
    ).data('load-attempts', 0);
    pdfjsLib.GlobalWorkerOptions.workerSrc = canvas.dataset.pdfWorkerUrl;
    loadPdfDocument(canvas);
  }


  function loadPdfDocument(canvas, page = 1) {
    var loadingPdf = pdfjsLib.getDocument(canvas.dataset.pdfUrl);
    $(canvas).data('load-attempts', $(canvas).data('load-attempts') + 1);
    loadingPdf.promise
      .then(function(pdfDocument) {
        $(canvas).data('pdfDocument', pdfDocument);
        return renderPdfPage(canvas, page);
      })
      .catch(function(reason) {
        pageRendering = false;
        if (reason.status === 202) {
          setTimeout(function() {
            loadPdfDocument(canvas, page);
          }, 5000);
        }
      });
  }

  function renderPdfPage(canvas, page = 1) {
    var pdfDocument = $(canvas).data('pdfDocument');
    if (pageRendering) return false;
    pageRendering = true;
    pdfDocument.getPage(page).then(function(pdfPage) {
      var ctx;
      var renderTask;
      var userScale = $(canvas).closest('.pdf-viewer').find('.zoom-page-selector').val();
      var $layersContainer = $(canvas).closest('.pdf-viewer').find('.layers-container');
      var scale = userScale === 'auto' ? DEFAULT_ZOOM : userScale;
      var viewport = pdfPage.getViewport({ scale: scale });
      var previewContainer = $(canvas).closest('.page-container')[0];
      var $textLayer = $(canvas).closest('.pdf-viewer').find('.textLayer');
      if (previewContainer.clientHeight < viewport.height && userScale === 'auto') {
        scale = previewContainer.clientHeight / viewport.height;
      }
      viewport = pdfPage.getViewport({ scale: scale });
      canvas.width = viewport.width;
      canvas.height = viewport.height;
      ctx = canvas.getContext('2d');
      renderTask = pdfPage.render({
        canvasContext: ctx,
        viewport: viewport
      });

      // Text layer draw
      $layersContainer.css({
        height: viewport.height + 'px',
        width: viewport.width + 'px'
      });

      pdfPage.getTextContent().then(function(textContent) {
        var textLayer = new pdfjsLibUtils.TextLayerBuilder({
          textLayerDiv: $textLayer[0],
          pageIndex: page - 1,
          viewport: viewport
        });
        textLayer.eventBus = new pdfjsLibUtils.EventBus();
        textLayer.setTextContent(textContent);
        textLayer.render();
      });

      $(canvas)
        .data('current-page', page)
        .data('total-page', pdfDocument.numPages);
      $(canvas).data('custom-scrollbar').update();
      animateSpinner($(canvas).closest('.pdf-viewer'), false);
      refreshPageCounter(canvas);
      refreshZoomButtons(canvas);
      pageRendering = false;
      return renderTask.promise;
    }).catch(function() {
      pageRendering = false;
      if ($(canvas).data('load-attempts') <= MAX_LOAD_ATTEMPTS) {
        setTimeout(function() {
          loadPdfDocument(canvas, page);
        }, 5000);
      }
    });

    return true;
  }

  return {
    initCanvas: function() {
      $.each($('.pdf-canvas.ready'), function(i, canvas) {
        renderPdfPreview(canvas);
      });
    },
    init: function() {
      initActionButtons();
    }
  };
}());

PdfPreview.init();
