backupApp.directive('backupEditStepOne', function (gettextCatalog) {
    return {
        restrict: 'E',
        scope: {
            backup: '=backup',
            options: '=options',
            setBuilduriFn: '&',
            isValid: '=',
            sshKeyFile: '=sshKeyFile',
        },
        templateUrl: 'templates/backups/edit/step1.html?v=1.1.1.2',
        controller: function ($scope, $routeParams, AppService, AppUtils, BackupConnectionService, BackupService, SystemInfo, EditUriBackendConfig, DialogService) {

            const scope = $scope;
            scope.AppUtils = AppUtils;

            scope.isEditMode = $routeParams.backupid !== undefined;
            scope.isServerPathVerified = scope.isEditMode;
            scope.ServerConfig = { Backend: null };
            
            scope.RepeatPasshrase = '';
            scope.PasswordStrength = 'unknown';

            let validatedPath = '';

            $scope.changeConfiguration = function () {
                $scope.isServerPathVerified = false;
            }

            $scope.testConnection = async function () {
                if ($scope.ServerConfig.Path == '') return;

                scope.Testing = true;

                const opts = {};
                EditUriBackendConfig.merge_in_advanced_options(scope.ServerConfig, opts);
                if ($scope.sshKeyFile)
                {
                    opts['ssh-keyfile'] = $scope.sshKeyFile;
                }

                const serverConfig = new ServerConfig(
                    scope.ServerConfig.Backend.Key,
                    scope.ServerConfig.Server,
                    scope.ServerConfig.Port,
                    (scope.ServerConfig.folderPathPrefix || '') + (scope.ServerConfig.Path || ''),
                    AppUtils.encodeDictAsUrl(opts),
                    (scope.ServerConfig.SupportsSSL && scope.ServerConfig.UseSSL),
                )
                try {
                    const ensureFolder = validatedPath == '' || validatedPath != scope.ServerConfig.Path;
                    const res = await BackupConnectionService.performConnectionTest(serverConfig, $routeParams.backupid, ensureFolder);

                    if(res) {
                        scope.backup.TargetURL = res;
                        reparseuri();
                        $scope.isServerPathVerified = true;
                    }
                }finally {
                    scope.Testing = false;

                }
            };

            $scope.contains_value = AppUtils.contains_value;

            $scope.$watch('ServerConfig.Backend', function () {
                if (scope.ServerConfig.Backend == null) {
                    $scope.TemplateUrl = null;
                    $scope.AdvanceOptionList = null;
                    return;
                }

                var opts = angular.copy(scope.ServerConfig.Backend.Options || []);
                for (var n in opts)
                    opts[n].Category = scope.ServerConfig.Backend.DisplayName;

                for (var m in SystemInfo.state.ConnectionModules) {
                    var t = angular.copy(SystemInfo.state.ConnectionModules[m].Options);
                    for (var n in t)
                        t[n].Category = SystemInfo.state.ConnectionModules[m].DisplayName;
                    opts.push.apply(opts, t);
                }

                $scope.AdvanceOptionList = opts;
                scope.SupportsSSL = false;
                for (var n in scope.ServerConfig.Backend.Options)
                    if (scope.ServerConfig.Backend.Options[n].Name == 'use-ssl')
                        scope.SupportsSSL = true;

                scope.TemplateUrl = EditUriBackendConfig.templates[scope.ServerConfig.Backend.Key];
                if (scope.TemplateUrl == null)
                    scope.TemplateUrl = EditUriBackendConfig.defaulttemplate;

                if (EditUriBackendConfig.loaders[scope.ServerConfig.Backend.Key] == null)
                    return;

                EditUriBackendConfig.loaders[scope.ServerConfig.Backend.Key](scope);
            });

            const reparseuri = function () {

                if (!scope.backup)
                {
                    return;
                }

                scope.ServerConfig = BackupService.reparseuri(scope.backup.TargetURL, scope.backup.TargetFolderPathPrefix, scope.DefaultBackend, scope.SystemInfo.GroupedBackendModules);
                validatedPath = scope.ServerConfig.Path;
            };

            $scope.SystemInfo = SystemInfo.watch($scope, function () {
                for (var n in scope.SystemInfo.GroupedBackendModules)
                    if (scope.SystemInfo.GroupedBackendModules[n].Key == EditUriBackendConfig.defaultbackend)
                        scope.DefaultBackend = scope.SystemInfo.GroupedBackendModules[n];

                reparseuri();
            });
            $scope.$watch('backup.TargetURL', reparseuri);



            function computePassPhraseStrength() {

                const strengthMap = {
                    'x': gettextCatalog.getString("Passphrases do not match"),
                    0: gettextCatalog.getString("Useless"),
                    1: gettextCatalog.getString("Very weak"),
                    2: gettextCatalog.getString("Weak"),
                    3: gettextCatalog.getString("Strong"),
                    4: gettextCatalog.getString("Very strong")
                };

                const passphrase = scope.options == null ? '' : scope.options['passphrase'] ?? '';

                if (scope.RepeatPasshrase != passphrase)
                    scope.PassphraseScore = 'x';
                else if ((passphrase || '') == '')
                    scope.PassphraseScore = '';
                else
                    scope.PassphraseScore = (zxcvbn(passphrase.substring(0, 100)) || { 'score': -1 }).score;

                scope.PassphraseScoreString = strengthMap[scope.PassphraseScore];
                isStep1Valid();
            }

            function isStep1Valid() {
                scope.isValid = scope.backup?.Name !== undefined
                    && scope.backup?.Name != ''
                    && scope.options
                    // && scope.RepeatPasshrase == (scope.options['passphrase'] ?? '')
                    && scope.isServerPathVerified
                    ;
            }

            

            $scope.generatePassphrase = function () {
                this.Options["passphrase"] = this.RepeatPasshrase = AppUtils.generatePassphrase();
                this.ShowPassphrase = true;
                this.HasGeneratedPassphrase = true;
            };

            $scope.togglePassphraseVisibility = function () {
                this.ShowPassphrase = !this.ShowPassphrase;
            };

            $scope.setBuilduriFn({ builduriFn: (callback => BackupConnectionService.buildUri(scope.ServerConfig, callback)) });


            $scope.$watch('options["passphrase"]', () => {
                if(scope.RepeatPasshrase === '' && scope.options != undefined)
                {
                    scope.RepeatPasshrase = scope.options["passphrase"];
                }
                computePassPhraseStrength();
                isStep1Valid();
            });
            $scope.$watch('RepeatPasshrase', computePassPhraseStrength);
            $scope.$watch('backup.Name', isStep1Valid);
            $scope.$watch('isServerPathVerified', isStep1Valid);
        }
    };
});
