/*-
 * ~~~~~~licensing~~~~~~
 * entaxy-management-plugin
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
var Entaxy;
(function (Entaxy) {
    Entaxy._module.component('entaxyResourceViewerModal', {
        bindings: {
            modalInstance: '<',
            resolve: '<'
        },
        template:
        `
          <div class="entaxy-modal-container">
            <div class="modal-header">
              <button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
                <span class="pficon pficon-close" aria-hidden="true"></span>
              </button>
              <h4 class="modal-title">{{$ctrl.modalTitle}}</h4>
            </div>
              <div class="modal-body-without-header" ng-class="{'entaxy-resource-save-mode': $ctrl.saveMode}">
                <div class="modal-resources-viewer-container">
                  <div class="modal-resources-viewer-header-container">
                    <div class="provider-selector" ng-if="$ctrl.providers">
                      <span>Provider:</span>
                      <select class="form-control" ng-options="provider for provider in $ctrl.providers"
                            ng-model="$ctrl.newProtocol" ng-change="$ctrl.onProviderSelectionChange()" />
                    </div>
                    <div class="navigation-creation">
                      <entaxy-crumbs root-crumb="$ctrl.protocol" crumbs="$ctrl.crumbs"></entaxy-crumbs>
                      <button type="button" data-toggle="tooltip" title="Create folder"
                              ng-click="$ctrl.addFolder()" ng-if="$ctrl.folderAddingEnabled">
                        <span class="pficon pficon-add-circle-o"></span>
                      </button>
                    </div>
                  </div>
                  <entaxy-file-panel items="$ctrl.items" selected-items="$ctrl.selectedItems" view="$ctrl.view"
                        change-selection-fn="$ctrl.changeSelection" open-fn="$ctrl.open"></entaxy-file-panel>
                </div>
              </div>
              <div class="modal-footer"
                   ng-class="{'has-error': $ctrl.error, 'entaxy-resource-save-mode': $ctrl.saveMode}">
                <div class="entaxy-resource-save-mode-labelled-field-container" ng-if="$ctrl.saveMode">
                  <label class="control-label">Name</label>
                  <div class="entaxy-resource-save-mode-field-container">
                    <entaxy-input-with-extension model="$ctrl.name" set-focused="true"
                            model-without-extension="$ctrl.nameWithoutExtension" extension="$ctrl.extension">
                    </entaxy-input-with-extension>
                    <span class="help-block" ng-if="$ctrl.error">
                      {{$ctrl.error}}
                    </span>
                  </div>
                </div>
                <button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">{{$ctrl.btnTitle}}</button>
              </div>
          </div>
        `,
        controller: entaxyResourceViewerModalController
    })
    .name;

    function entaxyResourceViewerModalController($uibModal, $scope, hotkeys, entaxyHotkeysService,
                                                 entaxyResourcesService, entaxyService) {
        'ngInject';

        let ctrl = this;

        ctrl.$onInit = function() {
            ctrl.saveMode = ctrl.resolve.config.saveMode;
            ctrl.btnTitle = ctrl.saveMode ? 'Save' : 'Select';
            ctrl.modalTitle = ctrl.saveMode ? 'Save Resource' : 'Select Resources';

            if (ctrl.saveMode) {
                entaxyHotkeysService.setHotkeys($scope, getHotkeysConfigs());
            } else {
                hotkeys.pause();
            }

            ctrl.view = 'tiles';
            ctrl.protocol = ctrl.resolve.config.resourceProvider;
            setProviderMbeanName();

            if (ctrl.resolve.config.providersSelectionEnabled) {
                ctrl.newProtocol = ctrl.protocol;
                populateProviders();
            }

            ctrl.filter = ctrl.resolve.config.filter;

            ctrl.folderSelectionEnabled = ctrl.resolve.config.folderSelectionEnabled;
            ctrl.folderAddingEnabled = ctrl.resolve.config.folderAddingEnabled;
            ctrl.multipleSelectionEnabled = ctrl.resolve.config.multipleSelectionEnabled;

            if (ctrl.saveMode) {
                ctrl.extension = ctrl.filter.slice(1);
            }

            let location = ctrl.resolve.location;
            ctrl.useShortUrl = ctrl.resolve.config.useShortUrl;

            if (location && location.includes(':')) {
                let path = ctrl.useShortUrl ? location.split(':')[1] : location.slice(18);
                if (path.length > 0) {
                    let splitPath = path.split('/');
                    if (!ctrl.useShortUrl) {
                        splitPath.shift();
                    }
                    if (ctrl.saveMode) {
                        let lastPathItem = splitPath[splitPath.length - 1];
                        if (lastPathItem.endsWith(ctrl.extension)) {
                            ctrl.nameWithoutExtension = lastPathItem
                                .substring(0, lastPathItem.lastIndexOf(ctrl.extension));
                            splitPath.pop();
                        }
                    }
                    if (!ctrl.folderSelectionEnabled) {
                        splitPath.pop();
                    }
                    // todo else check if the last item in path is folder or not
                    ctrl.crumbs = splitPath;
                } else {
                    ctrl.crumbs = [];
                }
            } else {
                ctrl.crumbs = [];
            }
        }

        function populateProviders() {
            entaxyResourcesService.getProviders()
            .then(result => {
                ctrl.providers = JSON.parse(result);
            })
            .catch(error => {
                Entaxy.log.error(error);
                Entaxy.notificationError(error)
            });
        }

        function setProviderMbeanName() {
            let provider = entaxyResourcesService.getProviderMbean(ctrl.protocol);
            ctrl.providerMBeanName = provider.objectName;
        }

        ctrl.providerCrumbsCache = {};

        ctrl.onProviderSelectionChange = function () {
            ctrl.providerCrumbsCache[ctrl.protocol] = ctrl.crumbs;
            let forceUpdate = entaxyResourcesService.getPath(ctrl.providerCrumbsCache[ctrl.protocol]) ===
                entaxyResourcesService.getPath(ctrl.providerCrumbsCache[ctrl.newProtocol]);
            ctrl.protocol = ctrl.newProtocol;
            setProviderMbeanName();
            ctrl.crumbs = ctrl.providerCrumbsCache[ctrl.newProtocol] ? ctrl.providerCrumbsCache[ctrl.newProtocol] : [];
            if (forceUpdate) {
                onCrumbsUpdated();
            }
        }

        $scope.$watchCollection('$ctrl.crumbs', function(newValue, oldValue) {
            onCrumbsUpdated();
        });

        function onCrumbsUpdated() {
            ctrl.selectedItems = [];
            updateItems();
        }

        $scope.$watch('$ctrl.name', function () {
            if (ctrl.saveMode && ctrl.selectedItems.length == 1 && ctrl.name !== ctrl.selectedItems[0].name) {
                ctrl.selectedItems = [];
            }
        });

        ctrl.changeSelection = function (item, isMultiple) {
            if (!item.error) {
                if (!isMultiple) {
                    ctrl.selectedItems = [ item ];
                    if (ctrl.saveMode && !item.isFolder) {
                        ctrl.nameWithoutExtension = item.name.substring(0, item.name.lastIndexOf(ctrl.extension));
                    }
                } else {
                    if (ctrl.multipleSelectionEnabled && ctrl.selectedItems && ctrl.selectedItems.length > 0) {
                        if (ctrl.selectedItems.includes(item)) {
                            ctrl.selectedItems = ctrl.selectedItems.filter(it => it.name !== item.name);
                        } else {
                            ctrl.selectedItems.push(item);
                        }
                    } else {
                        ctrl.selectedItems = [ item ];
                    }
                }
            } else {
                Entaxy.notificationError('Cannot select the resource containing an error');
            }
        }

        ctrl.open = function (item) {
            if (item.isFolder === true) {
                ctrl.crumbs.push(item.name);
            } else {
                ctrl.changeSelection(item);
                if (!item.error) {
                    ctrl.save();
                }
            }
        }

        let clientFolders = [];

        ctrl.addFolder = function () {
            entaxyResourcesService.addFolder(ctrl.items, clientFolders, ctrl.crumbs);
        }

        function updateItems() {
            let path = entaxyResourcesService.getPath(ctrl.crumbs);

            getItems(path).then(originItems => {

                if (ctrl.folderAddingEnabled && ctrl.crumbs.length > 0 &&
                        originItems.length == 0 && clientFolders.length == 0) {
                    populateAddedFoldersFromLocation(ctrl.crumbs);
                }

                let items = originItems
                    .concat(entaxyResourcesService.getClientFoldersToAdd(clientFolders, originItems, ctrl.crumbs));

                if (ctrl.filter === 'foldersOnly') {
                    items = items.filter(item => item.isFolder);
                } else if (Array.isArray(ctrl.filter) && ctrl.filter.length > 0) {
                    items = items.filter(item => {
                        let match = false;
                        if (item.isFolder) {
                            return true;
                        }
                        ctrl.filter.forEach(filter => {
                            if (filter.startsWith('*') && item.name.endsWith(filter.substring(1, filter.length))) {
                                match = true;
                            }
                        });
                        return match;
                    });
                } else if (ctrl.filter && ctrl.filter.startsWith('*')) {
                    items = items.filter(item => item.isFolder || item.name.endsWith(ctrl.filter.substring(1, ctrl.filter.length)));
                }
                ctrl.items = items.sort(Entaxy.compareBy('name')).sort((a, b) => b.isFolder - a.isFolder);
            })
        }

        function populateAddedFoldersFromLocation(originCrumbs) {
            let crumbs = Entaxy.deepCopy(originCrumbs);

            if (crumbs.length > 0) {
                let lastFolderName = crumbs.pop();
                let path = entaxyResourcesService.getPath(crumbs);

                getItems(path).then(result => {
                    let items = JSON.parse(result);

                    if (items.length == 0) {
                        let addedFolder = entaxyResourcesService.createFolder(lastFolderName, crumbs);
                        clientFolders.push(addedFolder);
                        populateAddedFoldersFromLocation(crumbs);
                    } else {
                        if (!items.map(item => item.name).includes(lastFolderName)) {
                            let addedFolder = entaxyResourcesService.createFolder(lastFolderName, crumbs);
                            clientFolders.push(addedFolder);
                        }
                    }
                });
            }
        }

        function getItems(path) {
            return entaxyResourcesService.getResourcesInfo(ctrl.providerMBeanName, path);
        }

        ctrl.cancel = function(reason) {
            ctrl.modalInstance.dismiss(reason);
        }

        ctrl.save = function() {
            if (ctrl.saveMode) {
                if (ctrl.items.find(item => item.name === ctrl.name)) {
                    let title = 'Confirm Saving';
                    let message = 'Resource with name ' + ctrl.name + ' already exists.' +
                        ' Do you want to replace it?';
                    entaxyService.openConfirmationWindow(title, message).then(() => {
                        save();
                    });
                } else {
                    save();
                }
            } else {
                save();
            }
        }

        function save() {
            if (!validate()) {
                return;
            }
            if (ctrl.selectedItems && ctrl.selectedItems.length > 0) {
                let locations = [];
                ctrl.selectedItems.forEach(selectedItem => {
                    if (!selectedItem.isFolder || ctrl.folderSelectionEnabled) {
                        let path = entaxyResourcesService.getPath(ctrl.crumbs);
                        let folderLocation = getFolderLocation(path);
                        let separator = path.length > 0 ? '/' : '';
                        let location = folderLocation + separator + selectedItem.name;
                        locations.push(location);
                    }
                });
                if (locations.length > 0) {
                    ctrl.modalInstance.close(ctrl.multipleSelectionEnabled ? locations : locations[0]);
                }
            } else {
                if (ctrl.folderSelectionEnabled) {
                    let path = entaxyResourcesService.getPath(ctrl.crumbs);
                    let folderLocation = getFolderLocation(path);
                    if (ctrl.saveMode) {
                        if (!folderLocation.endsWith(ctrl.extension)) {
                            folderLocation += '/' + ctrl.name;
                        }
                    }
                    ctrl.modalInstance.close(ctrl.multipleSelectionEnabled ? [ folderLocation ] : folderLocation);
                } else {
                    Entaxy.notificationError('There is no selected resource');
                }
            }
        }

        function getFolderLocation(path) {
            return ctrl.useShortUrl ? ctrl.protocol + ':' + path : 'entaxy-resource://' + ctrl.protocol + '/' + path;
        }

        function validate() {
            ctrl.error = undefined;
            if (ctrl.saveMode) {
                if (!ctrl.nameWithoutExtension || ctrl.nameWithoutExtension.trim().length == 0) {
                    ctrl.error = Entaxy.ERROR_MESSAGE.EMPTY;
                }
                if (!ctrl.error) {
                    ['/', '\\', ':', '*', '?', '<', '>', '|'].forEach((symbol) => {
                        if (ctrl.nameWithoutExtension.indexOf(symbol) >= 0) {
                            ctrl.error = 'Must not include symbols /\\:*?<>|';
                        }
                    });
                }
            }
            return ctrl.error ? false : true;
        }

        $scope.$on('$destroy', function() {
            if (!ctrl.saveMode) {
                hotkeys.unpause();
            }
        });

        function getHotkeysConfigs() {
            return [
                {
                    ...Entaxy.getSaveHotkeyDescription(),
                    callback: function (event) {
                        event.preventDefault();
                        ctrl.save();
                    }
                }
            ];
        }
    }
    entaxyResourceViewerModalController.$inject = ['$uibModal', '$scope', 'hotkeys', 'entaxyHotkeysService',
        'entaxyResourcesService', 'entaxyService'];

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