/**
 * Developer: Stepan Burguchev
 * Date: 12/3/2014
 * Copyright: 2009-2016 Comindware®
 *       All Rights Reserved
 * Published under the MIT license
 */

import { keypress, Handlebars } from 'lib';
import { helpers } from 'utils';
import list from 'list';
import template from '../templates/referencePanel.hbs';
import LocalizationService from '../../../../../services/LocalizationService';
import LoadingView from './LoadingView';
import AddNewButtonView from './AddNewButtonView';

const config = {
    CHILD_HEIGHT: 25
};

const classes = {
    EMPTY_VIEW: 'editor__common-empty-view'
};

export default Marionette.LayoutView.extend({
    initialize: function (options) {
        helpers.ensureOption(options, 'model');
        helpers.ensureOption(options, 'reqres');
        helpers.ensureOption(options, 'getDisplayText');

        this.reqres = options.reqres;
        this.showAddNewButton = this.options.showAddNewButton;
        this.fetchDelayId = _.uniqueId('fetch-delay-id-');
        this.timeoutId = null;
    },

    className: 'dd-list dd-list_reference',

    template: Handlebars.compile(template),

    templateHelpers: function () {
        let value = this.model.get('value');
        return {
            text: this.options.getDisplayText(this.model.get('value')),
            showAddNewButton: this.showAddNewButton
        };
    },

    ui: {
        input: '.js-input',
        clear: '.js-clear'
    },

    events: {
        'keyup @ui.input': '__onTextChange',
        'change @ui.input': '__onTextChange',
        'input @ui.input': '__onTextChange',
        'click @ui.clear': '__clear'
    },

    regions: {
        listRegion: '.js-list-region',
        scrollbarRegion: '.js-scrollbar-region',
        loadingRegion: '.js-loading-region',
        addNewButtonRegion: '.js-add-new-button-region'
    },

    onRender: function () {
        this.__assignKeyboardShortcuts();
    },

    onShow: function () {
        let result = list.factory.createDefaultList({
            collection: this.model.get('collection'),
            listViewOptions: {
                childView: this.options.listItemView,
                childViewOptions: {
                    reqres: this.reqres,
                    getDisplayText: this.options.getDisplayText
                },
                emptyViewOptions: {
                    text: LocalizationService.get('CORE.FORM.EDITORS.REFERENCE.NOITEMS'),
                    className: classes.EMPTY_VIEW
                },
                childHeight: config.CHILD_HEIGHT
            }
        });

        this.listView = result.listView;
        this.eventAggregator = result.eventAggregator;

        if (this.showAddNewButton) {
            this.$el.addClass('dd-list_reference-button');
            let addNewButton = new AddNewButtonView({reqres: this.reqres});
            this.addNewButtonRegion.show(addNewButton);
        }

        this.listRegion.show(result.listView);
        this.scrollbarRegion.show(result.scrollbarView);

        this.__updateFilter(true);
    },

    __assignKeyboardShortcuts () {
        if (this.keyListener) {
            this.keyListener.reset();
        }
        this.keyListener = new keypress.Listener(this.ui.input[0]);
        _.each(this.keyboardShortcuts, function (value, key)
        {
            let keys = key.split(',');
            _.each(keys, function (k) {
                this.keyListener.simple_combo(k, value.bind(this));
            }, this);
        }, this);
    },

    keyboardShortcuts: {
        'up': function () {
            this.listView.moveCursorBy(-1, false);
        },
        'down': function () {
            this.listView.moveCursorBy(1, false);
        },
        'enter,num_enter,tab': function () {
            if (this.isLoading) {
                return;
            }

            if (this.timeoutId) {
                clearTimeout(this.timeoutId);
                this.__updateFilter(true);
                return
            }

            let selectedModel = this.model.get('collection').selected;
            this.reqres.request('value:set', selectedModel);
        },
        'esc': function () {
            this.trigger('cancel');
        }
    },

    __clear: function () {
        this.reqres.request('value:set', null);
    },

    __onTextChange () {
        this.__updateFilter(false);
    },

    __updateFilter: function (immediate) {
        let text = (this.ui.input.val() || '').trim();
        if (this.activeText === text) {
            return;
        }
        const updateNow = function () {
            this.activeText = text;
            this.__setLoading(true);
            let collection = this.model.get('collection');
            collection.deselect();
            this.reqres.request('filter:text', {
                text: text
            }).then(function () {
                this.timeoutId = null;
                if (collection.length > 0) {
                    if (!collection.contains(collection.selected)) {
                        let model = collection.at(0);
                        model.select();
                    }
                }
                this.__setLoading(false);
            }.bind(this));
        }.bind(this);
        if (immediate) {
            updateNow();
        } else {
            this.timeoutId = helpers.setUniqueTimeout(this.fetchDelayId, updateNow, this.options.textFilterDelay);
        }
    },

    __setLoading (isLoading) {
        if (this.isDestroyed) {
            return;
        }
        this.isLoading = isLoading;
        if (isLoading) {
            this.loadingRegion.show(new LoadingView());
            this.ui.input.blur();
        } else {
            this.ui.input.focus();
            this.loadingRegion.reset();
        }
    }
});
