import {dropInputTpl, multipleTpl, menuItemTpl} from "./dropInputTpl";
import StringUtil from "../../util/StringUtil";
const DropInput = (($) => {
    const DefaultConfig = {
        node: null,
        list:[],
        placeholder:"请下拉选择",
        css:{
            width:200,
            height:30,
            listMaxHeight: 300
        },
        value:"",           
        multiple:false,     
        labelFiled:"name",  
        valueFiled:"id",    
        onChange: null,    
        onSearch: null,    
    };
    class DropInput {
        constructor(config) {
            this._config = this._getConfig(config);
            this.lastValues = "";
            this.searchResult = null;
            this.$container = $(this._config.node);
            let _list = this.getInitList();
            this.state = {
                list:_list
            };
            this._render();
            this._addEvents();
        }
        
        _getConfig(config) {
            return $.extend(true, {}, DefaultConfig, config);
        }
        
        update(config){
            this._config = $.extend(true, this._config, config);
            let _list = this.getInitList();
            this.state = {
                list:_list
            };
            this.$search.val("");
            this.searchResult = null;
            this.renderByState();
        }
        
        getSelects(list){
            let selectedItems = [];
            let labels = [];
            let values = [];
            let isSelectAll = false;
            if(list && list.length>0){
                isSelectAll = true;
                list.map((item, i)=>{
                    if(item.checked){
                        labels.push(item.name);
                        values.push(item.id);
                        selectedItems.push(item);
                    }
                    else{
                        isSelectAll = false;
                    }
                })
            }
            return {labels:labels, values:values, selectedItems:selectedItems, isSelectAll:isSelectAll};
        }
        
        getValues(){
            if(this.$dropText){
                return this.$dropText.attr("data-values");
            }
            else{
                return "";
            }
        }
        
        getSelected(){
            return this.getSelects(this.state.list);
        }
        
        renderByState(){
            const state = this.state;
            if(state && this.$dropText){
                const {placeholder} = this._config;
                let temp = this.getSelects(state.list);
                let values = temp.values.join(",");
                let labels = temp.labels.join(",");
                let _label = labels;
                if(!values){
                    _label = placeholder;
                }
                this.$dropText.text(_label);
                this.$dropText.attr("data-values", values);
                this.$dropText.attr("title", labels);
                if(this.isSearching()){
                    this.renderList(this.searchResult);
                }
                else{
                    this.renderList(state.list);
                }
            }
        }
        
        isSearching(){
            var val = this.$search.val();
            if(val && this.searchResult){
                return true;
            }
            else{
                return false;
            }
        }
        
        _render() {
            let searchTpl = template.render(dropInputTpl, this._config);
            this.$container.append(searchTpl);
            this.$dropText = this.$container.find(".J_dropText");
            this.$dropInput = this.$container.find('.J_dropInput');
            this.$dropInputSelect = this.$container.find('.J_dropInputSelect');
            this.$searchBtn = this.$dropInputSelect.find('.J_searchBtn');
            this.$search = this.$dropInputSelect.find('.J_search');
            this.$list = this.$dropInputSelect.find('.J_list');
            this.renderByState();
        }
        getTimer(){
            return (new Date().getTime());
        }
        
        renderItem(item){
            let result = '';
            if(item){
                result = '<li class="d-item J_item" data-index="' + item.index + '" data-name="' + item.name + '" data-id="' + item.id + '" data-info="' + JSON.stringify(item.item) + '" title="' + item.name + '">';
                result += '<label><input type="checkbox" data-id="' + item.id + '"';
                if(item.checked){
                    result += ' checked="checked"';
                }
                result += ' class="d-checkbox J_checkBox">' + item.name + '</label></li>';
            }
            return result;
        }
        
        renderCheckAll(item){
            let result = '';
            if(item){
                result = '<li class="d-item J_itemAll" data-name="全部" title="全部"><label><input type="checkbox"';
                if(item.checked) {
                    result += ' checked="checked"';
                }
                result += ' class="d-checkbox J_selectAll">全部</label></li>';
            }
            return result;
        }
        
        renderList(list){
            let _listHtml = "";
            if(list && list.length>0){
                const {multiple} = this._config;
                let isCheckAll = true;
                let len = list.length;
                for(let i=0; i<len; i++){
                    let item = list[i];
                    if(item.checked==false){
                        isCheckAll = false;
                    }
                    _listHtml += this.renderItem(item);
                }
                if(multiple){
                    let _multipleHtml = this.renderCheckAll({checked:isCheckAll});
                    _listHtml = _multipleHtml + _listHtml;
                }
            }
            this.$list.html(_listHtml);
        }
        
        
        getInitList(){
            const {list, value} = this._config;
            let tempList = value.split(",");
            let result = [];
            list.map((item, i)=>{
                let id = this.getValue(item) + "";
                let name = this.getLabel(item);
                if(tempList.indexOf(id)>-1){
                    result.push({checked:true, item:item, id:id, name:name, index:i});
                }
                else{
                    result.push({checked:false, item:item, id:id, name:name, index:i});
                }
            });
            return result;
        }
        
        getLabel(item){
            const {labelFiled} = this._config;
            if(item!=null){
                if(StringUtil.isObject(item)){
                    return item[labelFiled];
                }
                else{
                    return item;
                }
            }
            else{
                return "";
            }
        }
        
        getValue(item){
            const {valueFiled} = this._config;
            if(item!=null){
                if(StringUtil.isObject(item)){
                    return item[valueFiled];
                }
                else{
                    return item;
                }
            }
            else{
                return "";
            }
        }
        
        _addEvents() {
            var self=this;
            let config = this._config;
            this.$container.bind('click', () => {
                this.$dropInputSelect.show();
                if(!this.$dropInput.hasClass('active')){
                    this.$dropInput.addClass('active');
                }
            });
            this.$list.on('click','.J_checkBox',function(e){
                e.stopPropagation();
                const {multiple} = config;
                let $checkBox = $(this);
                let $item = $checkBox.closest('.J_item');
                let id = $item.data("id");
                let index = $item.data("index");
                let hideFlag = false;
                let checkFlag = $checkBox.prop("checked");
                let list = self.state.list;
                if(!multiple){
                    list.map((item, i)=>{
                        if(item.id == id && index == i){
                            item.checked = checkFlag;
                        }
                        else{
                            item.checked = false;
                        }
                    });
                    if(checkFlag===true){
                        hideFlag = true;	
                    }
                }
                else{
                    let _len = list.length;
                    for(let i=0; i<_len; i++){
                        let item = list[i];
                        if(item.id == id && index == i){
                            item.checked = checkFlag;
                        }
                    }
                }
                self.renderByState();
                if(hideFlag){
                    self.hideSelect();
                }
            });
            this.$list.on('change','.J_selectAll',function(e){
                e.stopPropagation();
                let $checkBox = $(this);
                let checkFlag = $checkBox.prop("checked");
                let list = self.state.list;
                if(self.isSearching()){
                    list = self.searchResult;
                }
                let _len = list.length;
                for(let i=0; i<_len; i++){
                    let item = list[i];
                    item.checked = checkFlag;
                }
                self.renderByState();
            });
            this.$search.bind('keyup',function(e){
                e.stopPropagation();
                self.$searchBtn.trigger('click');
            });
            this.$searchBtn.bind('click',(e)=>{
                e.stopPropagation();
                var val = this.$search.val();
                const {onSearch} = this._config;
                let list = self.state.list;
                if(onSearch && (typeof onSearch == 'function')){
                    self.searchResult = onSearch(list, val);
                }
                else{
                    if(!list|| list.length==0){
                        return;
                    }
                    if(val) {
                        self.searchResult = list.filter((data)=>{
                            if(data){
                                let label = data.name;
                                return label.includes(val);
                            }
                        });
                    }
                    else{
                        self.searchResult = list;
                    }
                }
                this.renderList(self.searchResult);
            });
            this._documentCLick1=this._documentClick.bind(this);
            document.addEventListener("click",this._documentCLick1 );
        }
        
        reset(){
            this.$search.val("");
            this.searchResult = null;
            this.renderByState();
        }
        
        _documentClick(e){
            if(!this.$container){
                return;
            }
            if($(e.target).closest(".J_dropWrapper").length > 0 || this.$dropInputSelect.is(':hidden')){
                return false;
            }
            else {
                this.hideSelect();
            }
        }
        hideSelect(){
            let data = this.getSelects(this.state.list);
            let values = data.values.join(",");
            if(this.lastValues!= data.values.join(",")){
                this.lastValues = values;
                const {onChange} = this._config;
                if(onChange){
                    onChange(data);
                }
            }
            this.reset();
            this.$dropInputSelect.hide();
            this.$dropInput.removeClass('active');
        }
        
        dispose() {
            this.$container.off();
            this.$list.off();
            this.$search.unbind('keyup');
            this.$searchBtn.unbind('click');
            if(this._documentCLick1)
                document.removeEventListener("click", this._documentCLick1);
            this.$container = null;
        }
    }
    return DropInput;
})($);
export default DropInput;