/*
 * 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 */

function DialogController($scope, $mdDialog) {
    'use strict';
    $scope.hide = function() {
        $mdDialog.hide();
    };
    $scope.cancel = function() {
        $mdDialog.cancel();
    };
    $scope.answer = function(answer) {
        $mdDialog.hide(answer);
    };
}

angular.module('ballots', [])
    .controller('ballots', function($scope, $rootScope, $mdDialog, $mdToast,
        sessionService, endpoints, $http, $q, _, settler, CustomDialog, gettextCatalog, ballotprinter, toastCustom, boardActivation) {
        'use strict';

        $scope.selectBallotText = function() {
            return gettextCatalog.
                getString('Please select first a Ballot');
        };
        $scope.listBallots = function() {

            $scope.errors.getBallotsFailed = false;

            var url = endpoints.host + endpoints.ballots.replace('{electionEventId}', $scope.selectedElectionEventId);
            $http.get(url)
                .success(function(data) {
                    $rootScope.safeApply(function() {
                        $scope.ballots = data;
                    });
                })
                .error(function() {
                    $scope.errors.getBallotsFailed = true;
                });
        };

        var showBallots = function(ev) {
            $mdDialog.show({
                controller: DialogController,
                templateUrl: 'app/views/dialogs/dialog-view-ballot.html',
                parent: angular.element(document.body),
                targetEvent: ev,
                scope: $scope,
                clickOutsideToClose: true,
                escapeToClose: true,
                preserveScope: true
            })
                .then(function() {
                    //
                });
        };

        $scope.viewBallot = function(ballotId, ev) {

            // get ballot to display

            $scope.ballotsToView = [];
            $scope.ballots.result.forEach(function(ballot) {
                if (ballot.id === ballotId) {
                    $scope.ballotsToView.push(ballot);
                }
            });

            // no selection?

            if ($scope.ballotsToView.length <= 0) {
                $mdDialog.show(
                    $mdDialog.customAlert({
                        locals: {
                            title: gettextCatalog.getString('View ballot(s)'),
                            content: gettextCatalog.getString('Please, select some ballots to view from the list.')
                        }
                    })
                );
                return;
            }

            // collect corresponding ballot texts

            $q.allSettled($scope.ballotsToView.map(function(ballot) {
                var url = (endpoints.host + endpoints.ballottexts)
                    .replace('{electionEventId}', $scope.selectedElectionEventId)
                    .replace('{ballotId}', ballot.id);
                return $http.get(url);
            })).then(function(responses) {

                var settled = settler.settle(responses);
                $scope.ballotTextsToView = settled.fulfilled.map(function(response) {
                    return (response.data.result);
                });

                // show the stuff

                ballotprinter.print($scope.ballotsToView);
                showBallots(ev);

            });


        };

        $scope.getBallotTexts = function(ballotid) {
            return _.find($scope.ballotTextsToView, function(text) {
                return ballotid === text[0]['ballot']['id'];
            });
        };

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

        var showBallotApprovalError = function() {
            $mdDialog.show(
                $mdDialog.customAlert({
                    locals: {
                        title: gettextCatalog.getString('Ballot signing'),
                        content: gettextCatalog.getString('Some ballot(s) could not be signed. Please review the list')
                    }
                })
            );
        };

        $scope.sign = function(ev) {

            $scope.errors.ballotApprovalError = false;

            var ballotsToSign = [];
            var ballotsSelected = [];            
            $scope.ballots.result.forEach(function(ballot) {
                if (ballot.selected && ballot.status === 'LOCKED') {
                    ballotsToSign.push(ballot);
                }
                if (ballot.selected) {
                    ballotsSelected.push(ballot);
                }
            });

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

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

            if (!$scope.isAdminAuthorityActivated()) {
                var p = $mdDialog.show(
                    $mdDialog.customConfirm({
                        locals: {
                            title: gettextCatalog.getString('Ballot 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;
            }else{
                var electionEvent = sessionService.getSelectedElectionEvent();
                if (!sessionService.doesActivatedABBelongToSelectedEE()) {
                    $mdDialog.show(
                        $mdDialog.customAlert({
                            locals: {
                                title: gettextCatalog.getString('Wrong Administration Board activated'),
                                content: gettextCatalog.getString('The active Administration Board does not belong to the Election Event that you are trying to operate. Please deactivate it and activate the corresponding Administration Board for the Election Event') +' '+ electionEvent.defaultTitle + '.'
                            }
                        })
                    );
                    return;
                }
            }

            $scope.ballotApprovalResults = [];
            $scope.ballotApprovalError = false;
            var privateKeyBase64 = sessionService.getSelectedAdminBoard().privateKey;

            $q.allSettled(ballotsToSign.map(function(ballot) {

                var url = (endpoints.host + endpoints.ballotSign)
                    .replace('{electionEventId}', $scope.selectedElectionEventId)
                    .replace('{ballotId}', ballot.id);

                var body = {
                    privateKeyPEM: privateKeyBase64
                };

                return $http.put(url, body);

            })).then(function(responses) {

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

                if (settled.ok) {
                    $mdToast.show(
                        toastCustom.topCenter(gettextCatalog.getString('Ballot(s) signed!'), 'success')
                    );
                    $scope.listBallots();
                }
                if (settled.error) {
                    showBallotApprovalError(ev);
                }

            });

            $scope.unselectAll();
        };

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

        $scope.onSelectAll = function(value) {
            $scope.ballots.result.forEach(function(ballot) {
                ballot.selected = value;
            });
        };

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

        $scope.$on('refresh-ballots', function() {
            $scope.listBallots();
        });

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

        $scope.isThereNoBallotSelected = function() {

            var noBallotSelected = true;

            if ($scope.ballots) {
                $scope.ballots.result.forEach(function(ballot) {
                    if (ballot.selected) {
                        noBallotSelected = false;
                    }
                });
            }

            return noBallotSelected;
        };


        $scope.getTextIsBallotSelected = function() {

            var check = $scope.isThereNoBallotSelected();
            return check ? $scope.selectBallotText() : '';
        };

        //initialize && populate view
        // -------------------------------------------------------------
        $scope.alert = '';
        $scope.errors = {};
        $scope.selectedElectionEventId = sessionService.getSelectedElectionEvent().id;
        $scope.listBallots();

    });
