define('bitbucket/internal/importer/repository-list', [
    'jquery',
    'bitbucket/util/server',
    'bitbucket/internal/util/object',
    'bitbucket/internal/widget/error-dialog',
    'bitbucket/internal/widget/paged-scrollable'
], function(
    $,
    server,
    obj,
    ErrorDialog,
    PagedScrollable
) {

    /**
     *
     * @param {HTMLElement|jQuery|string} scrollPaneSelector
     * @param {Object} options
     * @param {Function} options.urlBuilder
     * @param {Function} options.rowChangeHandler - a callback to call when the value of a row has changed
     * @constructor
     */
    function ImporterRepositoryList(scrollPaneSelector, options) {
        this._$container = $(scrollPaneSelector);
        this.dataLoadedEvent = 'bitbucket.internal.importer.repository.list.dataLoaded';
        this.urlBuilder = options.urlBuilder;

        this._$spinner = $('<div class="spinner"/>').insertAfter(this._$container);

        PagedScrollable.call(this, scrollPaneSelector, $.extend({
            //  We use a large pageSize here because this service makes calls to external providers on the backend.
            //  i.e. we make a request to the server and the server makes a request to a third-party.
            //  This indirection means that there is a compounded latency and requesting more items means fewer calls
            //  and thus faster perceived performance for the end user.
            pageSize: 50,
            dataLoadedEvent: this.dataLoadedEvent,
            autoLoad: 'next',
            paginationContext: 'repository-import-list'
        }, options));

        this._$container.on('change', 'input', this.rowChanged.bind(this));
    }

    obj.inherits(ImporterRepositoryList, PagedScrollable);

    /**
     *
     * @param {Event} e
     * @this {ImporterRepositoryList}
     */
    ImporterRepositoryList.prototype.rowChanged = function(e) {
        // toggle the focus
        $(e.target).closest('li').toggleClass('focused', e.target.checked);
        // call the rowChanged handler
        if (this.options.rowChangeHandler) {
            this.options.rowChangeHandler(e.target);
        }
    };

    ImporterRepositoryList.prototype.requestData = function(start, limit) {
        var self = this;
        this._$spinner.spin('small');

        return server.rest({
            contextType: 'application/json',
            url: this.urlBuilder
                .withParams({ start: start, limit: limit })
                .build(),
            type: 'POST',
            data: this._postData,
            statusCode: {
                400: false,
                500: false
            }
        }).always(function() {
            self._$spinner.spinStop();
        });
    };

    ImporterRepositoryList.prototype.attachNewContent = function(data, attachmentMethod) {
        this.$scrollElement[attachmentMethod](data.values.map(function(repository) {
            return bitbucket.internal.importer.repositoryListItem({
                repository: repository
            });
        }));
    };

    ImporterRepositoryList.prototype.handleErrors = function() {
        new ErrorDialog({
            panelContent: bitbucket.internal.widget.paragraph({ text: AJS.I18n.getText('bitbucket.importer.repository.list.fetch.error', this._postData.ownerName) })
        }).show();
    };

    ImporterRepositoryList.prototype.init = function(postData) {
        var self = this;
        this.reset();
        this._postData = postData;
        PagedScrollable.prototype.init.call(this).done(function(data){
            // if there is no data show relevant message
            if (data.values && data.values.length === 0) {
                self.$scrollElement.html(bitbucket.internal.importer.repositoryListEmpty({
                    owner: self._postData.ownerName
                }));
            }
        });
    };

    ImporterRepositoryList.prototype.reset = function() {
        this._$container.empty();
        PagedScrollable.prototype.reset.call(this);
    };

    return ImporterRepositoryList;
});
