/**
 * Webkul Software.
 *
 * @category  Webkul
 * @package   Webkul_MpPayPal
 * @author    Webkul
 * @copyright Copyright (c) Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html
 */
/*browser:true*/
/*global define*/
define(
    [
        'ko',
        'jquery',
        'Magento_Checkout/js/view/payment/default',
        'Magento_Checkout/js/action/set-payment-information',
        'Magento_Checkout/js/action/select-payment-method',
        'Magento_Checkout/js/checkout-data',
        'Magento_Checkout/js/model/quote',
        'Magento_Checkout/js/model/totals',
        'mage/translate',
        'Magento_Checkout/js/action/redirect-on-success'
    ],
    function (
        ko,
        $,
        Component,
        setPaymentInformationAction,
        selectPaymentMethodAction,
        checkoutData,
        quote,
        totals,
        $t,
        redirectOnSuccessAction
    ) {
        'use strict';
         /**
          * customerEmail customer email
          */
         var customerEmail = window.customerData.email;
         var customerCountry = window.customerData.defaultCountryId;

        return Component.extend(
            {
                defaults: {
                    template: 'Webkul_MpPayPal/payment/mppaypal',
                    config: window.checkoutConfig.payment.mppaypal,
                    cardError: false,
                    threeDError: false,
                    paymentToken: '',
                    PPBillingAddress: false
                },

                initialize: function() {
                    var that = this;
                    that._super();
                    if (parseInt(that.config.enable_default)) {
                        that.selectPaymentMethod();
                    }
                    if (that.config.unbranded) {
                        that.attachUnbrandedPayments();
                    }
                },
                
                /**
                 * @override
                 */
                initObservable: function () {
                    this._super()
                        .observe(
                            [
                                'intent',
                                'orderID',
                                'payerID',
                                'paymentToken',
                                'quoteID',
                                'cardError',
                                'threeDError',
                                'PPBillingAddress'
                            ]
                        );
                    return this;
                },

                getUnApprovedSellers : function() {
                    var that = this;
                    var unapprovedSellers = [];
                    $.each(that.config.sellersData, function (index, seller) {
                        if (!seller.seller_status) {
                            unapprovedSellers.push(seller)
                        }
                    });
                    return unapprovedSellers;
                },

                purchaseUnitLimit: function () {
                    return this.config.purchaseUnitLimitReached;
                },

                bindPayPalBtn: function() {
                    var that = this;
                    const request = {
                        post: function (url, data) {
                            return new Promise(function (resolve) {
                                let http = new XMLHttpRequest();
                                http.open("POST", url, true);
                                http.setRequestHeader("Content-type", "application/json");
                                http.onreadystatechange = function() {
                                    if (this.readyState === 4 && this.status === 200) {
                                        return resolve(JSON.parse(this.responseText));
                                    }
                                };
                                http.send(JSON.stringify(data));
                            });
                        }
                    };
                    var quoteID = '';
                    paypal.Buttons({

                        // Set your environment
                        env: that.config.environment,
                
                        // Set style of buttons
                        style: {
                            layout: 'horizontal',   // horizontal | vertical
                            shape:  'rect',         // pill | rect
                            color:  'gold',         // gold | blue | silver | black,
                            tagline: true,          // true | false,
                            label: 'paypal'
                        },
                
                        // Set allowed funding sources
                        funding: {
                            allowed: [
                                paypal.FUNDING.CARD
                            ],
                            disallowed: [ ]
                        },
                
                        // Show the buyer a 'Pay Now' button in the checkout flow
                        commit: false,
                
                        // payment() is called to start the payment flow when a button is clicked
                        createOrder: function() {
                            const postData = {
                                'update': null,
                                'flow': 'shortcut',
                                'form_key':$.mage.cookies.get('form_key')
                            };
                            return request.post(
                                that.config.createOrderUrl,
                                postData
                            ).then(function(returnObject) {
                                var returnData = JSON.parse(returnObject);
                                quoteID = returnData['quote_id'];
                                return returnData.id;
                            });
                        },
                
                        // onAuthorize() is called when the buyer approves the payment
                        onApprove: function(data) {
                            that.intent(data.intent);
                            that.orderID(data.orderID);
                            that.payerID(data.payerID);
                            that.paymentToken(data.facilitatorAccessToken);
                            that.quoteID(quoteID);
                            that.placeOrder();
                        },
                
                        // onCancel() is called when the buyer cancels payment authorization
                        onCancel: function(data) {
                            console.log(data)
                        },
                
                        // onError() is called when there is an error in this Checkout.js script
                        onError: function (error) {
                            console.log(error)
                        }
                
                    }).render('#paypalCheckoutContainer');
                },

                generateOrder: function () {
                    var that = this;
                    const request = {
                        post: function (url, data) {
                            return new Promise(function (resolve) {
                                let http = new XMLHttpRequest();
                                http.open("POST", url, true);
                                http.setRequestHeader("Content-type", "application/json");
                                http.onreadystatechange = function() {
                                    if (this.readyState === 4 && this.status === 200) {
                                        return resolve(JSON.parse(this.responseText));
                                    }
                                };
                                http.send(JSON.stringify(data));
                            });
                        }
                    };
                    const postData = {
                        'update': null,
                        'flow': 'shortcut',
                        'form_key':$.mage.cookies.get('form_key')
                    };
                    
                    $('body').trigger('processStart');
                    request.post(
                        that.config.createOrderUrl,
                        postData
                    ).then(function(returnObject) {
                        var returnData = JSON.parse(returnObject);
                        var redirectUrl = '#';
                        $.each(returnData.links, function(index, urls) {
                            if (urls.rel == 'approve') {
                                redirectUrl = urls.href;
                            }
                        });
                        if (redirectUrl) {
                            location.href = redirectUrl;
                        } else {
                            $('body').trigger('processStop');
                            that.messageContainer.addErrorMessage({message: $t("Something went wrong")});
                        }
                        
                    });
                },
              
                /**
                 * validate  to validate the payment method fields at checkout page
                 *
                 * @return boolean
                 */
                validate: function () {
                    return true;
                },

                /**
                 * selectPaymentMethod called when payment method is selected
                 * 
                 * @return boolean
                 */
                selectPaymentMethod: function () {
                    selectPaymentMethodAction(this.getData());
                    checkoutData.setSelectedPaymentMethod('mppaypal');                    
                    return true;                 
                },

                /**
                 * totals set order totals from quote
                 */
                totals: quote.getTotals(),
              
                /**
                 * getGrandTotal get order grand total
                 *
                 * @return decimal
                 */
                getGrandTotal:function () {
                    var price = 0;
                    if (this.totals()) {
                        price = totals.getSegment('grand_total').value;
                    }
                    return price;
                },

                /**
                 * getData set payment method data for making it available in PaymentMethod Class
                 *
                 * @return object
                 */
                getData: function () {
                    var self = this;
                    return {
                        'method': 'mppaypal',
                        'additional_data': {
                            'intent' : self.intent(),
                            'orderID' : self.orderID(),
                            'payerID' : self.payerID(),
                            'paymentToken' : self.paymentToken(),
                            'quoteID' : self.quoteID(),
                        },
                    };
                },

                /**
                 * check unbranded enable
                 */
                checkUnbranded: function() {
                    return this.config.unbranded;
                },

                /**
                 * check branded enable
                 */
                checkBranded: function () {
                    var self = this;
                    if (quote.billingAddress()) {
                        self.PPBillingAddress(true);
                    }
                    return this.config.branded; 
                },
                
                /**
                 * get paypal img url
                 */
                getPayPalButtonImg: function () {
                    return this.config.buttonImg; 
                },

                /**
                 * attach unbranded card method
                 */
                attachUnbrandedPayments: function() {
                    var that = this;
                    var jsScripts = document.getElementsByTagName('head')[0];
                    var script = document.createElement('script');
                    script.async = true;
                    script.src = that.config.unbrandedScriptUrl+'&client-id='+that.config.client_id;
                    script.setAttribute('data-client-token', that.config.client_token);
                    script.setAttribute('data-namespace', 'paypal_sdk_unbranded');
                    jsScripts.appendChild(script, jsScripts);
                },

                bindPayPalUnbradedPayments: function() {
                    var that = this;
                    const request = {
                        post: function (url, data) {
                            return new Promise(function (resolve) {
                                let http = new XMLHttpRequest();
                                http.open("POST", url, true);
                                http.setRequestHeader("Content-type", "application/json");
                                http.onreadystatechange = function() {
                                    if (this.readyState === 4 && this.status === 200) {
                                        return resolve(JSON.parse(this.responseText));
                                    }
                                };
                                http.send(JSON.stringify(data));
                            });
                        }
                    };
                    $('#paypalCheckoutContainer').addClass('with-unbranded');
                    var paypalUnbranded = setInterval(function () {
                        if (paypal_sdk_unbranded != undefined) {
                            clearInterval(paypalUnbranded);
                            if (paypal_sdk_unbranded.HostedFields.isEligible()) {
                        
                                paypal_sdk_unbranded.HostedFields.render({
                                    createOrder: function () {
                                        const postData = {
                                            'form_key':$.mage.cookies.get('form_key')
                                        };
                                        return request.post(
                                            that.config.createOrderUrl,
                                            postData
                                        ).then(function(returnObject) {
                                            var returnData = JSON.parse(returnObject);
                                            that.quoteID(returnData['quote_id']);
                                            that.orderID(returnData.id);
                                            that.payerID('Card Payment');
                                            return returnData.id;
                                        });
                                    },
                                    styles: {
                                        'input': {
                                            'font-size': '14pt',
                                            'color': '#6E6D6C'
                                        },
                                        'input.invalid': {
                                            'color': 'red'
                                        },
                                        'input.valid': {
                                            'color': 'green'
                                        }
                                    },
                                    fields: {
                                        number: {
                                            selector: '#card-number',
                                            placeholder: $t('Card Number')
                                        },
                                        cvv: {
                                            selector: '#cvv',
                                            placeholder: $t('Card Security Number')
                                        },
                                        expirationDate: {
                                            selector: '#expiration-date',
                                            placeholder: $t('mm/yy')
                                        }
                                    }
                                }).then(function (hostedFieldsInstance) {
                                    $('#paypal-unbranded-form').submit(function (event) {
                                        event.preventDefault();
                                        $('body').trigger('processStart');
                                        var state = hostedFieldsInstance.getState();
                                        var formValid = Object.keys(state.fields).every(function (key) {
                                          return state.fields[key].isValid;
                                        });
                                        if (formValid) {
                                            var billingAddress = quote.billingAddress();
                                            that.cardError(false);
                                            hostedFieldsInstance.submit({
                                                // contingencies: ['3D_SECURE'],
                                                cardholderName: billingAddress.firstname+' '+billingAddress.lastname,
                                                billingAddress: {
                                                    streetAddress: billingAddress.street.toString(),
                                                    locality: billingAddress.city,
                                                    postalCode: billingAddress.postcode,
                                                    countryCodeAlpha2: billingAddress.countryId
                                                }
                                            }).then(function (payload) {
                                                if (payload.liabilityShifted === undefined) {
                                                    // Handle no 3D Secure contingency passed scenario
                                                    $('body').trigger('processStop');
                                                    that.threeDError(false);
                                                    that.placeOrder();
                                                }
                                
                                                if (payload.liabilityShifted) {
                                                    // Handle Buyer confirmed 3D Secure successfully
                                                    that.threeDError(false);
                                                    that.placeOrder();
                                                }
                                
                                                if (payload.authenticationReason === 'SKIPPED_BY_BUYER') {
                                                    // Handle buyer skipped 3D Secure use-case
                                                    $('body').trigger('processStop');
                                                    that.threeDError(true);
                                                }
                                            });
                                        } else {
                                          // Let the customer know their fields are invalid
                                            $('body').trigger('processStop');
                                          that.cardError(true);
                                        }
                                    });
                                });
                            }
                            else {
                                $('#paypal-unbranded-form').hide();    // hide hosted fields
                            }
                        }
                    },500);
                }
            }
        );
    }
);
