define('bitbucket/internal/feature/ssh/keys/access/delete-dialog', [
    'aui',
    'jquery',
    'lodash',
    'bitbucket/internal/feature/ssh/keys/access/common',
    'bitbucket/internal/util/ajax',
    'bitbucket/internal/util/object',
    'bitbucket/internal/widget/paged-table',
    'exports'
], function(
    AJS,
    $,
    _,
    keyAccessCommon,
    ajax,
    obj,
    PagedTable,
    exports
) {

    'use strict';

    var containsKeyAccess = keyAccessCommon.containsKeyAccess;

    function DeleteDialog(currentKeyAccess, restUrlBuilder, alreadyDeletedRestHandler, deletionCallback) {
        this.currentKeyAccess = currentKeyAccess;
        this.restUrlBuilder = restUrlBuilder;
        this.deletionCallback = deletionCallback;
        this.alreadyDeletedRestHandler = alreadyDeletedRestHandler;
    }

    DeleteDialog.prototype.wireDialogButtons = function(onConfirm) {
        var self = this;

        this.dialog.$el.find('.confirm-button').on('click', onConfirm);

        this.dialog.$el.find('.cancel-button').on('click', function () {
            self.dialog.hide();
        });
    };

    DeleteDialog.prototype.show = function() {
        this.dialog.show();
    };

    DeleteDialog.prototype.hide = function() {
        this.dialog.hide();
    };

    function DeleteSingleAccessDialog(currentKeyAccess, restUrlBuilder, alreadyDeletedRestHandler, deletionCallback) {
        DeleteDialog.call(this, currentKeyAccess, restUrlBuilder, alreadyDeletedRestHandler, deletionCallback);

        var self = this;
        var dialogContents = self.currentKeyAccess.repository ?
            bitbucket.internal.feature.ssh.keys.access.deleteSingleDialogOnRepoPage({ currentKeyAccess: self.currentKeyAccess }) :
            bitbucket.internal.feature.ssh.keys.access.deleteSingleDialogOnProjectPage({ currentKeyAccess: self.currentKeyAccess });

        this.dialog = AJS.dialog2(dialogContents);
        this.wireDialogButtons(function() {
            ajax.rest(_.extend({
                    url: self.restUrlBuilder.addPathComponents(currentKeyAccess.key.id).build(),
                    type: 'DELETE'
                }, self.alreadyDeletedRestHandler)).done(self.deletionCallback).always(function() {
                self.dialog.hide();
            });
        });
    }
    obj.inherits(DeleteSingleAccessDialog, DeleteDialog);

    function DeleteMultipleAccessesDialog(currentKeyAccess, pageProvider, restUrlBuilder,
                                          alreadyDeletedRestHandler, deletionHandler) {
        DeleteDialog.call(this, currentKeyAccess, restUrlBuilder, alreadyDeletedRestHandler, deletionHandler);

        this.pageProvider = pageProvider;

        var self = this;

        var dialogContents = currentKeyAccess.repository ?
            bitbucket.internal.feature.ssh.keys.access.deleteMultipleDialogOnRepoPage({ currentKeyAccess: currentKeyAccess }) :
            bitbucket.internal.feature.ssh.keys.access.deleteMultipleDialogOnProjectPage({ currentKeyAccess: currentKeyAccess });

        this.dialog = AJS.dialog2(dialogContents);
        this.wireDialogButtons(function() {
            var builder = self.restUrlBuilder.addPathComponents(currentKeyAccess.key.id);
            var selectedKeyAccesses = self.getSelectedKeyAccesses();
            var $spinner = $('<div class="spinner"></div>');
            var $confirmButton = $(this).before($spinner);

            $spinner.spin();

            ajax.rest(_.extend({
                    url: builder.build(),
                    type: 'DELETE',
                    data: selectedKeyAccesses
                }, self.alreadyDeletedRestHandler)).done(function() {

                    if (containsKeyAccess(selectedKeyAccesses, currentKeyAccess)) {
                        self.deletionCallback.call();
                    }
                }).always(function() {
                    $spinner.spinStop();
                    self.dialog.hide();
                });
        });
    }
    obj.inherits(DeleteMultipleAccessesDialog, DeleteDialog);

    DeleteMultipleAccessesDialog.prototype.show = function() {
        this.dialog.show();

        new KeyAccessTable(this.pageProvider).init();
    };

    DeleteMultipleAccessesDialog.prototype.getSelectedKeyAccesses = function() {
        var $checkedResourceEl = $('input.checkbox:checked', this.dialog.$el)
            .parent()
            .find('label > span.repository-item, label > span.project-item');
        var toJson = function(el) {
            var $el = $(el);
            return JSON.parse(
                $el.hasClass('repository-item') ? $el.attr('data-repository') : $el.attr('data-project'));
        };
        return $.extend({ projects: [], repositories: [] }, _.groupBy(_.map($checkedResourceEl, toJson), function(resource) {
            return resource.slug ? 'repositories' : 'projects';
        }));
    };

    function KeyAccessTable(pageProvider, options) {
        this.pageProvider = pageProvider;

        var defaults = {
            bufferPixels: 50,
            pageSize: 25,
            spinnerSize : 'small',
            target: '.key-access-resources-table',
            scrollPaneSelector: '#delete-key-access-dialog',
            tableMessageClass: 'key-access-resources-message'
        };

        options = $.extend({}, defaults, options);
        PagedTable.call(this, options);
    }

    obj.inherits(KeyAccessTable, PagedTable);

    KeyAccessTable.prototype.performAjax = function(start, limit) {
        return this.pageProvider.fetch(start, limit);
    };

    KeyAccessTable.prototype.handleNewRows = function(data, attachmentMethod) {
        var html = bitbucket.internal.feature.ssh.keys.access.resourceRows({ keyAccesses: data.values });
        this.$table.children('tbody')[attachmentMethod](html);
    };

    exports.showForSingleKeyAccess = function(currentKeyAccess, deleteRestBuilder, alreadyDeletedHandler, deletionHandler) {
        var dialog = new DeleteSingleAccessDialog(currentKeyAccess, deleteRestBuilder, alreadyDeletedHandler, deletionHandler);
        dialog.show();
    };

    exports.showForMultipleKeyAccesses = function (currentKeyAccess, pageProvider, deletionRestBuilder,
                                                   alreadyDeletedHandler, deletionHandler) {
        var dialog = new DeleteMultipleAccessesDialog(currentKeyAccess, pageProvider, deletionRestBuilder,
            alreadyDeletedHandler, deletionHandler);
        dialog.show();
    };
});