import './index.scss'
import Message from '../../../message';
import sendHttp,{fetch} from '../../../httpClient';
import Loading from '../../../loading';
import domain from '../../../../util/domain'
import { cascadeContainerTpl, cascadeMenu, cascadeMenuLoading } from './tpl'
const BASE_PATH = domain.opJshop
const defaultConfig = {
    node: '',
    className: 'cd-cascade-select-layer',
    api: '/shop/getShopCategory.json',
    queryKey: 'fatherId',
    basePath: BASE_PATH,
    dataType: 'json',
    timeout: null,
    value: [],
    baseZIndex: 0,
    scrollNode: 'document',
    callback:null
}
const classNames = {
    active: 'cd--active',
    select: 'cd--selected'
}
class JDCategorySelect {
    constructor(config) {
        this.config = $.extend(defaultConfig, config || {})
        this.target = $(this.config.node)
        this.value = this.config.value
        this.selectedData = []
        this.layer = null
        this.menuData = []
        this.config.baseZIndex = this._getMaxZIndex()
    }
    show() {
        const menuData = this.menuData
        if (this.target.hasClass(classNames.active) && menuData.length) {
            return false
        }
        if (this.layer) {
            
            this._postion()
            this.layer.show()
        } else {
            this._render()
        }
        this.target.addClass(classNames.active)
    }
    _render() {
        if (!this.layer) {
            this.layer = $(template.render(cascadeContainerTpl, this.config))
        }
        this._postion()
        
        this._getMenuData(0)
        this.layer.appendTo($('body'))
        this._addEvent()
    }
    _postion() {
        let targetPostion = this.target.offset()
        this.layer.css({
            top: targetPostion.top + this.target.height() + 4,
            left: targetPostion.left,
            zIndex: this.config.baseZIndex + 9
        })
    }
    _addEvent() {
        this.layer.on('click', '.cd-cascade-select-more', ev => {
            ev.stopPropagation()
            let target = $(ev.currentTarget)
            let parent = target.parents('.cd-cascade-select-menu')
            let level = parent.data('level')
            let id = target.data('id')
            let children = target.data('children')
            let subMenu = this.layer.find('.cd-cascade-select-menu[data-level=' + (level + 1) + ']')
            if (this.isAjax) {
                return
            }
            if (subMenu.length && subMenu.data('parent') == id) {
                return
            }
            parent.find('.' + classNames.select).removeClass(classNames.select)
            target.addClass(classNames.select)
            this._clearData(level)
            
            let l = this.menuData.length
            $(template.render(cascadeMenu, {
                parentId: id,
                list: children,
                level: l,
                selectedValue: this.value[l]
            })).appendTo(this.layer)
            this.menuData.push(children)
            this.value.push(id)
            this.selectedData.push(target.data('original'))
            this.updateNodeText()
        })
        this.layer.on('click', '.cd-cascade-select-item:not(.cd-cascade-select-more)', ev => {
            ev.stopPropagation()
            let target = $(ev.currentTarget)
            let parent = target.parents('.cd-cascade-select-menu')
            let level = parent.data('level')
            let id = target.data('id')
            if (level <= this.selectedData.length) {
                this._clearData(level)
            }
            parent.find('.' + classNames.select).removeClass(classNames.select)
            target.addClass(classNames.select)
            this.value.push(id)
            this.selectedData.push(target.data('original'))
            if (!target.hasClass('cd-cascade-select-more')) {
                $(this).trigger('selected')
                this._hide()
            }
            this.updateNodeText()
        })
        $(window).on('click', ev => {
            let target = $(ev.target)
            if (!target.hasClass('cd-cascade-select-layer') && !target.parents('.cd-cascade-select-layer').length && !target.is(this.target)) {
                this._hide()
            }
        })
        
        $(window).on('winModalClose', () => {
            this._hide()
            this._dispose();
        })
        
        $(window).bind('scroll', (ev) => {
            let target = $(ev.target)
            if (!target.hasClass('cd-cascade-select-layer') && !target.parents('.cd-cascade-select-layer').length && !target.is(this.target)) {
                this._hide()
            }
        })
        $(this.config.scrollNode).bind('scroll', ev => {
            let target = $(ev.target)
            if (!target.hasClass('cd-cascade-select-layer') && !target.parents('.cd-cascade-select-layer').length && !target.is(this.target)) {
                this._hide()
            }
        })
    }
    updateNodeText(node) {
        let _node = node ? node : this.target
        if (_node && this.selectedData.length) {
            let _catName = []
            this.selectedData.forEach((item) => {
                _catName.push(item.catName)
            })
            if(this.config.displayMode == 'arrow' && _catName.length == 3){
                if(typeof this.config.callback  === 'function') {
                    this.config.callback(this.selectedData);
                }
            }else {
                _node.html(_catName.join('/'))
            }
            _node.data('catInfo', this.selectedData)
        }
    }
    _hide() {
        this.layer.hide()
        this.target.removeClass(classNames.active)
        if(this.config.displayMode == 'arrow'){
            this. _dispose()
        }
    }
    _dispose() {
        this.target.data('categorySelectInstance',null);
        this.layer.remove();
    }
    _clearData(level) {
        this.layer.find('.cd-cascade-select-menu').each((index, el) => {
            if ($(el).data('level') > level) {
                $(el).remove()
            }
        })
        if (level + 1 < this.menuData.length) {
            this.menuData.splice(level + 1, this.menuData.length)
        }
        if (level < this.value.length) {
            this.value.splice(level, this.value.length)
            this.selectedData.splice(level, this.selectedData.length)
        }
    }
    _getMaxZIndex() {
        let maxZ = Math.max.apply(null,
            $.map($('body *'), function (e, n) {
                if ($(e).css('position') != 'static')
                    return parseInt($(e).css('z-index')) || -1
            }))
        return maxZ
    }
    async _getMenuData(parentId) {
        let venderType =  window.page_data.venderType == 1 ? 'vc' : 'pop';
        let httpConfig = {
            basePath: this.config.basePath,
            url: this.config.api,
            method: 'get',
            data:{
                venderType:venderType,
            },
            showLoading: false,
            isErrorCallback: true
        }
        if (this.config.dataType === 'jsonp') {
            httpConfig = $.extend(httpConfig, {
                basePath: this.config.basePath,
                dataType: 'jsonp'
            })
        }
        if (this.config.timeout) {
            httpConfig = $.extend(httpConfig, {
                timeout: this.config.timeout
            })
        }
        let loading = $(cascadeMenuLoading)
        loading.appendTo(this.layer)
        let zoneLoading = new Loading({
            node: loading[0]
        })
        zoneLoading.show()
        this.isAjax = true
        sendHttp(httpConfig, result => {
            let res = result.data
            this.isAjax = false
            zoneLoading.hide()
            loading.remove()
            if (res.code == 0 || res.result) {
                let level = this.menuData.length
                if (this.config.adapterData) {
                    res = this.config.adapterData(res)
                }
                
                $(template.render(cascadeMenu, {
                    parentId: parentId,
                    list: res.data.shopCategory,
                    level: level,
                    selectedValue: this.value[level]
                })).appendTo(this.layer)
                this.menuData.push(res.data)
            } else {
                if (res.desc) {
                    Message.error(res.desc)
                }
            }
        })
    }
}
export default JDCategorySelect