import _slicedToArray from "@babel/runtime-corejs3/helpers/slicedToArray";
import _Object$assign from "@babel/runtime-corejs3/core-js-stable/object/assign";
import _findIndexInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find-index";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { useChildFrame } from "./useFrame";
import { obfuscateField, updateHeight as _updateHeight, updateTemplates as _updateTemplates, timeout as timeoutAction } from "./frame.actions";
import { jsx as ___EmotionJSX } from "@emotion/react";

/**
 * Component creating a frame and establishing a connection with it.
 * Once the connection has been established, `onConnected` will be called and will provide, as first parameter, a function to send actions to the frame.
 * This component must be provided
 * - a `dispatch `function that will listen for actions coming from the frame
 * - the URL of the decentralized renderer to use as the `source` prop
 */
export var FrameConnector = function FrameConnector(_ref) {
  var dispatch = _ref.dispatch,
      source = _ref.source,
      onConnected = _ref.onConnected,
      style = _ref.style,
      _ref$className = _ref.className,
      className = _ref$className === void 0 ? "" : _ref$className,
      _ref$sandbox = _ref.sandbox,
      sandbox = _ref$sandbox === void 0 ? "allow-scripts allow-same-origin allow-modals allow-popups" : _ref$sandbox;

  var _useState = useState(false),
      _useState2 = _slicedToArray(_useState, 2),
      onConnectedCalled = _useState2[0],
      setOnConnectedCalled = _useState2[1]; // ensure on connected is called once only


  var iframe = useRef(null); // this is used to store internally the latest templates shared in order to automatically transform
  // the selected template tab from the label to th index in the event we communicate with a legacy renderer
  // - templates is used to store the latest templates received and we use a ref in order to avoid triggering effect change when templates. Triggering the effect would mean that the consumer would be called again with the `onConnected` callback, which could be weird
  // - dispatchProxy is used to listen for action and react accordingly (update templates)

  var templates = useRef([]);
  var dispatchProxy = useMemo(function () {
    return function (action) {
      if (action.type === "UPDATE_TEMPLATES") {
        templates.current = action.payload;
      }

      return dispatch(action);
    };
  }, [dispatch]); // map automatically legacy method to the dispatch object so that the consumer doesn't need to provide this
  // that way we handle automatically legacy renderer

  var methods = useMemo(function () {
    return {
      updateHeight: function updateHeight(height) {
        return dispatchProxy(_updateHeight(height));
      },
      updateTemplates: function updateTemplates(templates) {
        return dispatchProxy(_updateTemplates(templates));
      },
      handleObfuscation: function handleObfuscation(field) {
        return dispatchProxy(obfuscateField(field));
      }
    };
  }, [dispatchProxy]);

  var _useChildFrame = useChildFrame({
    methods: methods,
    dispatch: dispatchProxy,
    iframe: iframe
  }),
      _useChildFrame2 = _slicedToArray(_useChildFrame, 3),
      connected = _useChildFrame2[0],
      timeout = _useChildFrame2[1],
      toFrame = _useChildFrame2[2];

  useEffect(function () {
    if (connected && !onConnectedCalled) {
      setOnConnectedCalled(true);
      onConnected(_Object$assign(function (action) {
        // if toFrame.dispatch is set that means we are on the main track with modern renderer
        // there is nothing to do but to call dispatch with the action provided.
        if (toFrame.dispatch) {
          toFrame.dispatch(action);
        } else {
          // otherwise if toFrame.dispatch is NOT set that means that we are dealing with a legacy renderer
          // in that event we will map each action to it's legacy renderer function
          // - "RENDER_DOCUMENT" must call toFrame.renderDocument
          // - "SELECT_TEMPLATE" must call toFrame.selectTemplateTab
          // - "PRINT" must call toFrame.print
          if (action.type === "RENDER_DOCUMENT" && toFrame.renderDocument) {
            toFrame.renderDocument(action.payload.document, action.payload.rawDocument);
          } else if (action.type === "SELECT_TEMPLATE" && toFrame.selectTemplateTab) {
            var _context;

            var index = _findIndexInstanceProperty(_context = templates.current).call(_context, function (template) {
              return template.id === action.payload;
            });

            if (index === -1) console.error("Unable to find the index associated with the label ".concat(action.payload));
            toFrame.selectTemplateTab(index);
          } else if (action.type === "PRINT" && toFrame.print) {
            toFrame.print();
          }
        }
      }));
    }
  }, [connected, toFrame, onConnected, onConnectedCalled]);
  useEffect(function () {
    if (timeout) {
      dispatch(timeoutAction());
    }
  }, [timeout, dispatch]);
  return ___EmotionJSX(React.Fragment, null, timeout ? ___EmotionJSX(React.Fragment, null, ___EmotionJSX("h3", null, "Connection timeout on renderer"), ___EmotionJSX("p", null, "Please contact the administrator of ", source, ".")) : ___EmotionJSX("iframe", {
    title: "Decentralised Rendered Certificate",
    id: "iframe",
    ref: iframe,
    src: source,
    style: style,
    className: className,
    sandbox: sandbox
  }));
};
//# sourceMappingURL=FrameConnector.js.map