// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

/**
 * The main controller of the daily closing subapp.
 */
Ext.define('Shopware.apps.ViisonShippingCommonDailyClosing.controller.Main', {

    extend: 'Ext.app.Controller',

    mainWindow: null,

    /**
     * @Override
     */
    init: function() {
        // Load the shop store
        this.shopStore = Ext.create('Shopware.apps.ViisonShippingCommonDailyClosing.store.Shop').load({
            scope: this,
            callback: function() {
                // Create the main window and pass the shop store to it
                this.mainWindow = this.getView('main.Window').create({
                    shopStore: this.shopStore
                });
            }
        });

        this.control({
            'viison_shipping_common_daily_closing-main_window': {
                showManifest: this.onShowManifest
            },
            'viison_shipping_common_daily_closing-main_window button[action=cancel]': {
                click: this.onCancel
            }
        });

        this.callParent(arguments);
    },

    /**
     * Reads the given form and parses the contained dates. These and the shop id are then used
     * to open a new tab showing the manifest document requested from ShippingCommon.
     */
    onShowManifest: function(form) {
        // Check if the form is valid
        if (!form.isValid()) {
            return;
        }
        // Get all values from the form
        var values = form.getFieldValues();

        // If the value for "All shops" is null or 0 depends on if the user selected it actively, make it consistent
        if (values.shop == null) {
            values.shop = 0;
        }

        // Open the manifest in a new window
        var params = '';
        if (values.onlyNewLabels) {
            params = '&onlyNewLabels=1';
        } else {
            if ('fromDate' in values) {
                // Get formatted string representations of the two dates
                var from = this.getFormattedDate(values.fromDate),
                    to = this.getFormattedDate(values.toDate);

                if (this.doesPluginSupportTimeSpecification()) {
                    from += ' ' + this.getFormattedTime(values.fromDate);
                    to += ' ' + this.getFormattedTime(values.toDate);
                }
                params = '&from=' + from + '&to=' + to;
            } else {
                params = '&date=' + this.getFormattedDate(values.date);
            }
        }

        this.mainWindow.loadMask.show();

        var url = this.getDailyClosingURL + '?shopId=' + values.shop + params;
        var xhr = new XMLHttpRequest();

        var me = this;
        xhr.addEventListener('load', function () {
            var blob = new Blob([xhr.response], { type: xhr.getResponseHeader('content-type') });
            me.mainWindow.loadMask.hide();
            window.open(URL.createObjectURL(blob));
        }, { once: true });
        xhr.addEventListener('error', function () {
            me.mainWindow.loadMask.hide();
        }, { once: true });

        xhr.responseType = 'arraybuffer';
        xhr.open('GET', url, true);
        xhr.send(null);
    },

    /**
     * Closes the main window/application.
     */
    onCancel: function(button, event, options) {
        this.mainWindow.close();
    },

    /**
     * Expects a Date object, whose date proportion is parsed and returned
     * in the format 'YYYY-MM-DD'.
     *
     * @param date The date object, whose formatted date value ill be returned.
     * @return A formatted string of the date's value.
     */
    getFormattedDate: function(date) {
        // Get the date components
        var days = date.getDate() + '',
            months = (date.getMonth() + 1) + '',
            years = date.getFullYear() + '';

        // Add missing zeros
        days = (days.length === 1) ? ('0' + days) : days;
        months = (months.length === 1) ? ('0' + months) : months;

        // Return the date formatted in 'YYYY-MM-DD'
        return years + '-' + months + '-' + days;
    },

    /**
     * Expects a Date object, whose time proportion is parsed and returned
     * in the format 'hh:mm:ss'.
     *
     * @param date The date object, whose formatted date value ill be returned.
     * @return A formatted string of the date's value.
     */
    getFormattedTime: function(date) {
        // Get the time components
        var hours = date.getHours() + '',
            minutes = (date.getMinutes()) + '',
            seconds = date.getSeconds() + '';

        // Add missing zeros
        hours = (hours.length === 1) ? ('0' + hours) : hours;
        minutes = (minutes.length === 1) ? ('0' + minutes) : minutes;
        seconds = (seconds.length === 1) ? ('0' + seconds) : seconds;

        // Return the time formatted in 'hh:mm:ss'
        return hours + ':' + minutes + ':' + seconds;
    },

    /**
     * Checks if the plugin supports the specification of the time part of the from and to dates.
     *
     * @returns boolean
     */
    doesPluginSupportTimeSpecification: function() {
        return (Object.getPrototypeOf(this).hasOwnProperty('pluginSupportsTimeSpecification') &&
            this.pluginSupportsTimeSpecification);
    }

});
