import React from 'react';

import isAllowedIframeOrigin from 'lib2/isAllowedIframeOrigin';

export class WidgetIFrame extends React.PureComponent {
    constructor(props) {
        super(props);

        this.POST_MSG_TYPE_PREFIX = '@connect/';

        this.initRef = this.initRef.bind(this);
        this.onMessage = this.onMessage.bind(this);
        this.postMessage = this.postMessage.bind(this);
        this.__updateSize = this.__updateSize.bind(this);
    }

    initFrame() {
        window.addEventListener('message', this.onMessage);
        window.parent.postMessage('ping', '*');
    }

    destructFrame() {
        clearInterval(this.__resizeTracker);
        window.removeEventListener('message', this.onMessage);
    }

    initRef(ref) {
        this.__ref = ref;
    }

    /**
     * @param {MessageEvent} param
     */
    onMessage({ data, origin }) {
        if (!data || !isAllowedIframeOrigin(origin)) {
            return;
        }

        if (typeof data === 'object' && ['pong', 'props'].includes(data.message)) {
            this.setState({
                widgetStyle: data.style,
            });
        }

        if (data === 'pong' || data.message === 'pong') {
            this.__targetOrigin = origin;
            this.__updateSize(true);

            clearInterval(this.__resizeTracker);
            this.__resizeTracker = setInterval(this.__updateSize, 300);
        }
    }

    /**
     * @param {Boolean} force
     */
    __updateSize(force) {
        const { offsetWidth, offsetHeight } = this.__ref;

        if (force || this.__width !== offsetWidth || this.__height !== offsetHeight) {
            this.postMessage('resize', {
                width: offsetWidth,
                height: offsetHeight,
            });

            this.__width = offsetWidth;
            this.__height = offsetHeight;
        }
    }

    /**
     * @param {String} type
     * @param {Object} payload
     */
    postMessage(type, payload) {
        type = `${this.POST_MSG_TYPE_PREFIX}${type}`;

        this.__targetOrigin && window.parent.postMessage({ type, payload }, this.__targetOrigin);
    }
}
