import { verify, createJWKSet } from '@recast-sdk/recast-jwt';

function _class_private_field_loose_base(receiver, privateKey) {
    if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
        throw new TypeError("attempted to use private field on non-instance");
    }
    return receiver;
}

var id = 0;
function _class_private_field_loose_key(name) {
    return "__private_" + id++ + "_" + name;
}

const toWindowFeatures = (features)=>{
    return features ? Object.keys(features).reduce((featuresKeys, name)=>{
        const value = features[name];
        if (typeof value === 'boolean') {
            featuresKeys.push(`${name}=${value ? 'yes' : 'no'}`);
        } else {
            featuresKeys.push(`${name}=${value}`);
        }
        return featuresKeys;
    }, []).join(',') : 'popup=yes';
};

function _extends() {
    _extends = Object.assign || function assign(target) {
        for(var i = 1; i < arguments.length; i++){
            var source = arguments[i];
            for(var key in source)if (Object.prototype.hasOwnProperty.call(source, key)) target[key] = source[key];
        }
        return target;
    };
    return _extends.apply(this, arguments);
}

const getNavigationParams = (params)=>{
    const definedParams = Object.fromEntries(Object.entries(params).filter(([, value])=>value));
    return new URLSearchParams(definedParams).toString();
};
/**
 * Validate the URL parameters and constructs the correct purchase navigation URL for a
 * given type and intent
 * @param rootUrl
 * @param intentToken
 * @param redirectUri
 * @param recastReferrer
 * @returns
 */ const purchaseNavigationUrl = (rootUrl, intentToken, sandbox, redirectUri, recastReferrer)=>{
    if (!rootUrl) {
        throw new Error(`${RecastBrowser.name}: rootUrl is required`);
    }
    if (!intentToken) {
        throw new Error(`${RecastBrowser.name}: intentToken is required`);
    }
    const navigationParams = getNavigationParams(_extends({}, redirectUri ? {
        mode: 'redirect',
        redirect_uri: redirectUri
    } : {
        mode: 'popup',
        origin: window.origin
    }, {
        intent: intentToken,
        recastReferrer: recastReferrer,
        sandbox: sandbox ? 'true' : undefined
    }));
    return `${rootUrl}/redirect?${navigationParams}`;
};
/**
 * Constructs the share and earn navigation URL for a given mode, root URL, parent URL, price, and share percentage.
 * @param mode
 * @param rootUrl
 * @param parentUrl
 * @param price
 * @param sharePercentage
 * @returns
 */ const shareAndEarnNavigationUrl = (mode, rootUrl, parentUrl, price, sharePercentage)=>{
    if (!rootUrl) {
        throw new Error(`${RecastBrowser.name}: rootUrl is required`);
    }
    if (!price) {
        throw new Error(`${RecastBrowser.name}: price is required`);
    }
    if (!sharePercentage) {
        throw new Error(`${RecastBrowser.name}: sharePercentage is required`);
    }
    if (!parentUrl) {
        throw new Error(`${RecastBrowser.name}: parentUrl is required`);
    }
    const params = new URLSearchParams({
        mode,
        price: price.toString(),
        share_pct: sharePercentage.toString(),
        parent_url: parentUrl
    });
    return `${rootUrl}/share-and-earn?${params.toString()}`;
};

const getFeatures = ()=>{
    var _window_screen_availLeft, _ref, _window_screen_availTop, _ref1;
    const screen = {
        height: window.screen.availHeight,
        width: window.screen.availWidth,
        left: (_ref = (_window_screen_availLeft = window.screen.availLeft) != null ? _window_screen_availLeft : window.screen.left) != null ? _ref : 0,
        top: (_ref1 = (_window_screen_availTop = window.screen.availTop) != null ? _window_screen_availTop : window.screen.top) != null ? _ref1 : 0
    };
    const width = 400;
    const height = 678;
    return {
        width,
        height,
        left: screen.width / 2 + screen.left - width / 2,
        top: screen.height / 2 + screen.top - height / 2,
        resizable: false,
        toolbar: false,
        menubar: false,
        location: false,
        scrollbars: false,
        popup: true
    };
};
const isConfigOverride = (config)=>{
    return config.accountUrl !== undefined || config.jwksUrl !== undefined;
};
var _Sandbox = /*#__PURE__*/ _class_private_field_loose_key("_Sandbox"), _Window = /*#__PURE__*/ _class_private_field_loose_key("_Window"), _RootUrl = /*#__PURE__*/ _class_private_field_loose_key("_RootUrl"), _Listeners = /*#__PURE__*/ _class_private_field_loose_key("_Listeners"), _verify = /*#__PURE__*/ _class_private_field_loose_key("_verify"), _recastReferrer = /*#__PURE__*/ _class_private_field_loose_key("_recastReferrer"), /**
   * If the `RecastBrowser` object is configured to open a `pop-up` and redirect
   * the `pop-up` window to Recast for purchase. The `pop-up` window object is
   * returned, otherwise the same window object is returned
   *
   * @param popup is the window a popup
   * @returns `Window` object of the popup or the `Window` or `null`
   */ _getWindow = /*#__PURE__*/ _class_private_field_loose_key("_getWindow"), _isWindowClosed = /*#__PURE__*/ _class_private_field_loose_key("_isWindowClosed"), _handleMessage = /*#__PURE__*/ _class_private_field_loose_key("_handleMessage");
/**
 * `RecastBrowser` handles the framework agnostic window and verification logic
 * for the Recast API, it can be used directly in the browser or with a
 * framework wrapper such as `recast-react`
 */ class RecastBrowser {
    constructor(config = {
        sandbox: false
    }){
        Object.defineProperty(this, _Sandbox, {
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, _Window, {
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, _RootUrl, {
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, _Listeners, {
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, _verify, {
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, _recastReferrer, {
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, _getWindow, {
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, _isWindowClosed, {
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, _handleMessage, {
            writable: true,
            value: void 0
        });
        _class_private_field_loose_base(this, _Listeners)[_Listeners] = new Map();
        _class_private_field_loose_base(this, _recastReferrer)[_recastReferrer] = null;
        _class_private_field_loose_base(this, _getWindow)[_getWindow] = (popup)=>{
            if (popup) {
                _class_private_field_loose_base(this, _Window)[_Window] = window.open('', '', toWindowFeatures(getFeatures()));
                if (_class_private_field_loose_base(this, _Window)[_Window]) {
                    window.addEventListener('message', _class_private_field_loose_base(this, _handleMessage)[_handleMessage]);
                    _class_private_field_loose_base(this, _Window)[_Window].document.title = 'Recast MicroPayments';
                }
            } else {
                _class_private_field_loose_base(this, _Window)[_Window] = window;
            }
            return _class_private_field_loose_base(this, _Window)[_Window];
        };
        /**
   * Verify the token is a valid RecastPay token
   * @param token
   * @returns
   */ this.verify = (token)=>{
            return _class_private_field_loose_base(this, _verify)[_verify](token);
        };
        /**
   * Parse the query string retuned from RecastPay API redirect
   * @param location
   * `Window` location object
   * @returns
   */ this.parsePurchaseQueryString = (location)=>{
            const searchParams = new URLSearchParams(location.search);
            const successParam = searchParams.get('success');
            if (!successParam) {
                return undefined;
            }
            if (successParam === 'true') {
                var _searchParams_get, _searchParams_get1;
                return {
                    success: true,
                    contentAccessToken: (_searchParams_get = searchParams.get('content_access_token')) != null ? _searchParams_get : '',
                    intent: (_searchParams_get1 = searchParams.get('intent')) != null ? _searchParams_get1 : ''
                };
            } else {
                return {
                    success: false
                };
            }
        };
        /**
   * Navigate to the Recast Redirect purchase flow, with the purchase intent token
   *
   * @param intentToken purchase intent
   * @param redirectUri where to return after the purchase is actioned
   */ this.purchaseViaRedirect = (intentToken, redirectUri)=>{
            if (_class_private_field_loose_base(this, _isWindowClosed)[_isWindowClosed]()) {
                _class_private_field_loose_base(this, _Window)[_Window] = _class_private_field_loose_base(this, _getWindow)[_getWindow](false);
            }
            if (_class_private_field_loose_base(this, _Window)[_Window]) {
                _class_private_field_loose_base(this, _Window)[_Window].location.href = purchaseNavigationUrl(_class_private_field_loose_base(this, _RootUrl)[_RootUrl], intentToken, _class_private_field_loose_base(this, _Sandbox)[_Sandbox], redirectUri, _class_private_field_loose_base(this, _recastReferrer)[_recastReferrer] || undefined);
            } else {
                throw new Error(`${RecastBrowser.name}: has no 'Window' object`);
            }
        };
        /**
   * Opens the Share and Earn flow in a new window via redirect.
   * @param parentUrl
   * @param price
   * @param sharePercentage
   */ this.openShareAndEarnFlowViaRedirect = (parentUrl, price, sharePercentage)=>{
            if (_class_private_field_loose_base(this, _isWindowClosed)[_isWindowClosed]()) {
                _class_private_field_loose_base(this, _Window)[_Window] = _class_private_field_loose_base(this, _getWindow)[_getWindow](false);
            }
            if (_class_private_field_loose_base(this, _Window)[_Window]) {
                _class_private_field_loose_base(this, _Window)[_Window].location.href = shareAndEarnNavigationUrl('redirect', _class_private_field_loose_base(this, _RootUrl)[_RootUrl], parentUrl, price, sharePercentage);
            } else {
                throw new Error(`${RecastBrowser.name}: has no 'Window' object`);
            }
        };
        /**
   * Use the RecastPay Pop-up flow to purchase an item.
   * @param intentToken Purchase intent token
   */ this.purchaseViaPopup = (intentToken)=>{
            if (_class_private_field_loose_base(this, _isWindowClosed)[_isWindowClosed]()) {
                _class_private_field_loose_base(this, _Window)[_Window] = _class_private_field_loose_base(this, _getWindow)[_getWindow](true);
            } else {
                this.focus();
            }
            if (_class_private_field_loose_base(this, _Window)[_Window]) {
                _class_private_field_loose_base(this, _Window)[_Window].location.href = purchaseNavigationUrl(_class_private_field_loose_base(this, _RootUrl)[_RootUrl], intentToken, _class_private_field_loose_base(this, _Sandbox)[_Sandbox], undefined, _class_private_field_loose_base(this, _recastReferrer)[_recastReferrer] || undefined);
            } else {
                throw new Error(`${RecastBrowser.name}: has no 'window' object`);
            }
        };
        /**
   * Opens the Share and Earn flow in a pop-up window.
   * @param parentUrl
   * @param price
   * @param sharePercentage
   */ this.openShareAndEarnFlowViaPopup = (parentUrl, price, sharePercentage)=>{
            if (_class_private_field_loose_base(this, _isWindowClosed)[_isWindowClosed]()) {
                _class_private_field_loose_base(this, _Window)[_Window] = _class_private_field_loose_base(this, _getWindow)[_getWindow](true);
            } else {
                this.focus();
            }
            if (_class_private_field_loose_base(this, _Window)[_Window]) {
                _class_private_field_loose_base(this, _Window)[_Window].location.href = shareAndEarnNavigationUrl('popup', _class_private_field_loose_base(this, _RootUrl)[_RootUrl], parentUrl, price, sharePercentage);
            } else {
                throw new Error(`${RecastBrowser.name}: has no 'window' object`);
            }
        };
        /**
   * Focuses the window managed by `RecastBrowser`
   */ this.focus = ()=>{
            var _class_private_field_loose_base__Window;
            if (!_class_private_field_loose_base(this, _Window)[_Window]) {
                throw new Error(`${RecastBrowser.name}: has no pop-up window to focus`);
            }
            (_class_private_field_loose_base__Window = _class_private_field_loose_base(this, _Window)[_Window]) == null ? void 0 : _class_private_field_loose_base__Window.focus();
        };
        /**
   * Closes the window managed by `RecastBrowser` and clears the window
   */ this.close = ()=>{
            var _class_private_field_loose_base__Window;
            if (!_class_private_field_loose_base(this, _Window)[_Window]) {
                throw new Error(`${RecastBrowser.name}: has no pop-up window to close`);
            }
            (_class_private_field_loose_base__Window = _class_private_field_loose_base(this, _Window)[_Window]) == null ? void 0 : _class_private_field_loose_base__Window.close();
            _class_private_field_loose_base(this, _Window)[_Window] = null;
            window.removeEventListener('message', _class_private_field_loose_base(this, _handleMessage)[_handleMessage]);
        };
        _class_private_field_loose_base(this, _isWindowClosed)[_isWindowClosed] = ()=>{
            var _class_private_field_loose_base__Window;
            var _class_private_field_loose_base__Window_closed;
            return (_class_private_field_loose_base__Window_closed = (_class_private_field_loose_base__Window = _class_private_field_loose_base(this, _Window)[_Window]) == null ? void 0 : _class_private_field_loose_base__Window.closed) != null ? _class_private_field_loose_base__Window_closed : true;
        };
        _class_private_field_loose_base(this, _handleMessage)[_handleMessage] = (event)=>{
            if (event.source !== _class_private_field_loose_base(this, _Window)[_Window] || event.origin !== _class_private_field_loose_base(this, _RootUrl)[_RootUrl]) {
                return;
            }
            var _class_private_field_loose_base__Listeners_get;
            const listeners = (_class_private_field_loose_base__Listeners_get = _class_private_field_loose_base(this, _Listeners)[_Listeners].get(event.data.type)) != null ? _class_private_field_loose_base__Listeners_get : [];
            listeners.forEach((callback)=>callback(event.data));
        };
        /**
   * Add an event listener and callback
   * @param type
   * @param callback
   * @returns
   */ this.addListener = (type, callback)=>{
            var _class_private_field_loose_base__Listeners_get;
            const listeners = (_class_private_field_loose_base__Listeners_get = _class_private_field_loose_base(this, _Listeners)[_Listeners].get(type)) != null ? _class_private_field_loose_base__Listeners_get : [];
            listeners.push(callback);
            _class_private_field_loose_base(this, _Listeners)[_Listeners].set(type, listeners);
            return ()=>this.removeListener(type, callback);
        };
        /**
   * Remove and event listener and callback
   * @param type
   * @param callback
   */ this.removeListener = (type, callback)=>{
            var _class_private_field_loose_base__Listeners_get;
            const listeners = (_class_private_field_loose_base__Listeners_get = _class_private_field_loose_base(this, _Listeners)[_Listeners].get(type)) != null ? _class_private_field_loose_base__Listeners_get : [];
            const index = listeners.indexOf(callback);
            if (index !== -1) {
                listeners.splice(index, 1);
            }
        };
        if (!window) {
            throw new Error(`${RecastBrowser.name}: can only be called in the client`);
        }
        _class_private_field_loose_base(this, _Sandbox)[_Sandbox] = config.sandbox;
        let rootUrl = `https://account.${_class_private_field_loose_base(this, _Sandbox)[_Sandbox] ? 'recast-sandbox' : 'recast'}.tv`;
        let jwksUrl = `https://api.${_class_private_field_loose_base(this, _Sandbox)[_Sandbox] ? 'recast-sandbox' : 'recast'}.tv/api/public/purchase/.well-known/jwks.json`;
        if (isConfigOverride(config)) {
            var _config_accountUrl;
            rootUrl = (_config_accountUrl = config == null ? void 0 : config.accountUrl) != null ? _config_accountUrl : rootUrl;
            var _config_jwksUrl;
            jwksUrl = (_config_jwksUrl = config.jwksUrl) != null ? _config_jwksUrl : jwksUrl;
        }
        _class_private_field_loose_base(this, _RootUrl)[_RootUrl] = rootUrl;
        _class_private_field_loose_base(this, _Window)[_Window] = null;
        _class_private_field_loose_base(this, _verify)[_verify] = verify(createJWKSet(jwksUrl));
        _class_private_field_loose_base(this, _recastReferrer)[_recastReferrer] = new URLSearchParams(window.location.search).get('recastReferrer');
    }
}

export { RecastBrowser };
