import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import React, { useState, useRef, useEffect, useCallback, useLayoutEffect } from 'react';
import { Camera, Vector2 } from '@atlaskit/media-ui';
import { ANALYTICS_MEDIA_CHANNEL } from '@atlaskit/media-common';
import { withAnalyticsEvents } from '@atlaskit/analytics-next';
import { BaselineExtend } from '../../styleWrappers';
import { ZoomLevel } from '../../domain/zoomLevel';
import { ZoomControls } from '../../zoomControls';
import { createClosedEvent } from '../../analytics/events/ui/closed';
import MediaSvg from '@atlaskit/media-svg';
import { MediaViewerError } from '../../errors';
import { clientRectangle, naturalSizeRectangle, zoomLevelAfterResize } from './utils';
import { ImageWrapper } from './ImageWrapper';
import { getErrorReason } from './errors';
var SvgViewerBase = function SvgViewerBase(_ref) {
  var identifier = _ref.identifier,
    onLoad = _ref.onLoad,
    onClose = _ref.onClose,
    onBlanketClicked = _ref.onBlanketClicked,
    onError = _ref.onError;
  var _useState = useState(new ZoomLevel(1)),
    _useState2 = _slicedToArray(_useState, 2),
    zoomLevel = _useState2[0],
    setZoomLevel = _useState2[1];
  var _useState3 = useState(false),
    _useState4 = _slicedToArray(_useState3, 2),
    isDragging = _useState4[0],
    setIsDragging = _useState4[1];
  var _useState5 = useState(new Vector2(0, 0)),
    _useState6 = _slicedToArray(_useState5, 2),
    cursorPos = _useState6[0],
    setCursorPos = _useState6[1];
  var _useState7 = useState(),
    _useState8 = _slicedToArray(_useState7, 2),
    camera = _useState8[0],
    setCamera = _useState8[1];
  var wrapperRef = useRef(null);
  var _useState9 = useState(),
    _useState0 = _slicedToArray(_useState9, 2),
    wrapperScroll = _useState0[0],
    setWrapperScroll = _useState0[1];
  var onResize = useCallback(function () {
    if (!wrapperRef.current || !camera) {
      return;
    }
    var newViewport = clientRectangle(wrapperRef.current);
    var newCamera = camera.resizedViewport(newViewport);
    var newZoomLevel = zoomLevelAfterResize(newCamera, camera, zoomLevel);
    setCamera(newCamera);
    setZoomLevel(newZoomLevel);
  }, [camera, zoomLevel]);
  var panImage = useCallback(function (ev) {
    if (isDragging && wrapperRef.current) {
      var newCursorPos = new Vector2(ev.screenX, ev.screenY);
      var delta = cursorPos.sub(newCursorPos);
      setCursorPos(newCursorPos);
      wrapperRef.current.scrollLeft += delta.x;
      wrapperRef.current.scrollTop += delta.y;
    }
  }, [cursorPos, isDragging]);
  var stopDragging = useCallback(function (ev) {
    ev.preventDefault();
    setIsDragging(false);
  }, []);
  useEffect(function () {
    window.addEventListener('resize', onResize);
    document.addEventListener('mousemove', panImage);
    document.addEventListener('mouseup', stopDragging);
    return function () {
      window.removeEventListener('resize', onResize);
      document.removeEventListener('mousemove', panImage);
      document.removeEventListener('mouseup', stopDragging);
    };
  }, [onResize, panImage, stopDragging]);
  var onSvgLoad = function onSvgLoad(ev) {
    onLoad === null || onLoad === void 0 || onLoad();
    if (!wrapperRef.current) {
      return;
    }
    var viewport = clientRectangle(wrapperRef.current);
    var originalImgRect = naturalSizeRectangle(ev.currentTarget);
    var newCamera = new Camera(viewport, originalImgRect);
    var newZoomLevel = new ZoomLevel(newCamera.scaleDownToFit);
    setCamera(newCamera);
    setZoomLevel(newZoomLevel);
  };
  var onSvgError = function onSvgError(err) {
    var error = new MediaViewerError(getErrorReason(err.primaryReason), err.secondaryError);
    onError(error);
  };
  var onSvgClicked = function onSvgClicked(e) {
    if (e.target === e.currentTarget) {
      onBlanketClicked === null || onBlanketClicked === void 0 || onBlanketClicked();
      onClose === null || onClose === void 0 || onClose();
    }
  };
  var startDragging = function startDragging(ev) {
    // stopping propagation to prevent media viewer from closing
    // when clicking on the image
    ev.stopPropagation();
    ev.preventDefault();
    setIsDragging(true);
    setCursorPos(new Vector2(ev.screenX, ev.screenY));
  };
  var onZoomChange = function onZoomChange(nextZoomLevel) {
    var wrapper = wrapperRef.current;
    if (!wrapper || !camera) {
      return;
    }
    var scrollLeft = wrapper.scrollLeft,
      scrollTop = wrapper.scrollTop;
    var prevOffset = new Vector2(scrollLeft, scrollTop);
    var prevZoomLevel = zoomLevel;
    setZoomLevel(nextZoomLevel);
    var _camera$scaledOffset = camera.scaledOffset(prevOffset, prevZoomLevel.value, nextZoomLevel.value),
      x = _camera$scaledOffset.x,
      y = _camera$scaledOffset.y;
    setWrapperScroll({
      scrollLeft: x,
      scrollTop: y
    });
  };
  useLayoutEffect(function () {
    // Must scroll after the new zoom (onZoomChange) and before the repaint
    var wrapper = wrapperRef.current;
    if (!wrapper || !wrapperScroll) {
      return;
    }
    var scrollLeft = wrapperScroll.scrollLeft,
      scrollTop = wrapperScroll.scrollTop;
    wrapper.scrollLeft = scrollLeft;
    wrapper.scrollTop = scrollTop;
  }, [wrapperScroll]);

  // We use style attr instead of SC prop for perf reasons
  // When image loads it does two things at the same time 1) it renders itself in the browser 2) triggers onLoad
  // visibility: 'hidden' is here to prevent image rendering on the screen (with 100%) before next
  // react re-render when we have `camera` and can control it's zoom level.
  // overflow: 'hidden' is here to prevent scroll going wild while image is rendered in visibility: 'hidden'
  // We can't use display: none or not render image, because we do need `onLoad` to trigger and read it's dimensions

  var canDrag = camera && zoomLevel.value > camera.scaleToFit || false;
  var isHidden = !camera;
  var imgStyles = {
    visibility: isHidden ? 'hidden' : 'visible',
    cursor: canDrag && isDragging ? 'grabbing' : canDrag ? 'grab' : 'initial',
    display: 'inline-block',
    verticalAlign: 'middle',
    position: 'relative'
  };
  var imgDimensions = camera === null || camera === void 0 ? void 0 : camera.scaledImg(zoomLevel.value);
  return /*#__PURE__*/React.createElement(ImageWrapper, {
    onClick: onSvgClicked,
    ref: wrapperRef,
    isHidden: isHidden
  }, /*#__PURE__*/React.createElement(MediaSvg, {
    testId: 'media-viewer-svg',
    identifier: identifier,
    dimensions: imgDimensions
    // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
    ,
    style: imgStyles,
    onLoad: onSvgLoad,
    onMouseDown: startDragging,
    onError: onSvgError
  }), /*#__PURE__*/React.createElement(BaselineExtend, null), /*#__PURE__*/React.createElement(ZoomControls, {
    zoomLevel: zoomLevel,
    onChange: onZoomChange
  }));
};
export var SvgViewer = withAnalyticsEvents({
  onBlanketClicked: function onBlanketClicked(createAnalyticsEvent) {
    var event = createAnalyticsEvent(createClosedEvent('blanket'));
    event.fire(ANALYTICS_MEDIA_CHANNEL);
  }
})(SvgViewerBase);