import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import React, { useEffect, useRef, useState } from 'react';
import { PDFViewer, EventBus, PDFLinkService, NullL10n } from 'pdfjs-dist/legacy/web/pdf_viewer';
import { getDocument, GlobalWorkerOptions, CMapCompressionType, PasswordResponses } from 'pdfjs-dist/legacy/build/pdf';
import { withAnalyticsEvents } from '@atlaskit/analytics-next';
import { cmap } from './cmaps';
import { ZoomControls } from '../../zoomControls';
import { PDFWrapper } from '../../styleWrappers';
import { closeOnDirectClick } from '../../utils/closeOnDirectClick';
import { Outcome } from '../../domain';
import { Spinner } from '../../loading';
import ErrorMessage from '../../errorMessage';
import { ZoomLevel } from '../../domain/zoomLevel';
import { processError } from './processError';
import { pdfJs } from './pdfJs';
import { extractCompressedBase64 } from './extractCompressedBase64';
import { PDFPasswordInput } from './pdfPasswordInput';
import { fireAnalytics } from '../../analytics';
import { createPdfPasswordInputScreenEvent } from '../../analytics/events/screen/pdfPasswordInput';
import { createPasswordPdfScreenEvent } from '../../analytics/events/screen/passwordPdf';
import { PDFRendererWrapper } from './pdfRendererWrapper';
export var pdfViewerClassName = 'pdfViewer';
var CmapFactory = /*#__PURE__*/function () {
  function CmapFactory() {
    _classCallCheck(this, CmapFactory);
  }
  return _createClass(CmapFactory, [{
    key: "fetch",
    value: function () {
      var _fetch = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
        var name, module, data;
        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) switch (_context.prev = _context.next) {
            case 0:
              name = _ref.name;
              _context.next = 3;
              return cmap[name]();
            case 3:
              module = _context.sent;
              _context.next = 6;
              return extractCompressedBase64(module.default);
            case 6:
              data = _context.sent;
              return _context.abrupt("return", {
                cMapData: data,
                compressionType: CMapCompressionType.BINARY
              });
            case 8:
            case "end":
              return _context.stop();
          }
        }, _callee);
      }));
      function fetch(_x) {
        return _fetch.apply(this, arguments);
      }
      return fetch;
    }()
  }]);
}();
var defaultWorkerUrl = '';
var PDFRendererBase = function PDFRendererBase(_ref2) {
  var src = _ref2.src,
    onClose = _ref2.onClose,
    onSuccess = _ref2.onSuccess,
    onError = _ref2.onError,
    workerUrl = _ref2.workerUrl,
    item = _ref2.item,
    createAnalyticsEvent = _ref2.createAnalyticsEvent;
  var _useState = useState(new ZoomLevel(1)),
    _useState2 = _slicedToArray(_useState, 2),
    zoomLevel = _useState2[0],
    setZoomLevel = _useState2[1];
  var _useState3 = useState(Outcome.pending()),
    _useState4 = _slicedToArray(_useState3, 2),
    docOutcome = _useState4[0],
    setDocOutcome = _useState4[1];
  var isPasswordPdfRef = useRef(false);
  var _useState5 = useState(false),
    _useState6 = _slicedToArray(_useState5, 2),
    passwordProtected = _useState6[0],
    setPasswordProtected = _useState6[1];
  var _useState7 = useState(false),
    _useState8 = _slicedToArray(_useState7, 2),
    hasPasswordError = _useState8[0],
    setHasPasswordError = _useState8[1];
  var pdfWrapperRef = useRef();
  var docRef = useRef();
  var pdfViewerRef = useRef();
  var onSuccessRef = useRef(onSuccess);
  onSuccessRef.current = onSuccess;
  var updatePasswordRef = useRef(undefined);
  var onErrorRef = useRef(onError);
  onErrorRef.current = onError;
  var existingGlobalWorkerRef = useRef(undefined);
  useEffect(function () {
    /**
     * CXP-4622: Fixes issue of PDF.js reusing the global worker registered by embeded PDF macro in confluence
     * The global worker will likely be a different version and thus throw an error.
     * This will remove the worker on mount and will re-register it on unmount
     */
    var _ref3 = window,
      pdfjsWorker = _ref3.pdfjsWorker;
    if (pdfjsWorker) {
      existingGlobalWorkerRef.current = pdfjsWorker;
      window.pdfjsWorker = undefined;
    }
    var isSubscribed = true;
    var fetchDoc = /*#__PURE__*/function () {
      var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
        var blob, getDocumentTask, pdfError;
        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
          while (1) switch (_context2.prev = _context2.next) {
            case 0:
              _context2.prev = 0;
              if (!(!workerUrl && !defaultWorkerUrl)) {
                _context2.next = 6;
                break;
              }
              _context2.next = 4;
              return extractCompressedBase64(pdfJs, 'blob');
            case 4:
              blob = _context2.sent;
              defaultWorkerUrl = URL.createObjectURL(blob);
            case 6:
              GlobalWorkerOptions.workerSrc = workerUrl !== null && workerUrl !== void 0 ? workerUrl : defaultWorkerUrl;
              getDocumentTask = getDocument({
                url: src,
                CMapReaderFactory: CmapFactory,
                isEvalSupported: false
              });
              getDocumentTask.onPassword = function (updatePassword, e) {
                updatePasswordRef.current = updatePassword;
                if (e === PasswordResponses.NEED_PASSWORD) {
                  isPasswordPdfRef.current = true;
                  setPasswordProtected(true);
                } else {
                  setHasPasswordError(true);
                }
              };
              _context2.next = 11;
              return getDocumentTask.promise;
            case 11:
              docRef.current = _context2.sent;
              isSubscribed && setDocOutcome(Outcome.successful(docRef.current));
              _context2.next = 20;
              break;
            case 15:
              _context2.prev = 15;
              _context2.t0 = _context2["catch"](0);
              pdfError = processError(_context2.t0);
              isSubscribed && setDocOutcome(Outcome.failed(pdfError));
              if (onErrorRef.current) {
                onErrorRef.current(pdfError);
              }
            case 20:
            case "end":
              return _context2.stop();
          }
        }, _callee2, null, [[0, 15]]);
      }));
      return function fetchDoc() {
        return _ref4.apply(this, arguments);
      };
    }();
    fetchDoc();
    return function () {
      isSubscribed = false;
      if (docRef.current) {
        docRef.current.destroy();
      }
      window.pdfjsWorker = existingGlobalWorkerRef.current;
    };
  }, [src, workerUrl]);
  useEffect(function () {
    if (docOutcome.status !== 'SUCCESSFUL' || !pdfWrapperRef.current) {
      return;
    }
    var eventBus = new EventBus();
    var pdfLinkService = new PDFLinkService({
      eventBus: eventBus
    });
    pdfViewerRef.current = new PDFViewer({
      container: pdfWrapperRef.current,
      eventBus: eventBus,
      linkService: pdfLinkService,
      l10n: NullL10n
    });
    pdfLinkService.setViewer(pdfViewerRef.current);
    pdfViewerRef.current.setDocument(docRef.current);
    pdfLinkService.setDocument(docRef.current, null);
    pdfViewerRef.current.firstPagePromise.then(scaleToFit);
    if (isPasswordPdfRef.current) {
      fireAnalytics(createPasswordPdfScreenEvent(), createAnalyticsEvent);
    }
    if (onSuccessRef.current) {
      onSuccessRef.current();
    }
  }, [createAnalyticsEvent, docOutcome.status]);
  var savePdfElement = function savePdfElement(el) {
    pdfWrapperRef.current = el;
  };
  var handleZoom = function handleZoom(zoomLevel) {
    pdfViewerRef.current.currentScale = zoomLevel.value;
    setZoomLevel(zoomLevel);
  };
  var scaleToFit = function scaleToFit() {
    if (pdfViewerRef.current) {
      pdfViewerRef.current.currentScaleValue = 'page-width';
      setZoomLevel(new ZoomLevel(pdfViewerRef.current.currentScale));
    }
  };
  return docOutcome.match({
    pending: function pending() {
      return passwordProtected ? /*#__PURE__*/React.createElement(PDFPasswordInput, {
        onRender: function onRender() {
          return fireAnalytics(createPdfPasswordInputScreenEvent(), createAnalyticsEvent);
        },
        onSubmit: function onSubmit(data) {
          var _updatePasswordRef$cu;
          // Reset hasPasswordError on each submission
          hasPasswordError && setHasPasswordError(false);
          (_updatePasswordRef$cu = updatePasswordRef.current) === null || _updatePasswordRef$cu === void 0 || _updatePasswordRef$cu.call(updatePasswordRef, data.password);
        },
        hasPasswordError: hasPasswordError
      }) : /*#__PURE__*/React.createElement(Spinner, null);
    },
    successful: function successful() {
      return /*#__PURE__*/React.createElement(PDFRendererWrapper, null, /*#__PURE__*/React.createElement(PDFWrapper, {
        "data-testid": "media-viewer-pdf-content",
        ref: savePdfElement
      },
      /*#__PURE__*/
      // eslint-disable-next-line @atlaskit/design-system/prefer-primitives, @atlassian/a11y/click-events-have-key-events, @atlassian/a11y/interactive-element-not-keyboard-focusable, @atlassian/a11y/no-static-element-interactions
      React.createElement("div", {
        // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
        className: pdfViewerClassName,
        onClick: closeOnDirectClick(onClose)
      }), /*#__PURE__*/React.createElement(ZoomControls, {
        zoomLevel: zoomLevel,
        onChange: handleZoom
      })));
    },
    failed: function failed(error) {
      return /*#__PURE__*/React.createElement(ErrorMessage, {
        fileId: item.id,
        fileState: item,
        error: error,
        supressAnalytics: true // item-viewer.tsx will send
      });
    }
  });
};
export var PDFRenderer = withAnalyticsEvents()(PDFRendererBase);