/* @flow */

import { prefix } from 'beaver-logger/client';

import { onDocumentReady, awaitKey } from '../lib';
import { ENV } from '../constants';

import { LOG_PREFIX, ATTRIBUTES, CLASSES } from './constants';
import { setup } from './interface';

let { error, debug } = prefix(LOG_PREFIX);

/*  PayPal Checkout Ready
    ---------------------

    Call window.paypalCheckoutReady on document ready, if it has been defined by the merchant
*/

function invokeReady(method) {

    onDocumentReady(() => {
        debug(`paypal_checkout_ready`);
        setTimeout(() => {

            if (!window.paypal) {
                error(`paypal_checkout_ready_no_window_paypal`);
            }

            method();
        }, 1);
    });
}


awaitKey(window, 'paypalCheckoutReady').then(method => {

    if (typeof method === 'function') {

        let oneTimeReady = function() : void {
            if (!method.called) {
                method.called = true;
                return method.apply(this, arguments);
            }
        };

        invokeReady(oneTimeReady);

        delete window.paypalCheckoutReady;

        // $FlowFixMe
        Object.defineProperty(window, 'paypalCheckoutReady', {
            get: () => {
                return oneTimeReady;
            },
            set: (val) => {
                method = val;
                oneTimeReady();
            }
        });
    }
});


/*  Scan for buttons
    ----------------

    Scan for any buttons on the page with a data-paypal-button attribute and auto-attach the PaypalCheckout component to them
*/

onDocumentReady(() => {

    let buttons = Array.prototype.slice.call(document.querySelectorAll(`[${ ATTRIBUTES.BUTTON }]`));

    if (buttons && buttons.length) {
        debug(`data_paypal_button`, { number: buttons.length });

        for (let button of buttons) {

            let id = button.getAttribute(ATTRIBUTES.MERCHANT_ID);

            let environment;

            if (button.hasAttribute(ATTRIBUTES.ENV)) {
                environment = button.getAttribute(ATTRIBUTES.ENV);
            } else if (button.hasAttribute(ATTRIBUTES.SANDBOX)) {
                environment = ENV.SANDBOX;
            }

            setup(id, { environment, button });
        }
    }

    // Show hidden buttons

    Array.prototype.slice.call(document.getElementsByClassName(CLASSES.HIDDEN_BUTTON)).forEach(el => {
        el.className = el.className.replace(CLASSES.HIDDEN_BUTTON, '');
    });
});

@@ -82,18 +82,8 @@
 eady
-, awaitKey
  %7D f
@@ -723,104 +723,214 @@
 %0A%7D%0A%0A
-%0AawaitKey(window, 'paypalCheckoutReady').then(method =%3E %7B%0A%0A    if (typeof method === 'function')
+function onKey(obj : Object, key : string, callback : Function) %7B%0A%0A    if (!obj) %7B%0A        return;%0A    %7D%0A%0A    let value = obj%5Bkey%5D;%0A%0A    if (value) %7B%0A        value = callback(value) %7C%7C value;%0A    %7D%0A%0A    try
  %7B%0A%0A
@@ -941,173 +941,244 @@
     
+de
 let
+e
  o
-neTimeReady = function() : void %7B%0A            if (!method.called) %7B%0A                method.called = true;%0A                return method.apply(this, arguments);%0A
+bj%5Bkey%5D;%0A%0A        Object.defineProperty(obj, key, %7B%0A%0A            configurable: true,%0A%0A            set(item) %7B%0A                value = item;%0A%0A                if (value) %7B%0A                    value = callback(value) %7C%7C value;%0A    
     
@@ -1199,10 +1199,14 @@
     
+  
-%7D;
+  %7D,
 %0A%0A  
@@ -1215,130 +1215,134 @@
     
-invokeReady(oneTimeReady);%0A%0A        delete window.paypalCheckoutReady;%0A%0A        // $FlowFixMe%0A        Object.definePropert
+    get() : mixed %7B%0A                return value;%0A            %7D%0A        %7D);%0A%0A    %7D catch (err) %7B%0A        // pass%0A    %7D%0A%7D%0A%0AonKe
 y(wi
@@ -1374,51 +1374,70 @@
 y', 
-%7B%0A            get: ()
+method
  =%3E %7B%0A
+%0A
     
-    
+if (typeof method === 'function') %7B%0A%0A
         
 retu
@@ -1432,22 +1432,19 @@
         
-r
+l
 et
-urn
  oneTime
@@ -1452,50 +1452,63 @@
 eady
-;%0A            %7D,%0A            set: (val) =%3E
+ = function () : void %7B%0A            if (!method.called)
  %7B%0A 
@@ -1532,14 +1532,22 @@
 thod
- = val
+.called = true
 ;%0A  
@@ -1564,48 +1564,135 @@
     
-oneTimeReady();%0A            %7D%0A        %7D)
+return method.apply(this, arguments);%0A            %7D%0A        %7D;%0A%0A        invokeReady(oneTimeReady);%0A%0A        return oneTimeReady
 ;%0A  

Use original onKey for ready