define(['cla_angular'], function(angular)
{
    var app = angular.module("clientsListApp", ['ngResource', 'server-data-module']);

    app.factory('modalService', ['$q', '$compile', '$rootScope', '$controller',
        function($q, $compile, $rootScope, $controller) {
            return {
                open: function(options) {
                    var deferred = $q.defer();
                    var scope = $rootScope.$new();

                    // Resolve dependencies
                    var resolvedData = resolveData(options.resolve);
                    angular.extend(scope, resolvedData);

                    // Get template from DOM
                    var templateElement = document.getElementById(options.templateUrl);
                    if (!templateElement) {
                        deferred.reject('Template not found: ' + options.templateUrl);
                        return { result: deferred.promise };
                    }

                    // Create and configure modal element
                    var modalElement = createModalElement(templateElement.innerHTML);
                    document.body.appendChild(modalElement);

                    // Instantiate controller with resolved data
                    if (options.controller) {
                        instantiateController(options.controller, scope, resolvedData);
                    }

                    // Compile and show modal
                    $compile(modalElement)(scope);
                    var bootstrapModal = new window.bootstrap.Modal(modalElement);
                    bootstrapModal.show();

                    // Setup modal lifecycle handlers
                    setupModalHandlers(modalElement, scope, bootstrapModal, deferred);

                    return { result: deferred.promise };

                    // Helper functions
                    function resolveData(resolveObj) {
                        var resolved = {};
                        if (resolveObj) {
                            angular.forEach(resolveObj, function(fn, key) {
                                resolved[key] = fn();
                            });
                        }
                        return resolved;
                    }

                    function createModalElement(content) {
                        var element = document.createElement('div');
                        element.className = 'modal fade';
                        element.setAttribute('tabindex', '-1');
                        element.setAttribute('role', 'dialog');
                        element.innerHTML = content;
                        return element;
                    }

                    function instantiateController(controllerString, scope, resolvedData) {
                        var parts = controllerString.split(' as ');
                        var controllerName = parts[0];
                        var controllerAlias = parts[1];

                        var locals = angular.extend({$scope: scope}, resolvedData);
                        var instance = $controller(controllerName, locals);

                        if (controllerAlias) {
                            scope[controllerAlias] = instance;
                        }
                    }

                    function setupModalHandlers(element, scope, modal, deferred) {
                        element.addEventListener('hidden.bs.modal', function() {
                            scope.$destroy();
                            document.body.removeChild(element);
                        });

                        scope.$close = function(result) {
                            deferred.resolve(result);
                            modal.hide();
                        };

                        scope.$dismiss = function() {
                            deferred.reject('dismissed');
                            modal.hide();
                        };
                    }
                }
            };
        }
    ]);



    app.controller("clientsListCtrl", clientsListCtrl);
    app.controller('editModalCtrl', editModalCtrl);
    app.controller('createModalCtrl', createModalCtrl);

    clientsListCtrl.$inject = ['modalService', '$resource', 'clientsList'];
    function clientsListCtrl(modalService, $resource, clientsList) {
        var ClientsResource = $resource('/oauth2/admin/client/:id', {'id': '@id'}, {
            'save': { method: 'PUT'},
            'delete': { method: 'DELETE' },
            'reset_secret': { method: 'POST', params: {'reset_secret': 1} },
            'save_new': { method: 'POST' }
        });

        var _this = this;

        this.clients = [];
        for (var i=0; i<clientsList.length; i++) {
            this.clients.push(new ClientsResource(clientsList[i]));
        }

        this.showEditDialog = function (client) {
            var modalInstance = modalService.open({
                templateUrl: 'editDialog.html',
                controller: 'editModalCtrl as dialog',
                resolve: {
                    item: function () {
                        return client;
                    }
                }
            });

            modalInstance.result.then(function (uris) {
                client.redirect_uris = uris;
                client.$save().then(function () {
                    cla.showMessage(lmsg('oauth2.admin.client.saved'), lmsg('oauth2.admin.client.settings_updated'));
                }, _this.onError);
            });
        };

        this.resetSecret = function (client) {
            if (confirm(lmsg('oauth2.admin.reset_secret.confirmation'))) {
                client.$reset_secret().then(function () {
                    cla.showMessage(lmsg('oauth2.admin.client.saved'), lmsg('oauth2.admin.client.secret_reset'));
                }, _this.onError);
            }
        };

        this.deleteClient = function (client) {
            if (confirm(lmsg('common.areyousure'))) {
                var index = _this.clients.indexOf(client);
                client.$delete().then(function () {
                    cla.showMessage(lmsg('oauth2.admin.client.deleted'), lmsg('oauth2.admin.client.deleted'));
                    _this.clients.splice(index, 1);
                }, _this.onError);
            }
        };

        this.createClient = function () {
            var modalInstance = modalService.open({
                templateUrl: 'createDialog.html',
                controller: 'createModalCtrl as dialog'
            });

            modalInstance.result.then(function (client_info) {
                var client = new ClientsResource(client_info);
                client.$save_new().then(function () {
                    _this.clients.push(client);
                    cla.showMessage(lmsg('oauth2.admin.client.saved'), lmsg('oauth2.admin.client.created'));
                });
            }, _this.onError);
        };

        this.onError = function (result) {
            if (typeof result !== 'undefined')
                cla.showMessage(lmsg('oauth2.admin.client.server_error') + ' - ' + result.status, result.data, true);
            else
                cla.showMessage(lmsg('oauth2.admin.client.server_error'));
        };
    }

    editModalCtrl.$inject = ['$scope'];
    function editModalCtrl($scope) {
        this.uris_str = $scope.item.redirect_uris.join("\n");

        var _this = this;

        this.ok = function () {
            var uris_arr = _this.uris_str.length > 0 ? _this.uris_str.split("\n") : [];
            $scope.$close(uris_arr);
        };

        this.cancel = function () {
            $scope.$dismiss();
        };
    }

    createModalCtrl.$inject = ['$scope'];
    function createModalCtrl($scope) {
        this.client = {
            name: '',
            uris_str: ''
        };

        var _this = this;

        this.ok = function () {
            var uris_arr = _this.client.uris_str.length > 0 ? _this.client.uris_str.split("\n") : [];
            var response = {
                name: _this.client.name,
                redirect_uris: uris_arr
            };
            $scope.$close(response);
        };

        this.cancel = function () {
            $scope.$dismiss();
        };
    }

    return null;
});
