// 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.

// {namespace name=backend/viison_pickware_common_device_management/main}
Ext.define('Shopware.apps.ViisonPickwareCommonDeviceManagement.controller.Main', {

    extend: 'Ext.app.Controller',
    mainWindow: null,
    advancedWindow: null,
    refs: [
        { ref: 'list', selector: 'viison_pickware_common_device_management-main-list' },
    ],
    snippets: {
        notification: {
            failureTitle: '{s name="main/notification/failure_title"}{/s}',
            confirmSingle: {
                success: {
                    title: '{s name="main/notification/confirm_single/success/title"}{/s}',
                    message: '{s name="main/notification/confirm_single/success/message"}{/s}',
                },
                failure: {
                    message: '{s name="main/notification/confirm_single/failure/message"}{/s}',
                },
            },
            confirmBatch: {
                success: {
                    title: '{s name="main/notification/confirm_batch/success/title"}{/s}',
                    message: '{s name="main/notification/confirm_batch/success/message"}{/s}',
                },
                failure: {
                    message: '{s name="main/notification/confirm_batch/failure/message"}{/s}',
                },
            },
            deleteSingle: {
                success: {
                    title: '{s name="main/notification/delete_single/success/title"}{/s}',
                    message: '{s name="main/notification/delete_single/success/message"}{/s}',
                },
                failure: {
                    message: '{s name="main/notification/delete_single/failure/message"}{/s}',
                },
            },
            deleteBatch: {
                success: {
                    title: '{s name="main/notification/delete_batch/success/title"}{/s}',
                    message: '{s name="main/notification/delete_batch/success/message"}{/s}',
                },
                failure: {
                    message: '{s name="main/notification/delete_batch/failure/message"}{/s}',
                },
            },
            save: {
                success: {
                    title: '{s name="main/notification/save/success/title"}{/s}',
                    message: '{s name="main/notification/save/success/message"}{/s}',
                },
                failure: {
                    message: '{s name="main/notification/save/failure/message"}{/s}',
                },
            },
        },
        alert: {
            warningTitle: '{s name="main/alert/warning_title"}{/s}',
            deleteSingleMessage: '{s name="main/alert/delete_single_message"}{/s}',
            deleteBatchMessage: '{s name="main/alert/delete_batch_message"}{/s}',
        },
    },

    /**
     * @Override
     */
    init: function () {
        // Create the main window
        this.mainWindow = this.getView('Main').create({
            pickwareDeviceStore: this.getStore('PickwareDevice'),
        });

        // Call the action handler instead of 'reloadData', because we wnat to trigger the Store login, if necessary
        this.onReloadList();

        this.control({
            'viison_pickware_common_device_management-main-list button[action=confirmDevices]': {
                click: this.onConfirmDevices,
            },
            'viison_pickware_common_device_management-main-list button[action=deleteDevices]': {
                click: this.onDeleteDevices,
            },
            'viison_pickware_common_device_management-main-list button[action=reloadList]': {
                click: this.onReloadList,
            },
            'viison_pickware_common_device_management-main-list': {
                saveDevice: this.onSaveDevice,
                deleteSingleDevice: this.onDeleteSingleDevice,
                confirmSingleDevice: this.onConfirmSingleDevice,
            },
        });

        this.callParent(arguments);
    },

    /**
     * Marks the given device as confirmed and triggers a sync of the data store.
     *
     * @param device
     */
    onConfirmSingleDevice: function (device) {
        // Mark device as confirmed
        device.set('confirmed', true);

        // Save changes on the server
        this.syncDevices(this.snippets.notification.confirmSingle);
    },

    /**
     * Finds all devices that are selected in the list, marks them as confirmed
     * and triggers a sync of the data store.
     */
    onConfirmDevices: function () {
        // Get all selected devices
        var devices = this.getList().getSelectionModel().getSelection();
        if (devices.length === 0) {
            return;
        }

        // Mark them all as confirmed
        for (var i = 0; i < devices.length; i += 1) {
            devices[i].set('confirmed', true);
            devices[i].setDirty();
        }

        // Save changes on the server
        this.syncDevices(this.snippets.notification.confirmBatch);
    },

    /**
     * Presents a confirmation alert. If confirmed, the given device is removed
     * from the data store before it is synced.
     *
     * @param device
     */
    onDeleteSingleDevice: function (device) {
        // Present a confirm alert before deleting the device
        Ext.Msg.confirm(this.snippets.alert.warningTitle, this.snippets.alert.deleteSingleMessage, function (decision) {
            if (decision !== 'yes') {
                return;
            }

            // Remove the device from the store
            this.getStore('PickwareDevice').remove([
                device,
            ]);

            // Save changes on the server
            this.syncDevices(this.snippets.notification.deleteSingle);
        }, this);
    },

    /**
     * Presents a confirmation alert. If confirmed, it finds all devices that are
     * selected in the list, removes them from the data store and syncs it.
     */
    onDeleteDevices: function () {
        // Present a confirm alert before deleting the device
        Ext.Msg.confirm(this.snippets.alert.warningTitle, this.snippets.alert.deleteBatchMessage, function (decision) {
            if (decision !== 'yes') {
                return;
            }

            // Get all selected devices
            var devices = this.getList().getSelectionModel().getSelection();
            if (devices.length === 0) {
                return;
            }

            // Remove the devices from the store
            this.getStore('PickwareDevice').remove(devices);

            // Save changes on the server
            this.syncDevices(this.snippets.notification.deleteBatch);
        }, this);
    },

    /**
     * Just triggers a sync of the data store to save changed devices.
     */
    onSaveDevice: function () {
        // Save changes on the server
        this.syncDevices(this.snippets.notification.save);
    },

    /**
     * Reloads both the app support info and device store. If executed in a Shopware version >= 5.5, a valid Shopware
     * store access token is ensured before reloading any data.
     */
    onReloadList: function () {
        if (this.environmentIsAtLeastShopware55()) {
            // In Shopware >= 5.5 the device limits are requested from the Shopware store API, which is only possible
            // if a valid access token exists. Therefore we fire the 'check-store-login' event, which first checks for a
            // valud access token and, if none exists, presents the store login.
            // That said, the callback of the event is fired even if e.g. the login failed and hence is useless here.
            // To work around this, we listen on the 'refresh-account-data' event, which is fired both if a valid access
            // token is found and if the login was successful.
            Shopware.app.Application.on(
                'refresh-account-data',
                this.reloadData,
                this,
                {
                    single: true,
                }
            );

            // Fisrt 'get' the main controller of the PluginManager app, to ensure it is loaded and hence listens for
            // the 'check-store-login' plugin
            this.getController('Shopware.apps.PluginManager.controller.Plugin');
            Shopware.app.Application.fireEvent('check-store-login', Ext.emptyFn);
        } else {
            // Showpare < 5.5, hence just load the data
            this.reloadData();
        }
    },

    /**
     * Sets the main window in a loading state and loads the app support info, before finally reloading the device list.
     */
    reloadData: function () {
        this.mainWindow.setLoading(true);
        // Load the app support info first
        var listView = this.mainWindow.down('viison_pickware_common_device_management-main-list');
        Ext.Ajax.request({
            url: '{url controller=ViisonPickwareCommonDeviceManagement action=getAppSupportInfo}',
            scope: this,
            success: function (response) {
                var appSupportInfo = Ext.JSON.decode(response.responseText, true).data;
                listView.appSupportInfo = appSupportInfo;
                listView.missingLicenseDataInfoPanel.hide();

                // Load the device store
                listView.store.load({
                    scope: this,
                    callback: function (devices, operation, success) {
                        this.mainWindow.setLoading(false);
                        if (!success) {
                            Shopware.Notification.createGrowlMessage(
                                this.snippets.notification.failureTitle,
                                '{s name="main/notification/load_devices/failure/message"}{/s}',
                                'Pickware'
                            );
                        }
                    },
                });
            },
            failure: function () {
                this.mainWindow.setLoading(false);
                listView.missingLicenseDataInfoPanel.show();
            },
        });
    },

    /**
     * Synchronizes the PickwareDevice data store and presents a notification
     * informing the user about the success of the operation.
     */
    syncDevices: function (snippetRoot) {
        this.mainWindow.setLoading(true);
        this.getStore('PickwareDevice').sync({
            scope: this,
            success: function () {
                this.mainWindow.setLoading(false);
                // Display a success notification
                Shopware.Notification.createGrowlMessage(snippetRoot.success.title, snippetRoot.success.message, 'Pickware');
            },
            failure: function () {
                this.mainWindow.setLoading(false);
                // Revert any changes like removed or updated records
                this.getStore('PickwareDevice').rejectChanges();
                // Display an error notification
                Shopware.Notification.createGrowlMessage(this.snippets.notification.failureTitle, snippetRoot.failure.message, 'Pickware');
            },
        });
    },

    /**
     * @return boolean True, if the executing environment is at least Shopware version 5.5.0. False otherwise.
     */
    environmentIsAtLeastShopware55: function () {
        return typeof Shopware.window.ExpiredPluginStop !== 'undefined';
    },

});
