/*-
 * ~~~~~~licensing~~~~~~
 * entaxy-management-plugin
 * ==========
 * Copyright (C) 2020 - 2021 EmDev LLC
 * ==========
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ~~~~~~/licensing~~~~~~
 */
var Entaxy;
(function (Entaxy) {
    Entaxy._module
    .component('entaxyTable', {
        bindings: {
            itemName: '@',
            folderName: '@',
            statusName: '@',
            objectName: '@'
        },
        template:
        `
          <pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
          <pf-table-view config="$ctrl.tableConfig"
                          columns="$ctrl.tableColumns"
                          action-buttons="$ctrl.tableActionButtons"
                          page-config="$ctrl.pageConfig"
                          items="$ctrl.viewedItems">
          </pf-table-view>
        `,
        controller: EntaxyTableController
    })
    .name;

    function EntaxyTableController(workspace, $location, $uibModal, operationsService, jolokiaService) {
        'ngInject';

        var ctrl = this;
        ctrl.workspace = workspace;
        var entaxyJmxDomain = localStorage['entaxyJmxDomain'] || "ru.entaxy.esb";

        let filterValues = Entaxy.getAllBundleStates();

        ctrl.tableConfig = {
            selectionMatchProp: 'name',
            showCheckboxes: false
        };

        ctrl.toolbarConfig = {
            filterConfig: {
                fields: [
                    {
                        id: 'name',
                        title: 'Name',
                        placeholder: 'Filter by Name...',
                        filterType: 'text'
                    },
                    {
                        id: 'status',
                        title: 'Status',
                        placeholder: 'Filter by Status...',
                        filterType: 'select',
                        filterValues: filterValues
                    }
                ],
//                resultsCount: ctrl.viewedItems ? ctrl.viewedItems.length : 0,
//                totalCount: ctrl.items ? ctrl.items.length : 0,
                appliedFilters: [],
                onFilterChange: filterChange
            },
//            actionsConfig: {
//                primaryActions: [
//                    { name: 'Add ' + ctrl.itemName, actionFn: () => ctrl.showModal() }
//                ]
//            },
            isTableView: true
        };

        ctrl.columnDefs = [
            { field: 'name', displayName: 'Name' },
            { field: 'status', displayName: 'Status' }
        ];

        ctrl.tableColumns = [
            { header: 'Name', itemField: 'name' },
            { header: 'Status', itemField: 'status' }
        ];

//        ctrl.tableActionButtons = [
//            { name: 'Start', title: 'Start ' + ctrl.itemName, actionFn: startItem },
//            { name: 'Stop', title: 'Stop ' + ctrl.itemName, actionFn: stopItem },
////            { name: 'Edit', title: 'Edit ' + ctrl.itemName, actionFn: editItem },
//            { name: 'Uninstall', title: 'Uninstall ' + ctrl.itemName, actionFn: uninstallItem }
//        ];

        ctrl.pageConfig = {
            pageNumber: 1,
            pageSize: 10,
            pageSizeIncrements: [5, 10, 20, 50, 100]
        };

        function filterChange(filters) {
            applyFilters(filters);
            ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
        };

        function applyFilters(filters) {
            ctrl.viewedItems = [];
            if (filters && filters.length > 0) {
                ctrl.items.forEach(function (item) {
                    if (matchesFilters(item, filters)) {
                        ctrl.viewedItems.push(item);
                    }
                });
            } else {
                ctrl.viewedItems = ctrl.items;
            }
        };

        function matchesFilters(item, filters) {
            var matches = true;
            filters.forEach(function(filter) {
                if (!matchesFilter(item, filter)) {
                    matches = false;
                    return false;
                }
            });
            return matches;
        };

        function matchesFilter(item, filter) {
            var match = true;
            if (filter.id === 'name') {
                match = item.name.match(filter.value) !== null;
            } else if (filter.id === 'status') {
                match = item.status === filter.value;
            }
            return match;
        };

        ctrl.items = [];
        ctrl.viewedItems = [];

        ctrl.$onInit = function() {
            populateTable();

            ctrl.toolbarConfig.actionsConfig = {
                primaryActions: [
                    { name: 'Add ' + ctrl.itemName, actionFn: () => ctrl.showModal() }
                ]
            };

            ctrl.tableActionButtons = [
                { name: 'Start', title: 'Start ' + ctrl.itemName, actionFn: startItem },
                { name: 'Stop', title: 'Stop ' + ctrl.itemName, actionFn: stopItem },
//                { name: 'Edit', title: 'Edit ' + ctrl.itemName, actionFn: editItem },
                { name: 'Uninstall', title: 'Uninstall ' + ctrl.itemName, actionFn: uninstallItem }
            ];
        }

        function populateTable() {
            let items = [];
            let count = 0; // FIXME if you can

            let children = workspace.tree.findDescendant(child => child.title === ctrl.folderName).children;
            if (children) {
                children.forEach((child) => {
                    jolokiaService.getAttributes(child.objectName, [ctrl.statusName])
                    .then((response) => {
                        items.push({name: child.title, status: response[ctrl.statusName], mbeanName: child.objectName});
                    });
                    count++; // FIXME
                });

                ctrl.items = items;
                ctrl.viewedItems = items;
                ctrl.toolbarConfig.filterConfig.resultsCount = count; // FIXME
            }
        }

        ctrl.showModal = function() {
            let templates = workspace.tree.findDescendant(child => child.title === 'entaxy.runtime.' + ctrl.itemName.toLowerCase())
            .children.map((child) => {
                let template = {
                    name: child.title,
                    mbeanName: child.objectName
                };
                return template;
            });

            $uibModal.open({
                component: 'entaxyModal',
                resolve: {
                    modalTitle: () => 'Add ' + ctrl.itemName,
                    templates: () => templates
                },
                size: 'xl',
                backdrop: 'static'
            })
            .result.then(args => {
                addItem(args)
            });
        }

        function addItem(args) {
            let objectId = args.fields.find((field) => field.label === 'objectId').value;

            let fields;
            if (objectId) {
                fields = args.fields.filter((field) => field.label !== 'objectId');
            }

            let mbeanName = args.factoryId.mbeanName;
            let properties = fields.reduce((obj, cur) => ({ ...obj, [cur.label] : cur.value }), {});

            operationsService.executeOperation(mbeanName, { name: 'createObject' }, [ objectId, 'public', properties ] )
            .then(result => {
                setTimeout(() => populateTable(), 200);

                let tableHtml = `<table class="entaxy-result-table">`;
                tableHtml +=
                `
                    <tr>
                        <th>Step</th>
                        <th>Step name</th>
                        <th>Step result</th>
                    </tr>
                `;
                _.forEach(JSON.parse(result), (step) => {
                    let iconName = step['Step result'] === 'OK' ? 'ok' : 'error-circle-o';
                    tableHtml += `<tr><td>` + step['Step'] + `</td><td>` + step['Step name'] + `</td>`;
                    tableHtml += `<td><span class="pficon pficon-${iconName}"></span></td></tr>`;
                });
                tableHtml += `</table>`;

                Entaxy.notification('success', tableHtml, 8000);

                changeLocation(properties[ctrl.objectName]);
            }).catch(error => {
                Core.notification('danger', error, 5000);
            });
        }

        function changeLocation(itemName) {
            let currentLocation = $location.search();
            $location.search('nid', currentLocation.nid + '-' + itemName); // FIXME FIXME FIXME
        }

        function startItem(action, item) {
            let mbeanName = workspace.getSelectedMBeanName();

            operationsService.executeOperation(mbeanName, { name: 'start' + ctrl.itemName }, [ item.name ])
                .then(result => {
                    // FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME

                    setTimeout(() => populateTable(), 100);

                    Core.notification('success', result, 3000);
                }).catch(error => {
                    Core.notification('danger', error, 5000);
                });
        }

        function stopItem(action, item) {
            let mbeanName = workspace.getSelectedMBeanName();

            operationsService.executeOperation(mbeanName, { name: 'stop' + ctrl.itemName }, [ item.name ])
                .then(result => {
                    // FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
//                    jolokiaService.getAttribute(item.mbeanName, 'BundleState')
//                        .then((response) => item.status = response);

                    setTimeout(() => populateTable(), 100);

                    Core.notification('success', result, 3000);
                }).catch(error => {
                    Core.notification('danger', error, 5000);
                });
        }

        function uninstallItem(action, item) {
            let mbeanName = workspace.getSelectedMBeanName();

            operationsService.executeOperation(mbeanName, { name: 'uninstall' + ctrl.itemName }, [ item.name ])
            .then(result => {
                ctrl.items.splice(ctrl.items.indexOf(item), 1);
                ctrl.viewedItems = ctrl.items;
                ctrl.toolbarConfig.filterConfig.appliedFilters = [];
                ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;

                Core.notification('success', result, 3000);
            }).catch(error => {
                Core.notification('danger', error, 5000);
            });
        }

        ctrl.dismissAlert = () => ctrl.alert = null;

    }
    EntaxyTableController.$inject = ['workspace', '$location', '$uibModal', 'operationsService', 'jolokiaService'];

})(Entaxy || (Entaxy = {}));