(function () {
    function IdentSearchFields(onSearch) {
        var self = this;
        this.searchData = this.initSearchData();

        this.searchFieldsDef = {
            IdentType: this.initSelectionFieldDef({
                value: '',
                label: ''
            }),
            Classification: this.initSelectionFieldDef({
                value: '',
                label: ''
            }),
            SecondaryClassification: this.initSelectionFieldDef({
                value: '',
                label: ''
            }),
            IdentStatus: this.initSelectionFieldDef(),
            SubjectCode: this.initTypeaheadFieldDef('SubjectCode', '/IdentSearch/FindSubjects'),
            PrimarySupplier: this.initTypeaheadFieldDef('PrimarySupplier', '/IdentSearch/FindPrimarySuppliers'),
            Supplier: this.initTypeaheadFieldDef('Supplier', '/IdentSearch/FindSuppliers')
        };
        this.searchFieldsData = null;

        this.inputs = {};

        this.searchDebouncer = debouncer(onSearch, 300);

        this.$typeaheadOutlet = null;
    }

    IdentSearchFields.prototype.init = function ($elt) {
        var self = this;
        return this.fetchSearchFieldsData().then(function(){
            self.initSearchFields().bindSearchFields();
        });
    };

    IdentSearchFields.prototype.destroy = function () {
        for(var fieldId in this.inputs){
            this.inputs[fieldId].unbind();
        }
        this.searchData = this.initSearchData();
        this.$typeaheadOutlet.remove();
        this.$typeaheadOutlet = null;
    };

    IdentSearchFields.prototype.fetchSearchFieldsData = function(){
        if(paw.utils.value.isSet(this.searchFieldsData)){
            return paw.utils.async.promise(this.searchFieldsData);
        }
        var self = this;
        var d = paw.utils.async.defer();
        $.ajax({
            method: "GET",
            url: "/IdentSearch/GetIdentSearchFieldsData",
            success: function(payload){
                self.searchFieldsData = payload;
                d.resolve(payload);
            },
            error: function(){
                d.reject();
            },
        });
        return d.promise;
    };

    IdentSearchFields.prototype.bindSearchFields = function(){
        var self = this;
        $('[data-ident-search-field]').each(function(){
            var $input = $(this);
            var fieldId = $input.attr('data-ident-search-field');
            
            var onChangeFn = null;
            // set field specific on change OR use generic on change
            if (paw.utils.value.isSet(self.searchFieldsDef[fieldId]) && paw.utils.value.isFunction(self.searchFieldsDef[fieldId].onChange)) {
                onChangeFn = self.searchFieldsDef[fieldId].onChange;
            }
            else {
                onChangeFn = function (e, v) {
                    if (fieldId === 'Quantity') {
                        return;
                    }
                    if (self.searchData.FindOnChange) {
                        self.searchDebouncer();
                    }
                };
            }
            self.inputs[fieldId] = new paw.com.Input($input, fieldId, self.searchData, self.searchFieldsDef[fieldId], onChangeFn);
        });
        return this; // for chaining
    };

    IdentSearchFields.prototype.initSearchFields = function(){
        var self = this;
        paw.utils.value.iterate(this.searchFieldsDef, function(fieldDef, fieldId){
            if(paw.utils.value.notSet(self.searchFieldsData[fieldId])){
                return;
            }
            fieldDef.options = self.searchFieldsData[fieldId];
        });

        // prepare outlet for typeahead - to solve z-index and bounding-box issue
        this.$typeaheadOutlet = $('<div class="ident-search-typehead-outlet"></div>');
        $('body').append(this.$typeaheadOutlet);
        return this; // for chaining
    };

    IdentSearchFields.prototype.initSelectionFieldDef = function(defaults){
        return {
            options: [],
            defaultValue: paw.utils.value.isSet(defaults)? defaults.value : undefined,
            defaultLabel: paw.utils.value.isSet(defaults) ? defaults.label : undefined,
            mappedValue: function(opt){
                return opt.Key;
            },
            mappedLabel: function(opt){
                return opt.Value;
            }
        };
    };

    IdentSearchFields.prototype.initTypeaheadFieldDef = function (fieldId, url) {
        var self = this;
        return {
            url: url,
            onChange: function (e, value) {
                // exec. search if typeahead value vas cleared (no item selected)
                if (value.length === 0) {
                    if (self.searchData.FindOnChange) {
                        self.searchDebouncer();
                    }
                }
            },
            onSelected: function (item) {
                self.searchData[fieldId] = item.id;
                if (self.searchData.FindOnChange) {
                    self.searchDebouncer();
                }
            }
        };
    };

    IdentSearchFields.prototype.initSearchData = function(){
        return {
            Ident: "",
            Quantity: "",
            Name: "",
            IdentType: "",
            SupplierCode: "",
            Classification: "",
            SecondaryClassification: "",
            Code: "",
            SubjectCode: "",
            Supplier: "",
            PrimarySupplier: "",
            FromLastDocuments: null,
            IdentStatus: 'ALL',
            FindInPiecesOfPaper: false,
            FindOnChange: true
        };
    };

    paw.com.identSearch.IdentSearchFields = IdentSearchFields;
})(paw);