import _defineProperty from "@babel/runtime/helpers/defineProperty";
/* eslint-disable @atlaskit/design-system/ensure-design-token-usage */
import React from 'react';
import { unzip, HTTPRangeReader } from 'unzipit';
import { FormattedMessage } from 'react-intl-next';
import { CustomMediaPlayer, messages } from '@atlaskit/media-ui';
import { getLanguageType, isCodeViewerItem } from '@atlaskit/media-ui/codeViewer';
import { Text } from '@atlaskit/primitives/compiled';
import { Outcome } from '../../domain';
import { CustomVideoPlayerWrapper, AudioPlayer, CustomAudioPlayerWrapper, DefaultCoverWrapper, ListWrapper } from '../../styleWrappers';
import AudioIcon from '@atlaskit/icon/core/migration/audio--media-services-audio';
import ErrorMessage from '../../errorMessage';
import { BaseViewer } from '../base-viewer';
import { InteractiveImg } from '../image/interactive-img';
import { PDFRenderer } from '../doc/pdfRenderer';
import { ArchiveItemViewerWrapper, ArchiveLayout, ArchiveViewerWrapper } from './styleWrappers';
import ArchiveSidebarRenderer from './archive-sidebar-renderer';
import { getMediaTypeFromFilename, getMimeTypeFromFilename, rejectAfter } from '../../utils';
import { Spinner } from '../../loading';
import { ENCRYPTED_ENTRY_ERROR_MESSAGE } from './consts';
import { withAnalyticsEvents } from '@atlaskit/analytics-next';
import { fireAnalytics } from '../../analytics';
import { ArchiveViewerError, isMediaViewerError } from '../../errors';
import { createZipEntryLoadSucceededEvent } from '../../analytics/events/operational/zipEntryLoadSucceeded';
import { createZipEntryLoadFailedEvent } from '../../analytics/events/operational/zipEntryLoadFailed';
import { CodeViewRenderer } from '../codeViewer/codeViewerRenderer';
import { DEFAULT_LANGUAGE } from '../codeViewer/util';
import { MAX_FILE_SIZE_SUPPORTED_BY_CODEVIEWER } from '../../item-viewer';
export const getArchiveEntriesFromFileState = async (fileState, mediaClient, collectionName) => {
  const url = await mediaClient.file.getFileBinaryURL(fileState.id, collectionName);
  const reader = new HTTPRangeReader(url);
  const archive = await rejectAfter(() => unzip(reader));
  return archive;
};
export class ArchiveViewerBase extends BaseViewer {
  constructor(...args) {
    super(...args);
    _defineProperty(this, "onError", (error, entry) => {
      this.props.onError(error);
      this.setState({
        content: Outcome.successful({
          ...this.state.content.data,
          selectedArchiveEntry: entry,
          error
        })
      });
    });
    _defineProperty(this, "onSelectedArchiveEntryChange", async selectedArchiveEntry => {
      this.setState({
        content: Outcome.successful({
          ...this.state.content.data,
          selectedArchiveEntry: undefined,
          hasLoadedEntries: false // displays a nice loading spinner for the content viewer
        })
      });
      let src = '';
      let codeViewerSrc = '';
      const isCodeMimeType = isCodeViewerItem(selectedArchiveEntry.name, getMimeTypeFromFilename(selectedArchiveEntry.name));
      if (!selectedArchiveEntry.isDirectory) {
        try {
          const blob = await rejectAfter(() => selectedArchiveEntry.blob(), 10000);
          src = URL.createObjectURL(blob);
          if (isCodeMimeType) {
            codeViewerSrc = await rejectAfter(() => blob.text());
          }
        } catch (error) {
          return this.onError(new ArchiveViewerError(error.message === ENCRYPTED_ENTRY_ERROR_MESSAGE ? 'archiveviewer-encrypted-entry' : 'archiveviewer-create-url', error), selectedArchiveEntry);
        }
      }
      this.setState({
        content: Outcome.successful({
          ...this.state.content.data,
          selectedArchiveEntry,
          src,
          name: selectedArchiveEntry.name,
          isDirectory: selectedArchiveEntry.isDirectory,
          error: undefined,
          codeViewerSrc,
          isCodeMimeType,
          hasLoadedEntries: true
        })
      });
    });
    _defineProperty(this, "onHeaderClicked", () => {
      // This will set the preview to show the Folder icon
      this.setState({
        content: Outcome.successful({
          ...this.state.content.data
        })
      });
    });
    _defineProperty(this, "onViewerLoad", selectedArchiveEntry => () => {
      fireAnalytics(createZipEntryLoadSucceededEvent(this.props.item, selectedArchiveEntry), this.props.createAnalyticsEvent);
    });
    _defineProperty(this, "onViewerError", (primaryErrorReason, selectedArchiveEntry) => error => error && isMediaViewerError(error) ? this.onError(new ArchiveViewerError(primaryErrorReason, error.secondaryError, selectedArchiveEntry)) : this.onError(new ArchiveViewerError(primaryErrorReason, error, selectedArchiveEntry)));
    _defineProperty(this, "onSidebarLoaded", () => {
      this.setState({
        content: Outcome.successful({
          ...this.state.content.data,
          hasLoadedEntries: true
        })
      });
      this.props.onSuccess();
    });
  }
  async init() {
    this.setState(this.initialState);
  }
  get initialState() {
    return {
      content: Outcome.successful({
        src: '',
        name: '',
        isDirectory: true
      })
    };
  }
  release() {
    const {
      content
    } = this.state;
    if (!content.data || !content.data.src) {
      return;
    }
    URL.revokeObjectURL(content.data.src);
  }
  renderSuccessful(content) {
    const {
      item,
      mediaClient,
      collectionName
    } = this.props;
    const {
      selectedArchiveEntry,
      hasLoadedEntries
    } = content;
    const hasSelectedArchiveEntry = selectedArchiveEntry !== undefined;
    return /*#__PURE__*/React.createElement(ArchiveLayout, null, /*#__PURE__*/React.createElement(ArchiveSidebarRenderer, {
      selectedFileState: item,
      mediaClient: mediaClient,
      onSelectedArchiveEntryChange: this.onSelectedArchiveEntryChange,
      onHeaderClicked: this.onHeaderClicked,
      isArchiveEntryLoading: !hasSelectedArchiveEntry,
      collectionName: collectionName,
      onError: this.onError,
      onSuccess: this.onSidebarLoaded
    }), /*#__PURE__*/React.createElement(ArchiveViewerWrapper, null, !hasSelectedArchiveEntry && !hasLoadedEntries ? /*#__PURE__*/React.createElement(ListWrapper, null, /*#__PURE__*/React.createElement(Spinner, null)) : this.renderArchiveItemViewer(content)));
  }
  renderArchiveItemViewer(content) {
    const {
      item,
      viewerOptions
    } = this.props;
    const {
      src,
      name,
      isDirectory,
      error,
      selectedArchiveEntry,
      codeViewerSrc,
      isCodeMimeType
    } = content;
    if (error) {
      return this.renderPreviewError(error, selectedArchiveEntry);
    }
    if (!isDirectory && selectedArchiveEntry) {
      var _viewerOptions$custom;
      if (!name || !src) {
        return this.renderPreviewError(new ArchiveViewerError('archiveviewer-missing-name-src'), selectedArchiveEntry);
      }
      const customRenderer = viewerOptions === null || viewerOptions === void 0 ? void 0 : (_viewerOptions$custom = viewerOptions.customRenderers) === null || _viewerOptions$custom === void 0 ? void 0 : _viewerOptions$custom.find(renderer => renderer.shouldUseCustomRenderer({
        fileItem: item,
        archiveFileItem: {
          name
        }
      }));
      if (customRenderer) {
        return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null, customRenderer.renderContent({
          fileItem: item,
          archiveFileItem: {
            name
          },
          getBinaryContent: async () => (await fetch(src)).blob(),
          onLoad: this.onViewerLoad(selectedArchiveEntry),
          onError: this.onViewerError('archiveviewer-customrenderer-onerror', selectedArchiveEntry)
        }));
      }
      const mediaType = getMediaTypeFromFilename(name);
      if (isCodeMimeType) {
        // Same code viewer logic as in Item-Viewer.tsx
        // Render error message if code file has size over 10MB.
        // Required by https://product-fabric.atlassian.net/browse/MEX-1788
        if ((selectedArchiveEntry === null || selectedArchiveEntry === void 0 ? void 0 : selectedArchiveEntry.size) > MAX_FILE_SIZE_SUPPORTED_BY_CODEVIEWER) {
          return this.renderPreviewError(new ArchiveViewerError('archiveviewer-codeviewer-file-size-exceeds'), selectedArchiveEntry);
        }
        return /*#__PURE__*/React.createElement(CodeViewRenderer, {
          onSuccess: this.onViewerLoad(selectedArchiveEntry),
          onError: this.onViewerError('archiveviewer-codeviewer-onerror', selectedArchiveEntry),
          item: item,
          src: codeViewerSrc || '',
          language: getLanguageType(name) || DEFAULT_LANGUAGE
        });
      }
      switch (mediaType) {
        case 'image':
          return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null, /*#__PURE__*/React.createElement(InteractiveImg, {
            src: src,
            alt: name,
            onLoad: this.onViewerLoad(selectedArchiveEntry),
            onError: this.onViewerError('archiveviewer-imageviewer-onerror', selectedArchiveEntry)
          }));
        case 'video':
          return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null, /*#__PURE__*/React.createElement(CustomVideoPlayerWrapper, {
            "data-testid": "media-viewer-video-content"
          }, /*#__PURE__*/React.createElement(CustomMediaPlayer, {
            type: "video",
            isAutoPlay: false,
            src: src,
            onCanPlay: this.onViewerLoad(selectedArchiveEntry),
            onError: this.onViewerError('archiveviewer-videoviewer-onerror', selectedArchiveEntry)
          })));
        case 'audio':
          return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null, /*#__PURE__*/React.createElement(AudioPlayer, {
            "data-testid": "media-viewer-audio-content"
          }, /*#__PURE__*/React.createElement(DefaultCoverWrapper, null, /*#__PURE__*/React.createElement(AudioIcon, {
            label: "cover",
            LEGACY_size: "xlarge",
            color: "currentColor"
            // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
            ,
            LEGACY_primaryColor: "#22272B"
            // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
            ,
            LEGACY_secondaryColor: "#9FADBC"
          })), /*#__PURE__*/React.createElement(CustomAudioPlayerWrapper, null, /*#__PURE__*/React.createElement(CustomMediaPlayer, {
            type: "audio",
            isAutoPlay: false,
            src: src,
            onCanPlay: this.onViewerLoad(selectedArchiveEntry),
            onError: this.onViewerError('archiveviewer-audioviewer-onerror', selectedArchiveEntry)
          }))));
        case 'doc':
          return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null, /*#__PURE__*/React.createElement(PDFRenderer, {
            item: item,
            src: src,
            onSuccess: this.onViewerLoad(selectedArchiveEntry),
            onError: this.onViewerError('archiveviewer-docviewer-onerror', selectedArchiveEntry)
          }));
        case 'archive':
          //BMPT-388 - Add illustration here, currently empty viewer
          return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null);
        default:
          return this.renderPreviewError(new ArchiveViewerError('archiveviewer-unsupported'), selectedArchiveEntry);
      }
    }
  }
  renderPreviewError(error, entry) {
    const {
      item,
      createAnalyticsEvent
    } = this.props;
    fireAnalytics(createZipEntryLoadFailedEvent(item, error, entry), createAnalyticsEvent);
    return /*#__PURE__*/React.createElement(ListWrapper, null, /*#__PURE__*/React.createElement(ErrorMessage, {
      fileId: item.id,
      fileState: item,
      error: error,
      supressAnalytics: true
    }, /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement(FormattedMessage, messages.try_downloading_file))));
  }
}
export const ArchiveViewer = withAnalyticsEvents()(ArchiveViewerBase);