// 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.view.main.List', {

    extend: 'Ext.grid.Panel',
    alias: 'widget.viison_pickware_common_device_management-main-list',
    split: true,
    border: true,
    autoScroll: true,
    cls: 'viison-common--grid has--no-borders',
    viewConfig: {
        loadMask: false,
        enableTextSelection: true,
    },
    snippets: {
        appNames: {
            picking: '{s name="list/app_names/picking"}{/s}',
            stocking: '{s name="list/app_names/stocking"}{/s}',
            pos: '{s name="list/app_names/pos"}{/s}',
        },
    },
    appSupportInfo: {},

    /**
     * @Override
     */
    initComponent: function () {
        // Add an empty text that points to the Pickware documentation
        this.emptyText = Ext.String.format(
            '{s name="list/empty_text/text"}{/s}',
            '<a href="{s name="list/empty_text/documentation/url"}{/s}" target="_blank">{s name="list/empty_text/documentation/title"}{/s}</a>'
        );

        // Init the grid selection model
        this.selModel = Ext.create('Ext.selection.CheckboxModel', {
            checkOnly: true,
            listeners: {
                scope: this,
                selectionchange: function (model, selection) {
                    // Change the disabled states of the two buttons
                    this.confirmDevicesButton.setDisabled(selection.length === 0);
                    this.deleteDevicesButton.setDisabled(selection.length === 0);
                },
            },
        });

        // Add the list columns
        this.columns = [{
            xtype: 'gridcolumn',
            header: '{s name="list/columns/name"}{/s}',
            dataIndex: 'name',
            sortable: true,
            flex: 1,
            editor: {
                xtype: 'textfield',
                allowBlank: false,
                padding: '0 5 0 0',
            },
        }, {
            xtype: 'gridcolumn',
            header: '{s name="list/columns/added"}{/s}',
            dataIndex: 'added',
            sortable: true,
            width: 120,
            renderer: Ext.util.Format.dateRenderer('d.m.Y H:i:s'),
        }, {
            xtype: 'gridcolumn',
            header: '{s name="list/columns/last_login"}{/s}',
            dataIndex: 'lastLogin',
            sortable: true,
            width: 120,
            renderer: Ext.util.Format.dateRenderer('d.m.Y H:i:s'),
        }, {
            xtype: 'gridcolumn',
            header: '{s name="list/columns/confirmed"}{/s}',
            dataIndex: 'confirmed',
            sortable: true,
            width: 50,
            renderer: function (value, metaData) {
                // Add a Qtip to the cell
                var message = (value) ? '{s name="list/columns/confirmed/tooltip/confirmed"}{/s}' : '{s name="list/columns/confirmed/tooltip/not_confirmed"}{/s}';
                metaData.tdAttr = 'data-qtip="<b>' + message + '</b>"';

                // Select the icon class and create a new element
                var iconCls = (value) ? 'sprite-tick' : 'sprite-cross';
                var tpl = new Ext.XTemplate('<div class="customer-column-icon ' + iconCls + '"></div>');

                return tpl.html;
            },
        }, {
            xtype: 'actioncolumn',
            width: 50,
            items: [{
                iconCls: 'sprite-minus-circle',
                action: 'deleteSingleDevice',
                tooltip: '{s name="list/columns/actions/tooltip/delete"}{/s}',
                scope: this,
                handler: function (view, rowIndex) {
                    this.fireEvent('deleteSingleDevice', view.getStore().getAt(rowIndex));
                },
            }, {
                iconCls: 'sprite-tick-circle',
                action: 'confirmSingleDevice',
                tooltip: '{s name="list/columns/actions/tooltip/confirm"}{/s}',
                scope: this,
                handler: function (view, rowIndex) {
                    this.fireEvent('confirmSingleDevice', view.getStore().getAt(rowIndex));
                },
                getClass: function (html, metadata, record) {
                    // Hide this action icon, if the device is already confirmed or no more device can be activated for
                    // the same app
                    var appSupportInfo = this.getAppSupportInfo(record.get('appName'));
                    var deviceCount = this.store.getGroups(record.get('appName')).children.length;
                    var canActivateMoreDevices = appSupportInfo && appSupportInfo.isLicenseValid && deviceCount < appSupportInfo.deviceLimit;

                    return (record.get('confirmed') || !canActivateMoreDevices) ? 'x-hide-display' : '';
                },
            }],
        }];

        // Add a grouping feature to the grid
        this.features = [
            Ext.create('Ext.grid.feature.Grouping', {
                groupHeaderTpl: [
                    '{literal}<div style="color: {rows:this.selectColor};" data-qtip="{rows:this.selectTooltip}">{name:this.localiseName} ({rows:this.caluculateConfirmedDeviceCount}/{rows:this.getDeviceLimit})</div>{/literal}',
                    {
                        selectColor: function (rows) {
                            // Compare the number of rows with the limit for the respective app name to select the
                            // text color
                            var appSupportInfo = this.getAppSupportInfoForGroupedRows(rows);

                            return (!appSupportInfo || !appSupportInfo.isLicenseValid || rows.length > appSupportInfo.deviceLimit) ? 'red' : 'black';
                        }.bind(this),
                        selectTooltip: function (rows) {
                            // Compare the number of confirmed rows with the limit for the respective app name to select
                            // the tooltip
                            var confirmedRows = rows.filter(function (row) {
                                return row.data.confirmed;
                            });
                            var appSupportInfo = this.getAppSupportInfoForGroupedRows(rows);
                            var deviceLimit = (appSupportInfo) ? appSupportInfo.deviceLimit : 0;
                            if (!appSupportInfo) {
                                return '{s name="list/group_header/tooltip/no_supporting_plugin"}{/s}';
                            }
                            if (!appSupportInfo.isLicenseValid) {
                                return Ext.String.format(
                                    '{s name="list/group_header/tooltip/invalid_license"}{/s}',
                                    appSupportInfo.pluginLabel
                                );
                            }
                            if (confirmedRows.length < deviceLimit) {
                                return Ext.String.format(
                                    '{s name="list/group_header/tooltip/limit_remaining"}{/s}',
                                    deviceLimit - confirmedRows.length
                                );
                            }
                            if (confirmedRows.length === deviceLimit) {
                                return '{s name="list/group_header/tooltip/limit_reached"}{/s}';
                            }

                            return Ext.String.format(
                                '{s name="list/group_header/tooltip/limit_exceeded"}{/s}',
                                appSupportInfo.pluginLabel
                            );
                        }.bind(this),
                        localiseName: function (name) {
                            // Try to find the name in the snippets
                            return this.snippets.appNames[name.toLowerCase()] || name;
                        }.bind(this),
                        caluculateConfirmedDeviceCount: function (rows) {
                            var confirmedRows = rows.filter(function (row) {
                                return row.data.confirmed;
                            });

                            return confirmedRows.length;
                        },
                        getDeviceLimit: function (rows) {
                            var appSupportInfo = this.getAppSupportInfoForGroupedRows(rows);

                            return (appSupportInfo) ? appSupportInfo.deviceLimit : '?';
                        }.bind(this),
                    },
                ],
            }),
        ];

        // Create buttons for confirming or deleting multiple devices at once
        this.confirmDevicesButton = Ext.create('Ext.button.Button', {
            text: '{s name="list/toolbar/confirm"}{/s}',
            iconCls: 'sprite-tick-circle',
            action: 'confirmDevices',
            disabled: true,
        });
        this.deleteDevicesButton = Ext.create('Ext.button.Button', {
            text: '{s name="list/toolbar/delete"}{/s}',
            iconCls: 'sprite-minus-circle',
            action: 'deleteDevices',
            disabled: true,
        });
        this.reloadListButton = Ext.create('Ext.button.Button', {
            tooltip: '{s name="list/toolbar/reload"}{/s}',
            iconCls: 'sprite-arrow-circle-315',
            action: 'reloadList',
        });

        // Create a hidden license data info panel
        var missingLicenseDataInfoPanelText = '{s name="list/missing_license_data_info_panel/text"}{/s}';
        if (this.environmentIsAtLeastShopware55()) {
            missingLicenseDataInfoPanelText += ' {s name="list/missing_license_data_info_panel/shopware55_login_hint"}{/s}';
        }
        this.missingLicenseDataInfoPanel = Ext.create('Ext.container.Container', {
            cls: 'viison-common--info-panel',
            html: missingLicenseDataInfoPanelText,
            width: '100%',
            style: {
                borderBottom: '1px solid #a4b5c0 !important',
            },
            hidden: true,
        });

        // Add a container at the top containing the toolbar and hidden info panel
        this.dockedItems = [
            {
                xtype: 'container',
                dock: 'top',
                layout: 'vbox',
                items: [
                    this.missingLicenseDataInfoPanel,
                    {
                        xtype: 'toolbar',
                        width: '100%',
                        ui: 'shopware-ui is--viison-common--toolbar',
                        padding: 8,
                        border: false,
                        items: [
                            this.confirmDevicesButton,
                            {
                                xtype: 'tbspacer',
                                width: 5,
                            },
                            this.deleteDevicesButton,
                            '->',
                            this.reloadListButton,
                        ],
                    },
                ],
            },
        ];

        // Init the row editor
        this.plugins = [
            Ext.create('Ext.grid.plugin.RowEditing', {
                clicksToEdit: 2,
                autoCancel: true,
                listeners: {
                    scope: this,
                    edit: function () {
                        this.fireEvent('saveDevice');
                    },
                },
            }),
        ];

        this.callParent(arguments);
    },

    /**
     * @param String appName The name of the app, for which the respective app support info shall be returned.
     * @return object|null The app support info object that matches the first element of the given rows.
     */
    getAppSupportInfo: function (appName) {
        var appSupportInfo = Ext.Object.getValues(this.appSupportInfo);
        for (var i = 0; i < appSupportInfo.length; i += 1) {
            if (appSupportInfo[i].supportedApps.indexOf(appName) > -1) {
                return appSupportInfo[i];
            }
        }

        return null;
    },

    /**
     * @param Array rows An array of list rows, all belonging to one group, for which the respective app support info
     *        shall be returned.
     * @return object|null The app support info object that matches the first element of the given rows.
     */
    getAppSupportInfoForGroupedRows: function (rows) {
        return (rows.length > 0) ? this.getAppSupportInfo(rows[0].data.appName) : null;
    },

    /**
     * @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';
    },

});
