"use strict";
/* eslint-disable @typescript-eslint/ban-types */
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.withFramePay = withFramePay;
exports.withFramePayCardComponent = withFramePayCardComponent;
exports.withFramePayBankComponent = withFramePayBankComponent;
exports.withFramePayIBANComponent = withFramePayIBANComponent;
exports.withFramePayApplePayComponent = withFramePayApplePayComponent;
exports.withFramePaySamsungPayComponent = withFramePaySamsungPayComponent;
exports.withFramePayGooglePayComponent = withFramePayGooglePayComponent;
exports.withFramePayPaypalComponent = withFramePayPaypalComponent;
var React = __importStar(require("react"));
var context_1 = require("../context");
var applepay_element_1 = __importDefault(require("./elements/applepay-element"));
var samsungpay_element_1 = __importDefault(require("./elements/samsungpay-element"));
var bank_element_1 = __importDefault(require("./elements/bank-element"));
var card_element_1 = __importDefault(require("./elements/card-element"));
var googlepay_element_1 = __importDefault(require("./elements/googlepay-element"));
var iban_element_1 = __importDefault(require("./elements/iban-element"));
var paypal_element_1 = __importDefault(require("./elements/paypal-element"));
// Create the main framepay prop for all the components.
// We take the normal framepay object and add error and ready on top of it.
// Todo: Refactor this to use a different approach where we do not decorate the framepay object.
var makeFramepayProps = function (data) {
    var _a;
    var apiTarget = (_a = data.api) !== null && _a !== void 0 ? _a : {}; // Use an empty object if framepay is null or undefined
    var apiProxy = new Proxy(apiTarget, {
        get: function (target, prop) {
            // If it's a property of the FramePay object...
            if (prop in target) {
                var key_1 = prop;
                // If it's a function, return a wrapper that calls the original function
                // otherwise private properties will break for proxies, see:
                // https://stackoverflow.com/a/75153646
                if (typeof target[key_1] === 'function') {
                    return function () {
                        var params = [];
                        for (var _i = 0; _i < arguments.length; _i++) {
                            params[_i] = arguments[_i];
                        }
                        return target[key_1].apply(target, params);
                    };
                }
                // Otherwise, it is not a function but a property, return it as is
                return target[key_1];
            }
            // If it's one of the additional properties, return it from data
            if (prop === 'error')
                return data.error;
            if (prop === 'ready')
                return data.ready;
            // Default behavior: return undefined for unknown properties
            return undefined;
        },
    });
    // Return the proxy which includes both the API properties and augmented properties
    return apiProxy;
};
function Hoc(name, WrappedComponent, provider) {
    var _a;
    return _a = /** @class */ (function (_super) {
            __extends(class_1, _super);
            function class_1() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            class_1.prototype.render = function () {
                var _this = this;
                return (React.createElement(context_1.ContextConsumer, null, function (data) {
                    var provided = provider(data);
                    return (React.createElement(WrappedComponent, __assign({}, _this.props, provided)));
                }));
            };
            return class_1;
        }(React.Component)),
        _a.displayName = "withFramePay".concat(name, "(").concat(WrappedComponent.displayName || WrappedComponent.name || 'Component', ")"),
        _a;
}
var elementsFabric = function (type) {
    if (type === 'iban') {
        /**
         * IBAN
         */
        /**
         * IBAN number element
         */
        var IBANElement = Hoc('IBANElement', iban_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
                elementType: 'iban',
            });
        });
        return {
            IBANElement: IBANElement,
        };
    }
    if (type === 'bankAccount') {
        /**
         * BankAccount
         * @see https://www.rebilly.com/docs/dev-docs/framepay-global-reference/#framepay.bban.mount
         */
        /**
         * Bank AccountType Element
         */
        var BankAccountTypeElement = Hoc('BankAccountTypeElement', bank_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
                elementType: 'bankAccountType',
            });
        });
        /**
         * BankRoutingNumber Element
         */
        var BankRoutingNumberElement = Hoc('BankRoutingNumberElement', bank_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
                elementType: 'bankRoutingNumber',
            });
        });
        /**
         * Bank AccountNumber Element
         */
        var BankAccountNumberElement = Hoc('BankAccountNumberElement', bank_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
                elementType: 'bankAccountNumber',
            });
        });
        return {
            BankAccountNumberElement: BankAccountNumberElement,
            BankAccountTypeElement: BankAccountTypeElement,
            BankRoutingNumberElement: BankRoutingNumberElement,
        };
    }
    if (type === 'card') {
        /**
         * Default Card Element
         * @see https://www.rebilly.com/docs/dev-docs/framepay-global-reference/#framepay.card.mount
         */
        var CardElement = Hoc('CardElement', card_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
            });
        });
        /**
         * Card CVV Element
         */
        var CardCvvElement = Hoc('CardCvvElement', card_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
                elementType: 'cardCvv',
            });
        });
        /**
         * Card Expiry Element
         */
        var CardExpiryElement = Hoc('CardExpiryElement', card_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
                elementType: 'cardExpiration',
            });
        });
        /**
         * Card Number Element
         */
        var CardNumberElement = Hoc('CardNumberElement', card_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
                elementType: 'cardNumber',
            });
        });
        return {
            CardCvvElement: CardCvvElement,
            CardElement: CardElement,
            CardExpiryElement: CardExpiryElement,
            CardNumberElement: CardNumberElement,
        };
    }
    if (type === 'applePay') {
        /**
         * Apple Pay
         */
        var ApplePayElement = Hoc('ApplePayElement', applepay_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
            });
        });
        return {
            ApplePayElement: ApplePayElement,
        };
    }
    if (type === 'samsungPay') {
        /**
         * Samsung Pay
         */
        var SamsungPayElement = Hoc('SamsungPayElement', samsungpay_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
            });
        });
        return {
            SamsungPayElement: SamsungPayElement,
        };
    }
    if (type === 'googlePay') {
        /**
         * Google Pay
         */
        var GooglePayElement = Hoc('GooglePayElement', googlepay_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
            });
        });
        return {
            GooglePayElement: GooglePayElement,
        };
    }
    if (type === 'paypal') {
        /**
         * Paypal
         */
        var PaypalElement = Hoc('PaypalElement', paypal_element_1.default, function (data) {
            return ({
                Framepay: makeFramepayProps(data),
            });
        });
        return {
            PaypalElement: PaypalElement,
        };
    }
    /**
     * Throw the error by default.
     */
    throw new Error("Invalid PaymentMethod type, see PaymentMethodTypes declaration");
};
function withFramePay(WrappedComponent) {
    var _a;
    var elements = __assign(__assign(__assign(__assign(__assign(__assign(__assign({}, elementsFabric('card')), elementsFabric('bankAccount')), elementsFabric('iban')), elementsFabric('applePay')), elementsFabric('samsungPay')), elementsFabric('googlePay')), elementsFabric('paypal'));
    return _a = /** @class */ (function (_super) {
            __extends(class_2, _super);
            function class_2() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            class_2.prototype.render = function () {
                var _this = this;
                return (React.createElement(context_1.ContextConsumer, null, function (data) {
                    return (React.createElement(WrappedComponent, __assign({}, _this.props, elements, { Framepay: makeFramepayProps(data) })));
                }));
            };
            return class_2;
        }(React.Component)),
        _a.displayName = "withFramePay(".concat(WrappedComponent.displayName || WrappedComponent.name || 'Component', ")"),
        _a;
}
function withFramePayCardComponent(WrappedComponent) {
    var _a;
    var elements = elementsFabric('card');
    return _a = /** @class */ (function (_super) {
            __extends(class_3, _super);
            function class_3() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            class_3.prototype.render = function () {
                var _this = this;
                return (React.createElement(context_1.ContextConsumer, null, function (data) {
                    return (React.createElement(WrappedComponent, __assign({}, _this.props, elements, { Framepay: makeFramepayProps(data) })));
                }));
            };
            return class_3;
        }(React.Component)),
        _a.displayName = "withFramePayCardComponent(".concat(WrappedComponent.displayName || WrappedComponent.name || 'Component', ")"),
        _a;
}
function withFramePayBankComponent(WrappedComponent) {
    var _a;
    var elements = elementsFabric('bankAccount');
    return _a = /** @class */ (function (_super) {
            __extends(class_4, _super);
            function class_4() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            class_4.prototype.render = function () {
                var _this = this;
                return (React.createElement(context_1.ContextConsumer, null, function (data) {
                    return (React.createElement(WrappedComponent, __assign({}, _this.props, elements, { Framepay: makeFramepayProps(data) })));
                }));
            };
            return class_4;
        }(React.Component)),
        _a.displayName = "withFramePayBankComponent(".concat(WrappedComponent.displayName || WrappedComponent.name || 'Component', ")"),
        _a;
}
function withFramePayIBANComponent(WrappedComponent) {
    var _a;
    var elements = elementsFabric('iban');
    return _a = /** @class */ (function (_super) {
            __extends(class_5, _super);
            function class_5() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            class_5.prototype.render = function () {
                var _this = this;
                return (React.createElement(context_1.ContextConsumer, null, function (data) {
                    return (React.createElement(WrappedComponent, __assign({}, _this.props, elements, { Framepay: makeFramepayProps(data) })));
                }));
            };
            return class_5;
        }(React.Component)),
        _a.displayName = "withFramePayIBANComponent(".concat(WrappedComponent.displayName || WrappedComponent.name || 'Component', ")"),
        _a;
}
function withFramePayApplePayComponent(WrappedComponent) {
    var _a;
    var elements = elementsFabric('applePay');
    return _a = /** @class */ (function (_super) {
            __extends(class_6, _super);
            function class_6() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            class_6.prototype.render = function () {
                var _this = this;
                return (React.createElement(context_1.ContextConsumer, null, function (data) {
                    return (React.createElement(WrappedComponent, __assign({}, _this.props, elements, { Framepay: makeFramepayProps(data) })));
                }));
            };
            return class_6;
        }(React.Component)),
        _a.displayName = "withFramePayApplePayComponent(".concat(WrappedComponent.displayName || WrappedComponent.name || 'Component', ")"),
        _a;
}
function withFramePaySamsungPayComponent(WrappedComponent) {
    var _a;
    var elements = elementsFabric('samsungPay');
    return _a = /** @class */ (function (_super) {
            __extends(class_7, _super);
            function class_7() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            class_7.prototype.render = function () {
                var _this = this;
                return (React.createElement(context_1.ContextConsumer, null, function (data) {
                    return (React.createElement(WrappedComponent, __assign({}, _this.props, elements, { Framepay: makeFramepayProps(data) })));
                }));
            };
            return class_7;
        }(React.Component)),
        _a.displayName = "withFramePaySamsungPayComponent(".concat(WrappedComponent.displayName || WrappedComponent.name || 'Component', ")"),
        _a;
}
function withFramePayGooglePayComponent(WrappedComponent) {
    var _a;
    var elements = elementsFabric('googlePay');
    return _a = /** @class */ (function (_super) {
            __extends(class_8, _super);
            function class_8() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            class_8.prototype.render = function () {
                var _this = this;
                return (React.createElement(context_1.ContextConsumer, null, function (data) {
                    return (React.createElement(WrappedComponent, __assign({}, _this.props, elements, { Framepay: makeFramepayProps(data) })));
                }));
            };
            return class_8;
        }(React.Component)),
        _a.displayName = "withFramePayGooglePayComponent(".concat(WrappedComponent.displayName || WrappedComponent.name || 'Component', ")"),
        _a;
}
function withFramePayPaypalComponent(WrappedComponent) {
    var _a;
    var elements = elementsFabric('paypal');
    return _a = /** @class */ (function (_super) {
            __extends(class_9, _super);
            function class_9() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            class_9.prototype.render = function () {
                var _this = this;
                return (React.createElement(context_1.ContextConsumer, null, function (data) {
                    return (React.createElement(WrappedComponent, __assign({}, _this.props, elements, { Framepay: makeFramepayProps(data) })));
                }));
            };
            return class_9;
        }(React.Component)),
        _a.displayName = "withFramePayPaypalComponent(".concat(WrappedComponent.displayName || WrappedComponent.name || 'Component', ")"),
        _a;
}
//# sourceMappingURL=data:application/json;base64, 