backupApp.controller('SystemSettingsController', function($rootScope, $scope, $route, $cookies, AppService, DialogService, AppUtils, SystemInfo, gettextCatalog) {

    $scope.SystemInfo = SystemInfo.watch($scope, () => {
        // Avoid a race when the system info is loaded after obtaining the settings
        if (($scope.timezone ?? '').trim().length == 0)
            $scope.timezone = $scope.SystemInfo.ServerTimeZone;
    });    
    $scope.theme = $scope.$parent.$parent.saved_theme;
    if (($scope.theme || '').trim().length == 0)
        $scope.theme = 'default';

    $scope.usageReporterLevel = '';
    $scope.remoteControlState = 'unknown';

    function reloadOptionsList() {
        $scope.advancedOptionList = AppUtils.buildOptionList($scope.SystemInfo, false, false, false);
        var mods = [];
        if ($scope.SystemInfo.ServerModules != null)
            for(var ix in $scope.SystemInfo.ServerModules)
            {
                var m = $scope.SystemInfo.ServerModules[ix];
                if (m.SupportedGlobalCommands != null && m.SupportedGlobalCommands.length > 0)
                    mods.push(m);
            }

        $scope.ServerModules = mods;
        $scope.remoteControlRegisterUrl = $scope.SystemInfo.RemoteControlRegistrationUrl;
        AppUtils.extractServerModuleOptions($scope.advancedOptions, $scope.ServerModules, $scope.servermodulesettings, 'SupportedGlobalCommands');
    };

    reloadOptionsList();
    $scope.$on('systeminfochanged', reloadOptionsList);

    $scope.$watch('theme', function() {
        $rootScope.$broadcast('preview_theme', { theme: $scope.theme });
    });

    $scope.uiLanguage = $cookies.get('ui-locale');
    $scope.lang_browser_default = gettextCatalog.getString('Browser default');
    $scope.lang_default = gettextCatalog.getString('Default');    

    function setUILanguage() {
        if (($scope.uiLanguage || '').trim().length == 0) {
            $cookies.remove('ui-locale');
            gettextCatalog.setCurrentLanguage($scope.SystemInfo.BrowserLocale.Code.replace("-", "_"));
        } else {
            var now = new Date();
            var exp = new Date(now.getFullYear()+10, now.getMonth(), now.getDate());
            $cookies.put('ui-locale', $scope.uiLanguage, { expires: exp });

            gettextCatalog.setCurrentLanguage($scope.uiLanguage.replace("-", "_"));
        }
        $rootScope.$broadcast('ui_language_changed');
    };

    AppService.get('/serversettings').then(function(data) {

        $scope.rawdata = data.data;

        $scope.requireRemotePassword = data.data['server-passphrase'] != null && data.data['server-passphrase'] != '';
        $scope.remotePassword = data.data['server-passphrase'];
        $scope.confirmPassword = '';
        $scope.allowRemoteAccess = data.data['server-listen-interface'] != 'loopback';
        $scope.startupDelayDurationValue = data.data['startup-delay'].substr(0, data.data['startup-delay'].length - 1) == "" ? "0" : data.data['startup-delay'].substr(0, data.data['startup-delay'].length - 1);
        $scope.startupDelayDurationMultiplier = data.data['startup-delay'].substr(-1) == "" ? "s" : data.data['startup-delay'].substr(-1);
        $scope.updateChannel = data.data['update-channel'];
        $scope.originalUpdateChannel = data.data['update-channel'];
        $scope.usageReporterLevel = data.data['usage-reporter-level'];
        $scope.disableTrayIconLogin =  AppUtils.parseBoolString(data.data['disable-tray-icon-login']);
        $scope.remoteHostnames = data.data['allowed-hostnames'];
        $scope.timezone = data.data['server-timezone'];
        if (($scope.timezone ?? '').trim().length == 0)
            $scope.timezone = $scope.SystemInfo.ServerTimeZone;
        $scope.advancedOptions = AppUtils.serializeAdvancedOptionsToArray(data.data);
        $scope.servermodulesettings = {};
        $scope.autogeneratedPassphrase = data.data['autogenerated-passphrase'] == 'True';

        AppUtils.extractServerModuleOptions($scope.advancedOptions, $scope.ServerModules, $scope.servermodulesettings, 'SupportedGlobalCommands');
        
    }, AppUtils.connectionError);


    $scope.repeatRegisterTimer = null;

    function mapRemoteControlStatus(data) {
        $scope.remoteControlEnabled = data.IsEnabled;
        $scope.remoteControlCanEnable = data.CanEnable;
        $scope.remoteControlConnected = data.IsConnected;
        $scope.remoteControlIsRegistering = data.IsRegistering;
        $scope.remoteControlIsRegisteringFaulted = data.IsRegisteringFaulted;
        $scope.remoteControlIsRegisteringCompleted = data.IsRegisteringCompleted; 
        $scope.remoteControlClaimUrl = data.RegistrationUrl ?? '';

        if (data.IsConnected)
            $scope.remoteControlState = 'connected';
        else if (data.IsEnabled)
            $scope.remoteControlState = 'enabled';
        else if (data.CanEnable)
            $scope.remoteControlState = 'disabled';
        else if (data.IsRegisteringFaulted)
            $scope.remoteControlState = 'registeringfaulted';
        else if (data.IsRegistering)
        {
            if (data.RegistrationUrl != null && data.RegistrationUrl.trim().length > 0)
                $scope.remoteControlState = 'registered';
            else
                $scope.remoteControlState = 'registering';
        }
        else
            $scope.remoteControlState = 'inactive';
        
        // Stop any existing timer
        if ($scope.repeatRegisterTimer != null)
        {
            clearTimeout($scope.repeatRegisterTimer);
            $scope.repeatRegisterTimer = null;
        }

        // If we are registering, we need to keep checking until the registration is claimed
        if ($scope.remoteControlState == 'registering' )
        {
            $scope.repeatRegisterTimer = setTimeout(function() {
                AppService.post('/remotecontrol/register', { RegistrationUrl: "" }).then(function(data) {
                    mapRemoteControlStatus(data.data);
                }, () => { 
                    AppService.get('/remotecontrol/status').then(function(data) {
                            mapRemoteControlStatus(data.data);
                    }, () => { });             
                });
            }, 5000);
        }

        // If we are enabled, poll to see if we become connected
        // If we are registered, poll to see if we become disabled
        if ($scope.remoteControlState == 'enabled' || $scope.remoteControlState == 'registered')
        {
            $scope.repeatRegisterTimer = setTimeout(function() {
                AppService.get('/remotecontrol/status').then(function(data) {
                        mapRemoteControlStatus(data.data);
                }, () => { });             
            }, 5000);
        }

        // If we can enable and are registering, there must be a lingering registration
        if (data.IsRegistering && data.CanEnable) {
            AppService.delete('/remotecontrol/register').then(function(data) {
                mapRemoteControlStatus(data.data);
            }, () => { });
        }
    }

    function mapRemoteControlError(data) {
        AppUtils.connectionError(data);

        AppService.get('/remotecontrol/status').then(function(data) {
            mapRemoteControlStatus(data.data);
        }, () => { });
       
    }

    $scope.refreshRemoteControlStatus = function() {
        AppService.get('/remotecontrol/status').then(function(data) {
            mapRemoteControlStatus(data.data);
        }, mapRemoteControlError);
    }

    $scope.beginRemoteRegistration = function() {
        $scope.remoteControlState = 'registering';

        AppService.post('/remotecontrol/register', { RegistrationUrl: $scope.remoteControlRegisterUrl }).then(function(data) {
            mapRemoteControlStatus(data.data);
        }, mapRemoteControlError);
    }

    $scope.cancelRemoteRegistration = function() {
        AppService.delete('/remotecontrol/register').then(function(data) {
            mapRemoteControlStatus(data.data);
        }, mapRemoteControlError);
    }

    $scope.enableRemoteControl = function() {
        AppService.post('/remotecontrol/enable').then(function(data) {
            mapRemoteControlStatus(data.data);
        }, mapRemoteControlError);
    }

    $scope.disableRemoteControl = function() {
        AppService.post('/remotecontrol/disable').then(function(data) {
            mapRemoteControlStatus(data.data);
        }, mapRemoteControlError);
    }

    $scope.deleteRemoteControl = function() {
        DialogService.confirm(gettextCatalog.getString('Are you sure you want to delete the remote control registration?'), function(ix) {
            if (ix == 0)
                return;            
            AppService.delete('/remotecontrol/registration').then(function(data) {
                mapRemoteControlStatus(data.data);
            }, mapRemoteControlError);
        });
    }

    $scope.getRemoteControlStatusText = function() {
        if ($scope.remoteControlState == 'enabled')
            return gettextCatalog.getString('Remote control is enabled but not connected');
        if ($scope.remoteControlState == 'connected')
            return gettextCatalog.getString('Remote control is connected');
        if ($scope.remoteControlState == 'registering')
            return gettextCatalog.getString('Registering machine...');
        if ($scope.remoteControlState == 'registeringfaulted')
            return gettextCatalog.getString('Registration failed');
        if ($scope.remoteControlState == 'registered')
            return gettextCatalog.getString('Registered, waiting for accept');
        if ($scope.remoteControlState == 'disabled')
            return gettextCatalog.getString('Remote control is configured but not enabled');
        if ($scope.remoteControlState == 'unknown')
            return gettextCatalog.getString('...loading...');

        return gettextCatalog.getString('Remote control is not set up');
    }

    $scope.refreshRemoteControlStatus();

    $scope.save = function() {

        if ($scope.changeServerPassword && $scope.remotePassword.trim().length == 0)
            return AppUtils.notifyInputError('Cannot use empty password');

        var patchdata = {
            'server-passphrase': $scope.changeServerPassword ? $scope.remotePassword : '',
            'allowed-hostnames': $scope.remoteHostnames,
            'server-listen-interface': $scope.allowRemoteAccess ? 'any' : 'loopback',
            'startup-delay': $scope.startupDelayDurationValue + '' + $scope.startupDelayDurationMultiplier,
            'update-channel': $scope.updateChannel,
            'usage-reporter-level': $scope.usageReporterLevel,
            'disable-tray-icon-login': $scope.disableTrayIconLogin,
            'server-timezone': $scope.timezone
        };

        if ($scope.changeServerPassword && $scope.rawdata['server-passphrase'] != $scope.remotePassword) {
            if ($scope.remotePassword != $scope.confirmPassword) {
                AppUtils.notifyInputError(gettextCatalog.getString('The passwords do not match'));
                return;
            }
        }

        AppUtils.mergeAdvancedOptions($scope.advancedOptions, patchdata, $scope.rawdata);
        for(var n in $scope.servermodulesettings)
            patchdata['--' + n] = $scope.servermodulesettings[n];

        $rootScope.$broadcast('update_theme', { theme: $scope.theme } );

        AppService.patch('/serversettings', patchdata, {headers: {'Content-Type': 'application/json; charset=utf-8'}}).then(
            function() {
                setUILanguage();

                // Check for updates if we changed the channel
                if ($scope.updateChannel != $scope.originalUpdateChannel)
                    AppService.post('/updates/check');

                $route.reload();
            },
            AppUtils.connectionError(gettextCatalog.getString('Failed to save:') + ' ')
        );
    };
});
