import _extends from "@babel/runtime/helpers/extends";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import React, { useCallback, useEffect, useState, useRef } from 'react';
import Loadable from 'react-loadable';
import { isExternalImageIdentifier, isFileIdentifier, toCommonMediaClientError } from '@atlaskit/media-client';
import { Text } from '@atlaskit/primitives/compiled';
import { FormattedMessage } from 'react-intl-next';
import { messages } from '@atlaskit/media-ui';
import { isCodeViewerItem } from '@atlaskit/media-ui/codeViewer';
import { useFileState, useMediaClient } from '@atlaskit/media-client-react';
import { Outcome } from './domain';
import { Spinner } from './loading';
import ErrorMessage from './errorMessage';
import { MediaViewerError } from './errors';
import { ErrorViewDownloadButton } from './download';
import { withAnalyticsEvents } from '@atlaskit/analytics-next';
import { createCommencedEvent } from './analytics/events/operational/commenced';
import { createLoadSucceededEvent } from './analytics/events/operational/loadSucceeded';
import { fireAnalytics, getFileAttributes } from './analytics';
import { InteractiveImg } from './viewers/image/interactive-img';
import ArchiveViewerLoader from './viewers/archiveSidebar/archiveViewerLoader';
import { startMediaFileUfoExperience, succeedMediaFileUfoExperience } from './analytics/ufoExperiences';
import { CustomViewer } from './viewers/customViewer/customViewer';
import { fg } from '@atlaskit/platform-feature-flags';
var ImageViewer = Loadable({
  loader: function loader() {
    return import( /* webpackChunkName: "@atlaskit-internal_imageViewer" */'./viewers/image').then(function (mod) {
      return mod.ImageViewer;
    });
  },
  loading: function loading() {
    return /*#__PURE__*/React.createElement(Spinner, null);
  }
});
var VideoViewer = Loadable({
  loader: function loader() {
    return import( /* webpackChunkName: "@atlaskit-internal_videoViewer" */'./viewers/video').then(function (mod) {
      return mod.VideoViewer;
    });
  },
  loading: function loading() {
    return /*#__PURE__*/React.createElement(Spinner, null);
  }
});
var AudioViewer = Loadable({
  loader: function loader() {
    return import( /* webpackChunkName: "@atlaskit-internal_audioViewer" */'./viewers/audio').then(function (mod) {
      return mod.AudioViewer;
    });
  },
  loading: function loading() {
    return /*#__PURE__*/React.createElement(Spinner, null);
  }
});
var DocViewer = Loadable({
  loader: function loader() {
    return import( /* webpackChunkName: "@atlaskit-internal_docViewer" */'./viewers/doc').then(function (mod) {
      return mod.DocViewer;
    });
  },
  loading: function loading() {
    return /*#__PURE__*/React.createElement(Spinner, null);
  }
});
var DocNextViewer = Loadable({
  loader: function loader() {
    return import( /* webpackChunkName: "@atlaskit-internal_docNextViewer" */'./viewers/doc-next').then(function (mod) {
      return mod.DocViewer;
    });
  },
  loading: function loading() {
    return /*#__PURE__*/React.createElement(Spinner, null);
  }
});
var CodeViewer = Loadable({
  loader: function loader() {
    return import( /* webpackChunkName: "@atlaskit-internal_codeViewer" */'./viewers/codeViewer').then(function (mod) {
      return mod.CodeViewer;
    });
  },
  loading: function loading() {
    return /*#__PURE__*/React.createElement(Spinner, null);
  }
});
var SvgViewer = Loadable({
  loader: function loader() {
    return (
      // @ts-ignore: [PIT-1685] Fails in post-office due to backwards incompatibility issue with React 18
      import( /* webpackChunkName: "@atlaskit-internal_svgViewer" */'./viewers/svg').then(function (mod) {
        return mod.SvgViewer;
      })
    );
  },
  loading: function loading() {
    return /*#__PURE__*/React.createElement(Spinner, null);
  }
});
// Consts
export var isExternalImageItem = function isExternalImageItem(fileItem) {
  return fileItem === 'external-image';
};
export var isFileStateItem = function isFileStateItem(fileItem) {
  return !isExternalImageItem(fileItem);
};
export var MAX_FILE_SIZE_SUPPORTED_BY_CODEVIEWER = 10 * 1024 * 1024;
export var ItemViewerBase = function ItemViewerBase(_ref) {
  var identifier = _ref.identifier,
    showControls = _ref.showControls,
    onClose = _ref.onClose,
    previewCount = _ref.previewCount,
    contextId = _ref.contextId,
    createAnalyticsEvent = _ref.createAnalyticsEvent,
    viewerOptions = _ref.viewerOptions,
    traceContext = _ref.traceContext;
  // States and Refs
  var _useState = useState(Outcome.pending()),
    _useState2 = _slicedToArray(_useState, 2),
    item = _useState2[0],
    setItem = _useState2[1];
  var fileStateFlagsRef = useRef({
    wasStatusUploading: false,
    wasStatusProcessing: false
  });
  var createAnalyticsEventRef = useRef(createAnalyticsEvent);
  createAnalyticsEventRef.current = createAnalyticsEvent;

  // Hooks
  var mediaClient = useMediaClient();
  var _useFileState = useFileState(isExternalImageIdentifier(identifier) ? '' : identifier.id, {
      collectionName: isExternalImageIdentifier(identifier) ? '' : identifier.collectionName,
      skipRemote: isExternalImageIdentifier(identifier)
    }),
    fileState = _useFileState.fileState;
  var renderDownloadButton = useCallback(function (fileState, error) {
    var collectionName = isFileIdentifier(identifier) ? identifier.collectionName : undefined;
    return /*#__PURE__*/React.createElement(ErrorViewDownloadButton, {
      fileState: fileState,
      mediaClient: mediaClient,
      error: error,
      collectionName: collectionName,
      traceContext: traceContext
    });
  }, [mediaClient, identifier, traceContext]);

  // Did mount

  useEffect(function () {
    if (isExternalImageIdentifier(identifier)) {
      return;
    }
    fireAnalytics(createCommencedEvent(identifier === null || identifier === void 0 ? void 0 : identifier.id, traceContext), createAnalyticsEventRef.current);
    startMediaFileUfoExperience();
  }, [identifier, traceContext]);
  useEffect(function () {
    if (isExternalImageIdentifier(identifier)) {
      // external images do not need to talk to our backend,
      // so therefore no need for media-client subscriptions.
      // just set a successful outcome of type "external-image".
      setItem(Outcome.successful('external-image'));
      return;
    }

    // File Subscription
    if (fileState) {
      var status = fileState.status;
      if (fileState.status !== 'error') {
        // updateFileStateFlag

        if (status === 'processing') {
          fileStateFlagsRef.current.wasStatusProcessing = true;
        } else if (status === 'uploading') {
          fileStateFlagsRef.current.wasStatusUploading = true;
        }
        setItem(Outcome.successful(fileState));
      } else {
        setItem(Outcome.failed(new MediaViewerError('itemviewer-fetch-metadata', toCommonMediaClientError(fileState))));
      }
    }
  }, [fileState, identifier]);
  var onSuccess = useCallback(function () {
    item.whenSuccessful(function (fileItem) {
      if (isFileStateItem(fileItem)) {
        var fileAttributes = getFileAttributes(fileItem);
        fireAnalytics(createLoadSucceededEvent(fileAttributes, traceContext), createAnalyticsEventRef.current);
        succeedMediaFileUfoExperience({
          fileAttributes: fileAttributes,
          fileStateFlags: fileStateFlagsRef.current
        });
      }
    });
  }, [item, traceContext]);
  var onLoadFail = useCallback(function (mediaViewerError) {
    setItem(Outcome.failed(mediaViewerError, fileState));
  }, [fileState]);
  var renderItem = function renderItem(fileItem) {
    var _viewerOptions$custom;
    var collectionName = isFileIdentifier(identifier) ? identifier.collectionName : undefined;
    var viewerProps = {
      mediaClient: mediaClient,
      item: fileItem,
      collectionName: collectionName,
      onClose: onClose,
      previewCount: previewCount,
      viewerOptions: viewerOptions,
      traceContext: traceContext
    };
    var customRenderer = viewerOptions === null || viewerOptions === void 0 || (_viewerOptions$custom = viewerOptions.customRenderers) === null || _viewerOptions$custom === void 0 ? void 0 : _viewerOptions$custom.find(function (renderer) {
      return renderer.shouldUseCustomRenderer({
        fileItem: fileItem
      });
    });
    if (customRenderer) {
      return /*#__PURE__*/React.createElement(CustomViewer, _extends({
        customRendererConfig: customRenderer,
        onError: onLoadFail,
        onSuccess: onSuccess
      }, viewerProps));
    }

    // TODO: fix all of the item errors

    if (isCodeViewerItem(fileItem.name, fileItem.mimeType)) {
      //Render error message if code file has size over 10MB.
      //Required by https://product-fabric.atlassian.net/browse/MEX-1788
      if (fileItem.size > MAX_FILE_SIZE_SUPPORTED_BY_CODEVIEWER) {
        return renderError(new MediaViewerError('codeviewer-file-size-exceeds'), fileItem);
      }
      return /*#__PURE__*/React.createElement(CodeViewer, _extends({
        onSuccess: onSuccess,
        onError: onLoadFail
      }, viewerProps));
    }
    if (isFileIdentifier(identifier) && fileItem.mimeType === 'image/svg+xml') {
      return /*#__PURE__*/React.createElement(SvgViewer, {
        identifier: identifier,
        onLoad: onSuccess,
        onError: onLoadFail,
        onClose: onClose,
        traceContext: traceContext
      });
    }
    var mediaType = fileItem.mediaType;
    switch (mediaType) {
      case 'image':
        return /*#__PURE__*/React.createElement(ImageViewer, _extends({
          onLoad: onSuccess,
          onError: onLoadFail,
          contextId: contextId
        }, viewerProps));
      case 'audio':
        return /*#__PURE__*/React.createElement(AudioViewer, _extends({
          showControls: showControls,
          onCanPlay: onSuccess,
          onError: onLoadFail
        }, viewerProps));
      case 'video':
        return /*#__PURE__*/React.createElement(VideoViewer, _extends({
          identifier: identifier,
          showControls: showControls,
          onCanPlay: onSuccess,
          onError: onLoadFail
        }, viewerProps));
      case 'doc':
        if (fg('media_document_viewer')) {
          return /*#__PURE__*/React.createElement(DocNextViewer, _extends({
            onSuccess: onSuccess,
            onError: onLoadFail
          }, viewerProps));
        }
        return /*#__PURE__*/React.createElement(DocViewer, _extends({
          onSuccess: onSuccess,
          onError: onLoadFail
        }, viewerProps));
      case 'archive':
        return /*#__PURE__*/React.createElement(ArchiveViewerLoader, _extends({
          onSuccess: onSuccess,
          onError: onLoadFail
        }, viewerProps));
    }
    return renderError(new MediaViewerError('unsupported'), fileItem);
  };
  var renderError = useCallback(function (error, fileItem) {
    if (fileItem) {
      var _fileState;
      if (fileItem === 'external-image') {
        // external image error outcome
        _fileState = {
          id: 'external-image',
          status: 'error'
        };
      } else {
        // FileState error outcome
        _fileState = fileItem;
      }
      return /*#__PURE__*/React.createElement(ErrorMessage, {
        fileId: isFileIdentifier(identifier) ? identifier.id : 'undefined',
        error: error,
        fileState: _fileState,
        fileStateFlags: fileStateFlagsRef.current,
        traceContext: traceContext
      }, /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement(FormattedMessage, messages.try_downloading_file)), renderDownloadButton(_fileState, error));
    } else {
      return /*#__PURE__*/React.createElement(ErrorMessage, {
        fileId: isFileIdentifier(identifier) ? identifier.id : 'undefined',
        error: error,
        fileStateFlags: fileStateFlagsRef.current
      });
    }
  }, [identifier, renderDownloadButton, traceContext]);
  return item.match({
    successful: function successful(fileItem) {
      if (fileItem === 'external-image') {
        // render an external image
        var _ref2 = identifier,
          dataURI = _ref2.dataURI,
          name = _ref2.name;
        return /*#__PURE__*/React.createElement(InteractiveImg, {
          src: dataURI,
          alt: name !== null && name !== void 0 ? name : '',
          onLoad: function onLoad() {
            fireAnalytics(createLoadSucceededEvent({
              fileId: 'external-image'
            }), createAnalyticsEventRef.current);
            succeedMediaFileUfoExperience({
              fileAttributes: {
                fileId: 'external-image'
              },
              fileStateFlags: fileStateFlagsRef.current
            });
          },
          onError: function onError() {
            setItem(Outcome.failed(new MediaViewerError('imageviewer-external-onerror')));
          }
        });
      } else {
        // render a FileState fetched through media-client
        switch (fileItem.status) {
          case 'processed':
          case 'uploading':
          case 'processing':
            return renderItem(fileItem);
          case 'failed-processing':
            if (fileItem.mediaType === 'doc' && fileItem.mimeType === 'application/pdf') {
              return renderItem(fileItem);
            }
            return renderError(new MediaViewerError('itemviewer-file-failed-processing-status'), fileItem);
          case 'error':
            return renderError(new MediaViewerError('itemviewer-file-error-status', toCommonMediaClientError(fileItem)), fileItem);
        }
      }
    },
    pending: function pending() {
      return /*#__PURE__*/React.createElement(Spinner, null);
    },
    failed: function failed(error) {
      return renderError(error, item.data);
    }
  });
};
var ViewerWithKey = function ViewerWithKey(props) {
  var identifier = props.identifier;
  var key = isFileIdentifier(identifier) ? identifier.id : identifier.dataURI;
  return /*#__PURE__*/React.createElement(ItemViewerBase, _extends({}, props, {
    key: key
  }));
};
export var ItemViewer = withAnalyticsEvents()(ViewerWithKey);