import {tpl, paginationTpl} from './pageTableTpl';
import MathUtil from "../../util/MathUtil";
import classNames from "classnames";
import LongPagination from "../longPagination";
import sendHttp from "../httpClient";
import "./pageTable.scss";
const PageBase = (($) => {
    const DefaultConfig = {
        frontEndPaging: false,
        showPagination: true,
        pageSize: 10,
        onPageChange: null,
        defaultClassName:"",
        className:"",
        itemRenderer:null,
        nodataRenderer:null,
        loadingRenderer:null,
        pagination:LongPagination,
        dataProvider:[],
        dataRenderType: 'html',
        loading:false,
        loadingText:"加载中...",
        nodataText:"没有查询到合适的数据",
        queryOptions:null,
        needStringify: false,      
        queryHandler:null,
        renderContentBefore:null,   
        currentPage: 1,
        totalPage: 1,
        totalItem:0,
        onReady:null,
        onDomReady:null,
        onDomUpdate:null,
        beforeDispose:null
    };
    class PageBase {
        
        constructor(config) {
            this.__name = "PageBase";
            this._config = this._getConfig(config);
            this._parent = this._config.node;
            this._$ui = null;
            this._$contentWrapper = null;
            this._$pagination = null;
            this._pagination = null;
            this.id = MathUtil.getUID();
            this._isShown = false;
            this.fixedQueryData = {data: this._config.queryOptions? this._config.queryOptions.data: {}};       
            this.cacheQueryData = null;         
            this.state = {
                totalPage:1,
                currentPage:1,
                totalItem:0,
                pageData:[],
                loading:this._config.loading
            }
            this.setPageData(this._config);
            this.initUI();
            const {onReady} = this._config;
            if(onReady){
                onReady(this._$ui);
            }
            this._addEvent();
            this.open();
            this.query();
            const {onDomReady} = this._config;
            if(onDomReady){
                onDomReady(this._$ui);
            }
        }
        
        _getConfig(config) {
            return $.extend(true,{}, DefaultConfig, config);
        }
        
        update(config){
            this._config.dataProvider = [];
            this._config = $.extend(true,{}, this._config, config);
            this.state.loading = this._config.loading;
            this.setPageData(this._config);
            this.render();
        }
        
        query(options){
            if(options && options.data){
                this.cacheQueryData = options.data;
            }
            else{
                this.cacheQueryData = {};       
            }
            let pageNo = 1;
            if(options && options.data && options.data.pageNo!=null){
                pageNo = options.data.pageNo;
            }
            this._config = $.extend(true,{}, this._config, {queryOptions:options});
            this._loadData(pageNo, this._config.pageSize);
        }
        
        _loadData(pageNo, pageSize){
            const {queryOptions, queryHandler} = this._config;
            if(queryOptions && queryOptions.url){
                let param = {
                    pageNo:pageNo,
                    pageSize:pageSize
                }
                if(queryOptions){
                    queryOptions.data = this.cacheQueryData;
                }
                param = $.extend(true, {}, this.fixedQueryData, queryOptions, {data: param});
                if(this._config.needStringify){
                    param.data = JSON.stringify(param.data);
                }
                sendHttp(param, (result)=>{
                    if(result.success && result.data){
                        let _pageInfo = result.data.pageInfo,
                            _data = result.data;
                        if((_data.success == true || _data.code == 200) && _data.data){
                            _data = _data.data;
                            if(queryHandler){
                                queryHandler(_data, pageNo, pageSize);
                            }
                            else{
                                this.update({
                                    loading:false,
                                    currentPage: pageNo,
                                    totalPage: _data.totalPage || _pageInfo && _pageInfo.pageCount,
                                    totalItem: _data.totalCount || _pageInfo && _pageInfo.totalCount,
                                    dataProvider: _data.list || _data
                                })
                            }
                        }
                        else{
                            this.update({
                                loading:false
                            })
                        }
                    }
                    else{
                        this.update({
                            loading:false
                        })
                    }
                    if(typeof queryOptions.queryCallback == "function"){
                        queryOptions.queryCallback(result);
                    }
                });
            }
        }
        
        _addEvent() {
        }
        open(){
            if(this._isShown==false){
                this._isShown = true;
                if(this._$ui && this._parent){
                    this._$ui.appendTo(this._parent);
                }
            }
        }
        close(){
            if(this._$ui){
                this._$ui.remove();
            }
            this._isShown = false;
            this.dispose();
        }
        setPageData(props){
            const {frontEndPaging, dataProvider, currentPage, totalPage, totalItem} = props;
            if(frontEndPaging){
                this._queryData(this.state.currentPage, props);
            }
            else{
                let tempList = dataProvider || [];
                this.setState({
                    totalPage:totalPage,
                    currentPage:currentPage,
                    pageData:tempList,
                    totalItem:totalItem
                })
            }
        }
        _queryData(queryPage, props){
            const {dataProvider, pageSize} = props;
            let tempList = dataProvider || [];
            let _totalPage = Math.ceil(tempList.length/pageSize);
            let _currentPage = queryPage;
            if(_currentPage > _totalPage || _currentPage<1){
                _currentPage = 1;
            }
            let startIndex = Math.max(0, (_currentPage-1) * pageSize);
            let endIndex = Math.min(tempList.length, _currentPage * pageSize);
            let result = tempList.slice(startIndex, endIndex);
            this.setState({
                totalPage:_totalPage,
                currentPage:_currentPage,
                pageData:result,
                totalItem:dataProvider.length
            })
        }
        _onPageChange(data){
            const {onPageChange, frontEndPaging} = this._config;
            if(frontEndPaging){
                this._queryData(data.selected, this._config);
                this.render();
                if(onPageChange){
                    onPageChange(data);
                }
            }
            else{
                this._loadData(data.selected, this._config.pageSize);
                if(onPageChange){
                    onPageChange(data);
                }
            }
        }
        
        initUI(){
            const {defaultClassName, className, showPagination, pagination} = this._config;
            let _className = classNames(defaultClassName, className);
            let _content = this.renderContent() || "";
            let _pagination = "";
            if(showPagination){
                _pagination = paginationTpl;
            }
            let renderData = {
                label:this._config.label || "",
                _className:_className,
                content:_content,
                pagination:_pagination
            }
            let renderText = template.render(tpl, renderData);
            this._$ui = $(renderText);
            this._$contentWrapper = this._$ui.find(".J_contentWrapper");
            if(showPagination){
                this._$pagination = this._$ui.find(".J_pagination");
                this._pagination = new pagination({
                    node: this._$pagination[0],
                    current: this.state.currentPage, 
                    total: this.state.totalPage,  
                    middleDisplay: 5,   
                    totalItem: this.state.totalItem,     
                    pageChange: (args)=> {
                        this._onPageChange({selected:args.current});
                    }
                })
                if(this.state.totalPage > 1){
                    this._$pagination.show();
                }
                else{
                    this._$pagination.hide();
                }
            }
        }
        
        render(){
            const {totalPage, currentPage, totalItem} = this.state;
            const {pageSize} = this._config;
            let _content = this.renderContent() || "";
            if(this._$contentWrapper){
                this._$contentWrapper[this.state.currentPage === 1? 'html': this._config.dataRenderType](_content);
            }
            if(this._pagination){
                this._pagination.update({
                    current: currentPage,
                    total: totalPage,
                    totalItem: totalItem,
                });
                if(this.state.totalPage > 1){
                    this._$pagination.show();
                }
                else{
                    this._$pagination.hide();
                }
            }
            const {onDomUpdate} = this._config;
            if(onDomUpdate){
                onDomUpdate(this._$ui);
            }
        }
        
        renderContent(){
            console.log("pagebase.renderContent")
            return "";
        }
        setState(partialState){
            if(partialState){
                this.state = $.extend(this.state, partialState);
            }
        }
        
        dispose() {
            const {beforeDispose} = this._config;
            if(beforeDispose){
                beforeDispose();
            }
            if(this._$ui){
                this._$ui.off();
            }
            this._$ui = null;
            this._parent = null;
            this._$pagination = null;
            if(this._pagination){
                this._pagination.dispose();
            }
            this._pagination = null;
            if(this._$contentWrapper){
                this._$contentWrapper.off();
            }
            this._$contentWrapper = null;
        }
    }
    return PageBase;
})($);
export default PageBase;