/** @jsx jsx */
import { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
import { jsx } from '@emotion/react';
import ReactDOM from 'react-dom';
import { createIntl, injectIntl } from 'react-intl-next';
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
import { fireFailedMediaInlineEvent, fireSucceededMediaInlineEvent, MediaCardError } from '@atlaskit/media-card';
import { FileFetcherError } from '@atlaskit/media-client';
import { MediaClientContext } from '@atlaskit/media-client-react';
import { MediaViewer } from '@atlaskit/media-viewer';
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
import { messages } from '../messages/media-inline-card';
import { referenceHeights } from './constants';
import { InlineImageCard } from './inline-image-card';
import { InlineImageWrapper } from './inline-image-wrapper';
import { InlineImageCardErrorView } from './views/error-view';
import { InlineImageCardLoadingView } from './views/loading-view';
export const MediaInlineImageCardInternal = ({
  mediaClient,
  identifier,
  isSelected,
  intl,
  alt,
  isLazy,
  width,
  height,
  border,
  ssr,
  serializeDataAttrs,
  shouldOpenMediaViewer
}) => {
  const [fileState, setFileState] = useState();
  const [subscribeError, setSubscribeError] = useState();
  const [isFailedEventSent, setIsFailedEventSent] = useState(false);
  const [isSucceededEventSent, setIsSucceededEventSent] = useState(false);
  const [isMediaViewerVisible, setMediaViewerVisible] = useState(false);
  const {
    formatMessage
  } = intl || createIntl({
    locale: 'en'
  });
  const {
    createAnalyticsEvent
  } = useAnalyticsEvents();
  const fireFailedOperationalEvent = (error = new MediaCardError('missing-error-data'), failReason) => {
    if (!isFailedEventSent && fileState) {
      setIsFailedEventSent(true);
      fireFailedMediaInlineEvent(fileState, error, failReason, createAnalyticsEvent);
    }
  };
  const fireSucceededOperationalEvent = () => {
    if (!isSucceededEventSent && fileState) {
      setIsSucceededEventSent(true);
      fireSucceededMediaInlineEvent(fileState, createAnalyticsEvent);
    }
  };
  useEffect(() => {
    if (mediaClient) {
      const subscription = mediaClient.file.getFileState(identifier.id, {
        collectionName: identifier.collectionName
      }).subscribe({
        next: fileState => {
          setFileState(fileState);
          setSubscribeError(undefined);
        },
        error: e => {
          setSubscribeError(e);
        }
      });
      return () => {
        subscription.unsubscribe();
      };
    }
  }, [identifier, mediaClient]);
  const content = dimensions => {
    if (!mediaClient) {
      return jsx(InlineImageCardLoadingView, null);
    }
    if (!ssr) {
      if (subscribeError) {
        const isUploading = (fileState === null || fileState === void 0 ? void 0 : fileState.status) === 'uploading';
        const errorMessage = isUploading ? messages.failedToUpload : messages.unableToLoadContent;
        const errorReason = (fileState === null || fileState === void 0 ? void 0 : fileState.status) === 'uploading' ? 'upload' : 'metadata-fetch';
        fireFailedOperationalEvent(new MediaCardError(errorReason, subscribeError));
        return jsx(InlineImageCardErrorView, {
          message: formatMessage(errorMessage)
        });
      }
      if (!fileState || (fileState === null || fileState === void 0 ? void 0 : fileState.status) === 'uploading') {
        return jsx(InlineImageCardLoadingView, null);
      }
      if (fileState.status === 'error') {
        fireFailedOperationalEvent(new MediaCardError('error-file-state', new Error(fileState.message)));
        return jsx(InlineImageCardErrorView, {
          message: formatMessage(messages.unableToLoadContent)
        });
      } else if (fileState.status === 'failed-processing') {
        fireFailedOperationalEvent(undefined, 'failed-processing');
        return jsx(InlineImageCardErrorView, {
          message: formatMessage(messages.unableToLoadContent)
        });
      } else if (!fileState.name) {
        fireFailedOperationalEvent(new MediaCardError('metadata-fetch', new FileFetcherError('emptyFileName', fileState.id)));
        return jsx(InlineImageCardErrorView, {
          message: formatMessage(messages.unableToLoadContent)
        });
      }
      if (fileState.status === 'processed') {
        fireSucceededOperationalEvent();
      }
    }
    return jsx(MediaClientContext.Provider, {
      value: mediaClient
    }, jsx(InlineImageCard, {
      dimensions: dimensions,
      identifier: identifier,
      renderError: () => jsx(InlineImageCardErrorView, {
        message: formatMessage(messages.unableToLoadContent)
      }),
      alt: alt,
      ssr: ssr === null || ssr === void 0 ? void 0 : ssr.mode,
      isLazy: isLazy,
      crop: true,
      stretch: false
    }));
  };
  const aspectRatio = useMemo(() => width && height ? width / height : undefined, [width, height]);

  /**
   * scaledDimensions is used to define the correct media size fetched from media service
   * inline images will only ever be rendered at a maximum height of H1 and so scaled dimensions
   * will only ever return a width and height where the height has a maximum height of H1
   */
  const scaledDimension = useMemo(() => {
    if (!width || !height || !aspectRatio) {
      return {
        width,
        height
      };
    }
    return {
      width: Math.round(aspectRatio * referenceHeights['h1']),
      height: referenceHeights['h1']
    };
  }, [width, height, aspectRatio]);
  const htmlAttributes = useMemo(() => {
    if (serializeDataAttrs) {
      const resolvedAttrs = fileState && fileState.status !== 'error' ? {
        'data-file-size': fileState.size,
        'data-file-mime-type': fileState.mimeType,
        'data-file-name': fileState.name
      } : {};
      return {
        'data-type': 'image',
        'data-node-type': 'mediaInline',
        'data-id': identifier.id,
        'data-collection': identifier.collectionName,
        'data-width': width,
        'data-height': height,
        'data-alt': alt,
        ...resolvedAttrs
      };
    }
    return {};
  }, [alt, fileState, height, identifier, width, serializeDataAttrs]);
  const onMediaInlineImageClick = useCallback(() => {
    if (shouldOpenMediaViewer && getBooleanFF('platform.editor.media.inline-image.renderer-preview-support_3w1ju')) {
      setMediaViewerVisible(true);
    }
  }, [shouldOpenMediaViewer]);
  const onMediaInlinePreviewClose = useCallback(() => {
    setMediaViewerVisible(false);
  }, []);
  const mediaViewer = useMemo(() => {
    if (isMediaViewerVisible && mediaClient !== null && mediaClient !== void 0 && mediaClient.mediaClientConfig) {
      return /*#__PURE__*/ReactDOM.createPortal(jsx(MediaViewer, {
        collectionName: identifier.collectionName || '',
        items: [identifier],
        mediaClientConfig: mediaClient === null || mediaClient === void 0 ? void 0 : mediaClient.mediaClientConfig,
        selectedItem: identifier,
        onClose: onMediaInlinePreviewClose
      }), document.body);
    }
    return null;
  }, [identifier, isMediaViewerVisible, mediaClient === null || mediaClient === void 0 ? void 0 : mediaClient.mediaClientConfig, onMediaInlinePreviewClose]);
  return jsx(Fragment, null, jsx(InlineImageWrapper, {
    isSelected: isSelected,
    isInteractive: getBooleanFF('platform.editor.media.inline-image.renderer-preview-support_3w1ju') && shouldOpenMediaViewer,
    aspectRatio: aspectRatio,
    borderColor: border === null || border === void 0 ? void 0 : border.borderColor,
    borderSize: border === null || border === void 0 ? void 0 : border.borderSize,
    htmlAttrs: htmlAttributes,
    onClick: onMediaInlineImageClick
  }, content(scaledDimension)), mediaViewer);
};
export const MediaInlineImageCard = injectIntl(MediaInlineImageCardInternal, {
  enforceContext: false
});