import React from 'react';
import { isErrorFileState, request } from '@atlaskit/media-client';
import { Outcome } from '../../domain';
import { MediaViewerError } from '../../errors';
import { Spinner } from '../../loading';
import { BaseViewer } from '../base-viewer';
import { DEFAULT_LANGUAGE, normaliseLineBreaks } from './util';
import { getLanguageType, getExtension } from '@atlaskit/media-ui/codeViewer';
import { msgToText } from './msg-parser';
import { CodeRendererAdvanced } from './CodeRendererAdvanced/CodeRendererAdvanced';
import { fg } from '@atlaskit/platform-feature-flags';
const moduleLoader = () => import( /* webpackChunkName: "@atlaskit-internal_media-code-viewer" */'./codeViewerRenderer');
const componentLoader = () => moduleLoader().then(module => module.CodeViewRenderer);
export class CodeViewer extends BaseViewer {
  get initialState() {
    return {
      content: Outcome.pending()
    };
  }
  async init() {
    if (!CodeViewer.CodeViewerComponent) {
      await this.loadCodeViewer();
    }
    const {
      item,
      mediaClient,
      collectionName,
      onError
    } = this.props;
    if (item.status === 'processed' || item.status === 'processing') {
      try {
        const downloadUrl = await mediaClient.file.getFileBinaryURL(item.id, collectionName);
        const response = await request(downloadUrl, {
          method: 'GET',
          endpoint: '/file/{fileId}/binary'
        });
        const ext = getExtension(item.name);

        // Pass through EmailViewer logic
        if (ext === 'msg') {
          const arrayBuffer = await response.arrayBuffer();
          const src = msgToText(arrayBuffer);
          // email contents parsed successfully
          if (typeof src === 'string') {
            this.onMediaDisplayed();
            this.setState({
              content: Outcome.successful(normaliseLineBreaks(src))
            });
          } else {
            throw new MediaViewerError('codeviewer-parse-email');
          }
        } else {
          const src = await response.text();
          this.onMediaDisplayed();
          this.setState({
            content: Outcome.successful(normaliseLineBreaks(src))
          });
        }
      } catch (error) {
        const codeViewerError = new MediaViewerError('codeviewer-fetch-src', error instanceof Error ? error : undefined);
        this.setState({
          content: Outcome.failed(codeViewerError)
        });
        if (onError) {
          onError(codeViewerError);
        }
      }
    }
  }
  async loadCodeViewer() {
    CodeViewer.CodeViewerComponent = await componentLoader();
    this.forceUpdate();
  }
  getCodeLanguage(item) {
    if (!isErrorFileState(item)) {
      return getLanguageType(item.name, item.mimeType);
    }
    return DEFAULT_LANGUAGE;
  }
  release() {}
  renderSuccessful(content) {
    const {
      item,
      onClose,
      onSuccess,
      onError
    } = this.props;
    const {
      CodeViewerComponent
    } = CodeViewer;
    if (!CodeViewerComponent) {
      return /*#__PURE__*/React.createElement(Spinner, null);
    }
    if (fg('media_advanced_text_viewer')) {
      return /*#__PURE__*/React.createElement(CodeRendererAdvanced, {
        item: item,
        src: content,
        onSuccess: onSuccess,
        onError: onError,
        onClose: onClose
      });
    }
    return /*#__PURE__*/React.createElement(CodeViewerComponent, {
      item: item,
      src: content,
      language: this.getCodeLanguage(this.props.item) || DEFAULT_LANGUAGE,
      onSuccess: onSuccess,
      onError: onError,
      onClose: onClose
    });
  }
}