/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
/*jshint maxparams: 12 */
angular.module('ballot-boxes', ['app.dialogs'])
    .controller('ballot-boxes', function($scope, $mdDialog, $mdToast, toastCustom,
        sessionService, endpoints, $templateCache, $http, $q, settler,
        CustomDialog, jobqueue, gettextCatalog, $rootScope, ErrorsDict, statusBox, boardActivation,
        activeFilters, configElectionConstants, _) {

        'use strict';

        var privateKeyBase64 = null;
        var electoralAuthorityId; 

        $scope.isCollapsed = false;

        // manage status filters
        $scope.filterItem = 'ballotBoxes';
        $scope.filterTabs = [
            configElectionConstants.STATUS_LOCKED,
            configElectionConstants.STATUS_READY,
            configElectionConstants.STATUS_SIGNED,
            configElectionConstants.STATUS_MIXED,
            configElectionConstants.STATUS_BB_DOWNLOADED,
            configElectionConstants.STATUS_DECRYPTED,
            configElectionConstants.STATUS_TALLIED
        ];
        $scope.onTabSelected = function(filter) {
            $scope.filterActive = filter.text;
            $scope.tableFilter = filter.code;
            activeFilters.setActiveFilter($scope.filterItem, filter);
            $scope.typeCount = $scope.countTestInFilterActive(filter);
            $scope.unselectAll();
        };

        // manage test filter
        $scope.filterBBTest = 'ballotBoxesTest';
        $scope.filterTestTabs = [
            configElectionConstants.TEST_REGULAR,
            configElectionConstants.TEST_TEST
        ];
        $scope.onTestSelected = function(filter) {
            $scope.filterActiveTest = filter.text;
            $scope.tableFilterTest = filter.code;
            activeFilters.setActiveFilter($scope.filterBBTest, filter);
            $scope.typeCount = $scope.countTestInFilterActive(activeFilters.getActiveFilter($scope.filterItem));
            $scope.unselectAll();
        };
        $scope.parseFilterActiveTest = function(filter) {
            let value;
            filter === 'Test' ? value = 'true' : value = 'false';
            return value;
        };
        $scope.countTestInFilterActive = function(filter) {
            let testStatus = {};
            testStatus.false = _.filter($scope.ballotBoxes.result, { 'status': filter.code, 'test': 'false' }).length;
            testStatus.true = _.filter($scope.ballotBoxes.result, { 'status': filter.code, 'test': 'true' }).length;
            return testStatus;
        };

        // init status filter
        if (!activeFilters.getActiveFilter($scope.filterItem)) {
            activeFilters.setActiveFilter($scope.filterItem, $scope.filterTabs[0]);
        }
        $scope.filterActive = (activeFilters.getActiveFilter($scope.filterItem)).text;
        $scope.tableFilter = (activeFilters.getActiveFilter($scope.filterItem)).code;

        // init test filter
        if (!activeFilters.getActiveFilter($scope.filterBBTest)) {
            activeFilters.setActiveFilter($scope.filterBBTest, $scope.filterTestTabs[0]);
        }
        $scope.filterActiveTest = (activeFilters.getActiveFilter($scope.filterBBTest)).text;
        $scope.tableFilterTest = (activeFilters.getActiveFilter($scope.filterBBTest)).code;

        $scope.selectBallotBoxText = '';

        $scope.progress = function(id) {
            return jobqueue.getJobStatus(id);
        };
        $scope.batches = function(types) {
            return jobqueue.getBatches(types);
        };
        $scope.batchesTotals = function(types) {
            return jobqueue.getBatchesTotals(types);
        };

        var updateView = _.debounce(function() {
            $rootScope.$broadcast('refresh-ballot-boxes');
        }, 3000);

        var updateDecryptingProgress = function(alias) {
            updateView();
        };


        $scope.listBallotBoxes = function() {

            $scope.errors.ballotBoxesFailed = false;
            $scope.errors.getElectoralAuthoritiesFailed = false;

            var ballotBoxesURL = endpoints.host + endpoints.ballotboxes
                .replace('{electionEventId}', $scope.selectedElectionEventId);
            $http.get(ballotBoxesURL)
                .success(function(data) {
                    try {
                        sessionService.setBallotBoxes(data);
                        $scope.ballotBoxes = data;
                        $scope.statusCount = _.countBy(data.result, 'status');
                        $scope.typeCount = $scope.countTestInFilterActive(activeFilters.getActiveFilter($scope.filterItem));
                    } catch (e) {
                        $scope.data.message = e.message;
                        $scope.errors.ballotBoxesFailed = true;
                        $scope.statusCount = null;
                        $scope.typeCount = null;
                    }
                })
                .error(function() {
                    $scope.errors.ballotBoxesFailed = true;
                    $scope.statusCount = null;
                    $scope.typeCount = null;
                });


            var electoralAuthoritiesURL = endpoints.host + endpoints.electoralAuthorities
                .replace('{electionEventId}', $scope.selectedElectionEventId);

            $http.get(electoralAuthoritiesURL)
                .success(function(data) {
                    try {
                        $scope.electoralAuthorities = data.result;
                        sessionService.setElectoralAuthorities(data.result);
                    } catch (e) {
                        $scope.data.message = e.message;
                        $scope.errors.getElectoralAuthoritiesFailed = true;
                    }
                })
                .error(function() {
                    $scope.errors.getElectoralAuthoritiesFailed = true;
                });
        };


        // download ballotBox(es)
        // -------------------------------------------------------------

        var showBallotBoxDownloadError = function() {
            new CustomDialog()
                .title(gettextCatalog.getString('Ballot box download'))
                .error()
                .show();
        };

        $scope.downloadBallotBox = function(ev) {

            $scope.errors.ballotBoxDownloadError = false;

            // collect ballot box to download

            var ballotBoxesToDownload = [];
            var ballotBoxesSelected = [];
            $scope.ballotBoxes.result.forEach(function(ballotBox) {
                if (ballotBox.selected && ballotBox.status === 'MIXED') {
                    ballotBoxesToDownload.push(ballotBox);
                } else if (ballotBox.selected && ballotBox.status === 'SIGNED' &&
                    ballotBox.synchronized === 'true' && ballotBox.test === 'true') {
                    ballotBoxesToDownload.push(ballotBox);
                }
                if (ballotBox.selected) {
                    ballotBoxesSelected.push(ballotBox);
                }
            });

            // no selection?

            if (ballotBoxesSelected.length <= 0) {
                $mdDialog.show(
                    $mdDialog.customAlert({
                        locals: {
                            title: gettextCatalog.getString('Ballot box download'),
                            content: gettextCatalog.getString('Please, select some ballot box(es) to be download from the list')
                        }
                    })
                );
                return;
            }

            if (ballotBoxesToDownload.length <= 0) {
                new CustomDialog()
                    .title(gettextCatalog.getString('Ballot box download'))
                    .cannotPerform(gettextCatalog.getString('Ballot Box(es)'))
                    .show();
                return;
            }

            // download individual ballot box

            $scope.ballotBoxDownloadResults = [];
            $scope.ballotBoxDownloadError = false;

            $q.allSettled(ballotBoxesToDownload.map(function(ballotBox) {
                var url = (endpoints.host + endpoints.ballotbox)
                    .replace('{electionEventId}', $scope.selectedElectionEventId)
                    .replace('{ballotBoxId}', ballotBox.id);
                return $http.post(url);
            })).then(

                function(responses) {

                    var settled = settler.settle(responses);
                    if (settled.ok) {
                        $scope.ballotBoxDownloadResults = settled.fulfilled.map(function(response) {
                            return (response.data.result);
                        });
                        if (!$scope.checkOkBecauseExtraFastClick(settled.fulfilled)) {
                            $mdToast.show(
                                toastCustom.topCenter(gettextCatalog.getString('Ballot box(es) downloaded!'), 'success')
                            );
                        }
                    }
                    if (settled.error) {
                        $scope.errors.ballotBoxDownloadError = true;
                        showBallotBoxDownloadError(ev);
                    }
                    $scope.listBallotBoxes();
                    $scope.unselectAll();

                });
        };

        $scope.unselectAll = function() {
            $scope.selectAll = false;
            $scope.ballotBoxes.result.forEach(function(ballotBox) {
                ballotBox.selected = false;
            });
        };

        $scope.onSelectAll = function(value) {
            $scope.ballotBoxes.result.forEach(function(ballotBox) {
                const status = activeFilters.getActiveFilter($scope.filterItem).code;
                const test = activeFilters.getActiveFilter($scope.filterBBTest).code;
                if (ballotBox.status === status && ballotBox.test === test) {
                    ballotBox.selected = value;
                }
                
            });
        };

        $scope.updateSelectAll = function(value) {
            if (!value) {
                $scope.selectAll = false;
            }
        };


        $scope.$on('refresh-ballot-boxes', function() {
            $scope.listBallotBoxes();
        });

        // Recover electoral authority private key
        function activateElectoralAuthorityThruDialog(electoralAuthorityId) {
            boardActivation.init('electoralAuthorities', electoralAuthorityId);
            boardActivation.electoralBoardActivate($scope.selectedElectionEventId)
                .then( 
                    function(response){ 
                        if(response && response.data && response.data.error != ''){
                            $mdToast.show(
                                toastCustom.topCenter(gettextCatalog.getString('The Electoral Authority could not be activated'), 'error')
                            );
                        }else{
                            boardActivation.openBoardElectoralAuthority()
                                .then(
                                    function(success){
                                        $scope.decrypt();
                                    }
                                );
                        }
                    }
                );
        }

        $scope.decrypt = function() {

            // collect ballot boxes to decrypt
            var boxesToDecrypt = [];
            var boxesSelected = [];

            $scope.ballotBoxes.result.forEach(function(ballotBox) {
                if (ballotBox.selected && ballotBox.status === 'BB_DOWNLOADED') {
                    boxesToDecrypt.push(ballotBox);
                }
                if (ballotBox.selected) {
                    boxesSelected.push(ballotBox);
                }
            });

            // no selection?

            if (boxesSelected.length <= 0) {
                $mdDialog.show(
                    $mdDialog.customAlert({
                        locals: {
                            title: gettextCatalog.getString('Ballot Box decrypting'),
                            content: gettextCatalog.getString('Please, select some ballot boxes to decrypt from the list')
                        }
                    })
                );
                return;
            }

            if (boxesToDecrypt.length <= 0) {
                new CustomDialog()
                    .title(gettextCatalog.getString('Ballot Box decrypting'))
                    .cannotPerform(gettextCatalog.getString('Ballot Box(es)'))
                    .show();
                return;
            }

            // all from the same authority?

            electoralAuthorityId = boxesToDecrypt[0].electoralAuthority.id;
            var same = true;
            boxesToDecrypt.forEach(function(ballotBox) {

                same = same && (ballotBox.electoralAuthority.id === electoralAuthorityId);

            });
            if (!same) {
                $mdDialog.show(
                    $mdDialog.customAlert({
                        locals: {
                            title: gettextCatalog.getString('Ballot Box decrypting'),
                            content: gettextCatalog.getString('Please, select ballot boxes for a single electoral authority')
                        }
                    })
                );
                return;
            }


            privateKeyBase64 = null;


            if (sessionService.getSelectedAdminBoard()) {
                privateKeyBase64 = sessionService.getSelectedAdminBoard().privateKey;
            }

            if (!$scope.isAdminAuthorityActivated() || !privateKeyBase64) {
                var p = $mdDialog.show(
                    $mdDialog.customConfirm({
                        locals: {
                            title: gettextCatalog.getString('Ballot Box decrypting'),
                            content: gettextCatalog.getString('Please, activate the administration board.'),
                            ok: gettextCatalog.getString('Activate now')
                        }
                    })
                );
                p.then(function (success) {
                    boardActivation.init('adminBoard');
                    boardActivation.adminBoardActivate()
                        .then(
                            function(response){
                                if(response && response.data && response.data.error != ''){
                                    $mdToast.show(
                                        toastCustom.topCenter(gettextCatalog.getString('The Administration Board could not be activated'), 'error')
                                    );
                                }else{
                                    boardActivation.openBoardAdmin()
                                        .then(
                                            function(success){
                                                checkElectoralAuthority();
                                            }
                                        );
                                }
                            }
                        );
                },
                function (error){
                    //Not possible to open the $mdDialog
                });
                return;

            } else {
                if (!$scope.isElectoralAuthorityActivated()){
                    var activateElectoralAuthorityDialogPromise = activateElectoralAuthorityThruDialog(electoralAuthorityId);
                } else {
                    checkElectoralAuthority();
                }
            }

            function checkElectoralAuthority(){

                $scope.selectedAuthority = boardActivation.getSelectedAuthority();
                privateKeyBase64 = sessionService.getSelectedAdminBoard().privateKey;

                var electoralAuthorityPrivateKey = null;
                if (sessionService.getSelectedElectoralAuthority()) {
                    electoralAuthorityPrivateKey = sessionService.getSelectedElectoralAuthority().privateKey;
                    sessionService.expireAfter('eb', $scope.selectedAuthority);
                }

                if (electoralAuthorityPrivateKey) {
                    // unleash mixing!
                    // unleash decrypting!

                    $q.allSettled(boxesToDecrypt.map(
                        function(ballotBox) {
                            var url = endpoints.host + endpoints.mixing
                                .replace('{electionEventId}', $scope.selectedElectionEventId)
                                .replace('{ballotBoxId}', ballotBox.id);
                            var body = {
                                serializedPrivateKey: electoralAuthorityPrivateKey,
                                privateKeyPEM: privateKeyBase64
                            };
                            return $http.post(url, body);
                        })).then(function(responses) {

                        var settled = settler.settle(responses);
                        if (settled.ok) {
                            if (!$scope.checkOkBecauseExtraFastClick(settled.fulfilled)) {
                                $mdToast.show(
                                    toastCustom.topCenter(gettextCatalog.getString('Decrypting complete!'), 'success')
                                );
                            }
                        }
                        if (settled.error) {
                            new CustomDialog()
                                .title(gettextCatalog.getString('Ballot Box decrypting'))
                                .error()
                                .show();
                        }
                        $scope.listBallotBoxes();
                    });

                    $mdToast.show(
                        toastCustom.topCenter(gettextCatalog.getString('Decrypting started'), 'success')
                    );
                    $scope.unselectAll();


                } else {
                    var activateElectoralAuthorityDialogPromise = activateElectoralAuthorityThruDialog(electoralAuthorityId);
                }
            }

        };
        

        // tally
        // -------------------------------------------------------------

        $scope.tally = function() {

            if (!$scope.isAdminAuthorityActivated()) {
                var p = $mdDialog.show(
                    $mdDialog.customConfirm({
                        locals: {
                            title: gettextCatalog.getString('Ballot Box tallying'),
                            content: gettextCatalog.getString('Please, activate the administration board.'),
                            ok: gettextCatalog.getString('Activate now')
                        }
                    })
                );
                p.then(function (success) {
                    boardActivation.init('adminBoard');
                    boardActivation.adminBoardActivate()
                        .then( 
                            function(response){ 
                                if(response && response.data && response.data.error != ''){
                                    $mdToast.show(
                                        toastCustom.topCenter(gettextCatalog.getString('The Administration Board could not be activated'), 'error')
                                    );
                                }else{
                                    boardActivation.openBoardAdmin()
                                        .then(
                                            function(success){
                                                $scope.tally();
                                            }
                                        );
                                }
                            }
                        );
                },
                function (error){
                    //Not possible to open the $mdDialog
                });
                return;
            }

            // collect ballot boxes to tally

            var boxesToCount = [];
            var boxesSelected = [];
            $scope.ballotBoxes.result.forEach(function(ballotBox) {
                if (ballotBox.selected && ballotBox.status === 'DECRYPTED') {
                    boxesToCount.push(ballotBox);
                }
                if (ballotBox.selected) {
                    boxesSelected.push(ballotBox);
                }
            });

            // no selection?

            if (boxesSelected.length <= 0) {
                $mdDialog.show(
                    $mdDialog.customAlert({
                        locals: {
                            title: gettextCatalog.getString('Ballot Box tallying'),
                            content: gettextCatalog.getString('Please, select some ballot boxes to tally from the list')
                        }
                    })
                );
                return;
            }

            if (boxesToCount.length <= 0) {
                new CustomDialog()
                    .title(gettextCatalog.getString('Ballot Box tallying'))
                    .cannotPerform(gettextCatalog.getString('Ballot Box(es)'))
                    .show();
                return;
            }

            // unleash tally!

            $q.allSettled(boxesToCount.map(
                function(ballotBox) {
                    var url = endpoints.host + endpoints.tallying
                        .replace('{electionEventId}', $scope.selectedElectionEventId)
                        .replace('{ballotBoxId}', ballotBox.id);

                    privateKeyBase64 = null;
                    if (sessionService.getSelectedAdminBoard()) {
                        privateKeyBase64 = sessionService.getSelectedAdminBoard().privateKey;
                    }
                    var body = {
                        privateKeyPEM: privateKeyBase64
                    };

                    if (!privateKeyBase64) {
                        $mdDialog.show(
                            $mdDialog.customAlert({
                                locals: {
                                    title: gettextCatalog.getString('Ballot Box tallying'),
                                    content: gettextCatalog.getString('Please, activate the administration board')
                                }
                            })
                        );
                        return $q.reject('Administration board not activated or expired');
                    } else {
                        return $http.post(url, body);
                    }

                })).then(function(responses) {

                var settled = settler.settle(responses);
                if (settled.ok) {
                    if (!$scope.checkOkBecauseExtraFastClick(settled.fulfilled)) {
                        $mdToast.show(
                            toastCustom.topCenter(gettextCatalog.getString('Tallying complete!'), 'success')
                        );
                    }
                }
                if (settled.error) {
                    new CustomDialog()
                        .title(gettextCatalog.getString('Ballot Box tallying'))
                        .error()
                        .show();
                }
                $scope.listBallotBoxes();

                // Forget that key!
                // $rootScope.safeApply(function() {
                //     if ($scope.selectedAuthority) {
                //         $scope.selectedAuthority.privateKey = undefined;
                //     }
                //     if (sessionService.getSelectedAdminBoard()) {
                //         sessionService.getSelectedAdminBoard().privateKey = undefined;
                //     }
                // });
            }

            );

            $scope.unselectAll();


        };


        $scope.viewTallySheet = function(balloBoxId, status) {


            // get ballot to display
            $scope.tallySheetToDisplay = [];

            if (status !== 'TALLYED') {
                $mdDialog.show(
                    $mdDialog.customAlert({
                        locals: {
                            title: gettextCatalog.getString('View Tally Sheet'),
                            content: gettextCatalog.getString('The selected Ballot Box has not been tallyed yet')
                        }
                    })
                );
                return;
            }

            // collect corresponding tally sheet
            var url = (endpoints.host + endpoints.tallysheetCSV)
                .replace('{electionEventId}', $scope.selectedElectionEventId)
                .replace('{ballotBoxId}', balloBoxId);

            window.location.href = url;

        };

        function capitalizeWord(string) {
            var lowerCaseString = string.toLowerCase();
            return lowerCaseString.charAt(0).toUpperCase() + lowerCaseString.slice(1);
        }

        $scope.capitalizeFirstLetter = function(string) {
            var words = string.split('_');
            var out = [];
            angular.forEach(words, function(word) {
                out.push(capitalizeWord(word));
            });
            return out.join(' ');
        };

        $scope.isAdminAuthorityActivated = function() {
            var adminBoard = sessionService.getSelectedAdminBoard();
            if (!adminBoard) {
                return false;
            }
            return sessionService.getSelectedAdminBoard().privateKey;
        };

        $scope.isElectoralAuthorityActivated = function() {
            var electoralBoard = sessionService.getSelectedElectoralAuthority();
            if (!electoralBoard) {
                return false;
            }
            return sessionService.getSelectedElectoralAuthority().privateKey;
        };

        var showSigningError = function() {
            new CustomDialog()
                .title(gettextCatalog.getString('Ballot box signing'))
                .error()
                .show();
        };

        $scope.sign = function() {

            var ballotBoxesToSign = [];
            var ballotBoxesSelected = [];
            $scope.ballotBoxes.result.forEach(function(bb) {

                if (bb.selected && bb.status === 'READY') {
                    ballotBoxesToSign.push(bb);
                }
                if (bb.selected) {
                    ballotBoxesSelected.push(bb);
                }
            });

            if (ballotBoxesSelected.length <= 0) {
                $mdDialog.show(
                    $mdDialog.customAlert({
                        locals: {
                            title: gettextCatalog.getString('Ballot Box signing'),
                            content: gettextCatalog.getString('Please, select a ballot box to sign from the list')
                        }
                    })
                );
                return;
            }

            if (ballotBoxesToSign.length <= 0) {
                new CustomDialog()
                    .title(gettextCatalog.getString('Ballot box signing'))
                    .cannotPerform(gettextCatalog.getString('Ballot Box(es)'))
                    .show();
                return;
            }

            if (!$scope.isAdminAuthorityActivated()) {
                var p = $mdDialog.show(
                    $mdDialog.customConfirm({
                        locals: {
                            title: gettextCatalog.getString('Ballot Box signing'),
                            content: gettextCatalog.getString('Please, activate the administration board.'),
                            ok: gettextCatalog.getString('Activate now')
                        }
                    })
                );
                p.then(function (success) {
                    boardActivation.init('adminBoard');
                    boardActivation.adminBoardActivate()
                        .then( 
                            function(response){ 
                                if(response && response.data && response.data.error != ''){
                                    $mdToast.show(
                                        toastCustom.topCenter(gettextCatalog.getString('The Administration Board could not be activated'), 'error')
                                    );
                                }else{
                                    boardActivation.openBoardAdmin()
                                        .then(
                                            function(success){
                                                $scope.sign();
                                            }
                                        );
                                }
                            }
                        );
                },
                function (error){
                    //Not possible to open the $mdDialog
                });
                return;
            }

            privateKeyBase64 = sessionService.getSelectedAdminBoard().privateKey;

            $q.allSettled(ballotBoxesToSign.map(function(bb) {

                var url = (endpoints.host + endpoints.ballotBoxSign)
                    .replace('{electionEventId}', $scope.selectedElectionEventId)
                    .replace('{ballotBoxId}', bb.id);

                var body = {
                    privateKeyPEM: privateKeyBase64
                };

                return $http.put(url, body);

            })).then(function(responses) {

                var settled = settler.settle(responses);
                $scope.ballotBoxesResults = settled.fulfilled;

                if (settled.ok) {
                    $mdToast.show(
                        toastCustom.topCenter(gettextCatalog.getString('Ballot box(es) signed!'), 'success')
                    );
                    $scope.listBallotBoxes();
                }
                if (settled.error) {
                    showSigningError();
                }

            });

            $scope.unselectAll();

        };

        $scope.isThereNoBallotBoxSelected = function() {

            var generatedBallotBoxSelected = false;

            if ($scope.ballotBoxes) {
                $scope.ballotBoxes.result.forEach(function(bb) {
                    if (bb.selected) {
                        generatedBallotBoxSelected = true;
                    }
                });
            }

            return !generatedBallotBoxSelected;
        };

        $scope.getTextByBallotBoxSelected = function() {
            var selectBallotBoxText = gettextCatalog.
                getString('Please select first a Ballot box');
            var check = $scope.isThereNoBallotBoxSelected();
            return check ? selectBallotBoxText : '';
        };


        /**
         * Check if the responses might be ok because a extra fast double click in  an action
         * @param responses
         * @returns {boolean}
         */
        $scope.checkOkBecauseExtraFastClick = function(responses) {

            responses.forEach(function(r) {
                if (r.idle) {
                    return true;
                }
            });
            return false;
        };

        /*
            ballot test get descriptiontext
         */
        $scope.getBallotBoxTypeDesc = function(val) {

            var ballotBoxTestDesc = gettextCatalog.getString('Test');
            var ballotBoxRegularDesc = gettextCatalog.getString('Regular');
            return val === 'true' ? ballotBoxTestDesc : ballotBoxRegularDesc;
        };

        $scope.tallyingEnabled = function() {
            return sessionService.isTallyingEnabled();
        };
        
        $scope.generatePostVotingOutputsEnabled = function() {
            return sessionService.isGeneratePostVotingOutputsEnabled();
        };

        $scope.generatePostVotingOutputs = function () {

            function internalRequest(privateKeyBase64) {
                var url = endpoints.host + endpoints.generatePostVotingOutputs
                    .replace('{electionEventId}', $scope.selectedElectionEventId)
                    .replace('{bbStatus}', boxesSelected[0].status.toLowerCase());
                var body = {
                    privateKeyInBase64: privateKeyBase64
                };

                $http.post(url, body)
                    .then(function (res) {
                        $mdToast.show(
                            toastCustom.topCenter(gettextCatalog.getString('Custom files generated successfully'), 'success')
                        );
                    })
                    .catch(function (e) {
                        if(e.data.error=='4005') {
                            $mdDialog.show(
                                $mdDialog.customAlert({
                                    locals: {
                                        title: gettextCatalog.getString('Custom files'),
                                        content: gettextCatalog.getString(ErrorsDict(e.data.error))
                                    }
                                })
                            );
                        } else {
                            $mdToast.show(
                                toastCustom.topCenter(
                                    gettextCatalog.getString('Custom files') + ': ' +
                                    gettextCatalog.getString('Something went wrong. Contact with Support') + '. ' +
                                    gettextCatalog.getString('Error code') + ': ' + e.data.error + ', ' +
                                    gettextCatalog.getString(ErrorsDict(e.data.error)),
                                    'error'
                                )
                            );
                        }
                    });
            }

            privateKeyBase64 = null;
            if (sessionService.getSelectedAdminBoard()) {
                privateKeyBase64 = sessionService.getSelectedAdminBoard().privateKey;
            }

            if (!$scope.isAdminAuthorityActivated() || !privateKeyBase64) {
                var p = $mdDialog.show(
                    $mdDialog.customConfirm({
                        locals: {
                            title: gettextCatalog.getString('Custom files'),
                            content: gettextCatalog.getString('Please, activate the administration board.'),
                            ok: gettextCatalog.getString('Activate now')
                        }
                    })
                );
                p.then(function (success) {
                    boardActivation.init('adminBoard');
                    boardActivation.adminBoardActivate()
                        .then( 
                            function(response){ 
                                if(response && response.data && response.data.error != ''){
                                    $mdToast.show(
                                        toastCustom.topCenter(gettextCatalog.getString('The Administration Board could not be activated'), 'error')
                                    );
                                }else{
                                    boardActivation.openBoardAdmin()
                                        .then(
                                            function(success){
                                                $scope.generatePostVotingOutputs();
                                            }
                                        );
                                }
                            }
                        );
                },
                function (error){
                    //Not possible to open the $mdDialog
                });
                return;
            }

            var boxesSelected = _.filter($scope.ballotBoxes.result, 'selected');
            console.log(boxesSelected);
            var sameStatusBB = _.uniq(boxesSelected, function(bb){ return bb.status; }).length === 1;

            if (!sameStatusBB) {
                new CustomDialog()
                    .title(gettextCatalog.getString('All the ballot boxes to be processed must have the same status'))
                    .show();
                return;
            }

            var statusSelected = boxesSelected[0].status;

            var boxesWithStatus = _.filter($scope.ballotBoxes.result, {status: statusSelected});

            if (boxesWithStatus.length > boxesSelected.length) {
                var p = $mdDialog.show(
                    $mdDialog.customConfirm({
                        locals: {
                            title: gettextCatalog.getString('Custom files'),
                            content: gettextCatalog.getString('Please note that all ballot boxes with the same status as the selected ones will be processed'),
                            ok: gettextCatalog.getString('Generate')
                        }
                    })
                );
                p.then(function () {
                    internalRequest(privateKeyBase64);
                });
            } else {
                internalRequest(privateKeyBase64);
            }
        };

        $scope.isThereNoBBSelectedWithAppropiateStatus = function () {
            if ($scope.ballotBoxes) {
                var boxesSelected = _.filter($scope.ballotBoxes.result, 'selected');
                if (boxesSelected.length === 0) {
                    return true;
                }
                for (var i = 0; i < boxesSelected.length; ++i) {
                    if (boxesSelected[i].status === 'LOCKED' ||
                        boxesSelected[i].status === 'READY' ||
                        boxesSelected[i].status === 'SIGNED' || 
                        boxesSelected[i].status === 'CLOSED') {
                        return true;
                    }
                }
            }

            return false;
        };

        //initialize && populate view
        // -------------------------------------------------------------

        $scope.alert = '';
        $scope.errors = {};
        $scope.selectedElectionEventId = sessionService.getSelectedElectionEvent().id;
        $scope.electoralAuthorities = [];
        $scope.listBallotBoxes();
        $scope.statusBox = statusBox;

    });
