/**
 * OpenMage
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE_AFL.txt.
 * It is also available at https://opensource.org/license/afl-3-0-php
 *
 * @category    Mage
 * @package     js
 * @copyright   Copyright (c) 2006-2020 Magento, Inc. (https://www.magento.com)
 * @copyright   Copyright (c) 2022-2023 The OpenMage Contributors (https://www.openmage.org)
 * @license     https://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */
var directPost = Class.create();
directPost.prototype = {
    initialize : function(methodCode, iframeId, controller, orderSaveUrl,
            cgiUrl, nativeAction) {
        this.iframeId = iframeId;
        this.controller = controller;
        this.orderSaveUrl = orderSaveUrl;
        this.nativeAction = nativeAction;
        this.cgiUrl = cgiUrl;
        this.code = methodCode;
        this.inputs = ['cc_type', 'cc_number', 'expiration', 'expiration_yr', 'cc_cid'];
        this.headers = [];
        this.isValid = true;
        this.paymentRequestSent = false;
        this.isResponse = false;
        this.orderIncrementId = false;
        this.successUrl = false;
        this.hasError = false;
        this.tmpForm = false;

        this.onSaveOnepageOrderSuccess = this.saveOnepageOrderSuccess.bindAsEventListener(this);
        this.onLoadIframe = this.loadIframe.bindAsEventListener(this);
        this.onLoadOrderIframe = this.loadOrderIframe.bindAsEventListener(this);
        this.onSubmitAdminOrder = this.submitAdminOrder.bindAsEventListener(this);

        this.preparePayment();
    },

    validate : function() {
        this.isValid = true;
        this.inputs.each(function(elemIndex) {
            if ($(this.code + '_' + elemIndex)) {
                if (!Validation.validate($(this.code + '_' + elemIndex))) {
                    this.isValid = false;
                }
            }
        }, this);

        return this.isValid;
    },

    changeInputOptions : function(param, value) {
        this.inputs.each(function(elemIndex) {
            if ($(this.code + '_' + elemIndex)) {
                $(this.code + '_' + elemIndex).writeAttribute(param, value);
            }
        }, this);
    },

    preparePayment : function() {
        this.changeInputOptions('autocomplete', 'off');
        if ($(this.iframeId)) {
            switch (this.controller) {
                case 'onepage':
                    this.headers = $$('#' + checkout.accordion.container.readAttribute('id') + ' .section');
                    var button = $('review-buttons-container').down('button');
                    button.writeAttribute('onclick', '');
                    button.stopObserving('click');
                    button.observe('click', function() {
                        if ($(this.iframeId)) {
                            if (this.validate()) {
                                this.saveOnepageOrder();
                            }
                        } else {
                            review.save();
                        }
                    }.bind(this));
                    break;
                case 'sales_order_create':
                case 'sales_order_edit':
                    var buttons = document.getElementsByClassName('scalable save');
                    for ( var i = 0; i < buttons.length; i++) {
                        buttons[i].writeAttribute('onclick', '');
                        buttons[i].observe('click', this.onSubmitAdminOrder);
                    }
                    $('order-' + this.iframeId).observe('load', this.onLoadOrderIframe);
                    break;
            }

            $(this.iframeId).observe('load', this.onLoadIframe);
        }
    },

    loadIframe : function() {
        if (this.paymentRequestSent) {
            switch (this.controller) {
                case 'onepage':
                    this.paymentRequestSent = false;
                    if (!this.hasError) {
                        this.returnQuote();
                    }
                    break;
                case 'sales_order_edit':
                case 'sales_order_create':
                    if (!this.orderRequestSent) {
                        this.paymentRequestSent = false;
                        if (!this.hasError) {
                            this.returnQuote();
                        } else {
                            this.changeInputOptions('disabled', false);
                            hideLoader();
                            enableElements('save');
                        }
                    }
                    break;
            }
            if (this.tmpForm) {
                document.body.removeChild(this.tmpForm);
            }
        }
    },

    loadOrderIframe : function() {
        if (this.orderRequestSent) {
            $(this.iframeId).hide();
            var data = $('order-' + this.iframeId).contentWindow.document.body.innerHTML;
            this.saveAdminOrderSuccess(data);
            this.orderRequestSent = false;
        }
    },

    showError : function(msg) {
        this.hasError = true;
        if (this.controller == 'onepage') {
            $(this.iframeId).hide();
            this.resetLoadWaiting();
        }
        alert(msg.stripTags().toString());
    },

    returnQuote : function() {
        var url = this.orderSaveUrl.replace('place', 'returnQuote');
        new Ajax.Request(url, {
            onSuccess : function(transport) {
                var response = transport.responseJSON || transport.responseText.evalJSON(true) || {};

                if (response.error_message) {
                    alert(response.error_message.stripTags().toString());
                }
                $(this.iframeId).show();
                switch (this.controller) {
                    case 'onepage':
                        this.resetLoadWaiting();
                        break;
                    case 'sales_order_edit':
                    case 'sales_order_create':
                        this.changeInputOptions('disabled', false);
                        hideLoader();
                        enableElements('save');
                        break;
                }
            }.bind(this)
        });
    },

    setLoadWaiting : function() {
        this.headers.each(function(header) {
            header.removeClassName('allow');
        });
        checkout.setLoadWaiting('review');
    },

    resetLoadWaiting : function() {
        this.headers.each(function(header) {
            header.addClassName('allow');
        });
        checkout.setLoadWaiting(false);
    },

    saveOnepageOrder : function() {
        this.hasError = false;
        this.setLoadWaiting();
        var params = Form.serialize(payment.form);
        if (review.agreementsForm) {
            params += '&' + Form.serialize(review.agreementsForm);
        }
        params += '&controller=' + this.controller;
        new Ajax.Request(this.orderSaveUrl, {
            method : 'post',
            parameters : params,
            onComplete : this.onSaveOnepageOrderSuccess,
            onFailure : function(transport) {
                this.resetLoadWaiting();
                if (transport.status == 403) {
                    checkout.ajaxFailure();
                }
            }
        });
    },

    saveOnepageOrderSuccess : function(transport) {
        if (transport.status == 403) {
            checkout.ajaxFailure();
        }
        var response = transport.responseJSON || transport.responseText.evalJSON(true) || {};

        if (response.success && response.directpost) {
            this.orderIncrementId = response.directpost.fields.x_invoice_num;
            var paymentData = {};
            for ( var key in response.directpost.fields) {
                if(response.directpost.fields.hasOwnProperty(key)) {
                    paymentData[key] = response.directpost.fields[key];
                }
            }
            var preparedData = this.preparePaymentRequest(paymentData);
            this.sendPaymentRequest(preparedData);
        } else {
            var msg = response.error_messages;
            if (Object.isArray(msg)) {
                msg = msg.join("\n");
            }
            if (msg) {
                alert(msg.stripTags().toString());
            }

            if (response.update_section) {
                $('checkout-' + response.update_section.name + '-load').update(response.update_section.html);
                response.update_section.html.evalScripts();
            }

            if (response.goto_section) {
                checkout.gotoSection(response.goto_section);
                checkout.reloadProgressBlock();
            }
        }
    },

    submitAdminOrder : function() {
        if (editForm.validate()) {
            var paymentMethodEl = $(editForm.formId).getInputs('radio','payment[method]').find(function(radio) {
                return radio.checked;
            });
            this.hasError = false;
            if (paymentMethodEl.value == this.code) {
                showLoader();
                this.changeInputOptions('disabled', 'disabled');
                this.paymentRequestSent = true;
                this.orderRequestSent = true;
                $(editForm.formId).writeAttribute('action', this.orderSaveUrl);
                $(editForm.formId).writeAttribute('target',
                        $('order-' + this.iframeId).readAttribute('name'));
                $(editForm.formId).appendChild(this.createHiddenElement('controller', this.controller));
                disableElements('save');
                $(editForm.formId).submit();
            } else {
                $(editForm.formId).writeAttribute('action', this.nativeAction);
                $(editForm.formId).writeAttribute('target', '_top');
                disableElements('save');
                $(editForm.formId).submit();
            }
        }
    },

    recollectQuote : function() {
        var area = [ 'sidebar', 'items', 'shipping_method', 'billing_method', 'totals', 'giftmessage' ];
        area = order.prepareArea(area);
        var url = order.loadBaseUrl + 'block/' + area;
        var info = $('order-items_grid').select('input', 'select', 'textarea');
        var data = {};
        for ( var i = 0; i < info.length; i++) {
            if (!info[i].disabled && (info[i].type != 'checkbox' || info[i].checked)) {
                data[info[i].name] = info[i].getValue();
            }
        }
        data.reset_shipping = true;
        data.update_items = true;
        if ($('coupons:code') && $F('coupons:code')) {
            data['order[coupon][code]'] = $F('coupons:code');
        }
        data.json = true;
        new Ajax.Request(url, {
            parameters : data,
            loaderArea : 'html-body',
            onSuccess : function(transport) {
                $(editForm.formId).submit();
            }.bind(this)
        });

    },

    saveAdminOrderSuccess : function(data) {
        var response = transport.responseJSON || transport.responseText.evalJSON(true) || {};

        if (response.directpost) {
            this.orderIncrementId = response.directpost.fields.x_invoice_num;
            var paymentData = {};
            for ( var key in response.directpost.fields) {
                if(response.directpost.fields.hasOwnProperty(key)) {
                    paymentData[key] = response.directpost.fields[key];
                }
            }
            var preparedData = this.preparePaymentRequest(paymentData);
            this.sendPaymentRequest(preparedData);
        } else {
            if (response.redirect) {
                window.location = response.redirect;
            }
            if (response.error_messages) {
                var msg = response.error_messages;
                if (Object.isArray(msg)) {
                    msg = msg.join("\n");
                }
                if (msg) {
                    alert(msg.stripTags().toString());
                }
            }
        }
    },

    preparePaymentRequest : function(data) {
        if ($(this.code + '_cc_cid')) {
            data.x_card_code = $(this.code + '_cc_cid').value;
        }
        var year = $(this.code + '_expiration_yr').value;
        if (year.length > 2) {
            year = year.substring(2);
        }
        var month = parseInt($(this.code + '_expiration').value, 10);
        if (month < 10) {
            month = '0' + month;
        }

        data.x_exp_date = month + '/' + year;
        data.x_card_num = $(this.code + '_cc_number').value;

        return data;
    },

    sendPaymentRequest : function(preparedData) {
        this.recreateIframe();
        this.tmpForm = document.createElement('form');
        this.tmpForm.style.display = 'none';
        this.tmpForm.enctype = 'application/x-www-form-urlencoded';
        this.tmpForm.method = 'POST';
        document.body.appendChild(this.tmpForm);
        this.tmpForm.action = this.cgiUrl;
        this.tmpForm.target = $(this.iframeId).readAttribute('name');
        this.tmpForm.setAttribute('target', $(this.iframeId).readAttribute('name'));

        for ( var param in preparedData) {
            this.tmpForm.appendChild(this.createHiddenElement(param, preparedData[param]));
        }

        this.paymentRequestSent = true;
        this.tmpForm.submit();
    },

    createHiddenElement : function(name, value) {
        var field;
        field = document.createElement('input');
        field.type = 'hidden';
        field.name = name;
        field.value = value;
        return field;
    },

    recreateIframe : function() {
        if ($(this.iframeId)) {
            var nextElement = $(this.iframeId).next();
            var src = $(this.iframeId).readAttribute('src');
            var name = $(this.iframeId).readAttribute('name');
            $(this.iframeId).stopObserving();
            $(this.iframeId).remove();
            var iframe = '<iframe id="' + this.iframeId + 
                '" allowtransparency="true" frameborder="0"  name="' + name + 
                '" style="display:none;width:100%;background-color:transparent" src="' + src + '" />';
            Element.insert(nextElement, {'before':iframe});
            $(this.iframeId).observe('load', this.onLoadIframe);
        }
    }
};
