import { Namespace } from '../../utils/namespace'
import { Touch } from '../../utils/touch'
import { DOMExtension } from '../../utils/extensions/dom'

const namespace = Namespace.Create('pull-refresh')

export default {
    name:namespace.name,
    props:{
        distanceToRefresh: {
            type: Number,
            default: 50
        },
        loading: {
            type: Boolean,
            default: false
        },
        finished: {
            type: Boolean,
            default: false
        }
    },
    data(){
        return {
            status: 'normal',
            isReachTop: false,
            touch: Touch.Create()
        }
    },
    computed:{
        cls(){
            return namespace.derive()
        },
        containerCls(){
            return namespace.derive('container')
        },
        infoCls(){
            return namespace.derive('info')
        },
        viewerCls(){
            return namespace.derive('viewer')
        },
        containerStyle(){
            let distance = this.ease(this.touch.deltaY);
            if(this.isLoading){
                distance = this.distanceToRefresh
            }
            return `transform:translateY(${distance}px)`;
        },
        infoStyle(){
            return `height:${this.distanceToRefresh}px`
        },
        isPulling(){
            return this.status === 'pulling'
        },
        isLoosing(){
            return this.status === 'loosing'
        },
        isLoading(){
            return this.loading
        },
        isFinished(){
            return this.finished
        },
        isTouchable(){
            return !this.isLoading
        }
    },
    methods:{
        onTouchStart(e){
            if(!this.isTouchable){
                return
            }
            if (!this.isReachEdge()) {
                return;
            }
            this.touch.start(e)
        },
        onTouchMove(e){
            if (!this.isTouchable) {
                return;
            }
            if (!this.isReachEdge()) {
                return;
            }
            if(this.touch.startY === 0 ){
                this.touch.start(e)
            }else{
                this.touch.move(e)
                if(this.touch.deltaY > 0){
                    DOMExtension.PreventDefault(e)
                    if(this.touch.deltaY < this.distanceToRefresh){
                        this.status = 'pulling'
                    }else{
                        this.status = 'loosing'
                    }
                }
            }
        },
        onTouchEnd(e){
            if(this.touch.deltaY > this.distanceToRefresh){
                this.$emit('refresh', e)
            }
            this.touch.reset()
            this.status = 'normal'
        },
        isReachEdge(){
            return this.$refs.viewer.scrollTop === 0 
        },
        ease(deltaY) {
            let distance = deltaY < 0 ? 0 : deltaY;
            if (distance > this.distanceToRefresh) {
              if (distance < this.distanceToRefresh * 2) {
                distance = this.distanceToRefresh + (distance - this.distanceToRefresh) / 2;
              } else {
                distance = this.distanceToRefresh * 1.5 + (distance - this.distanceToRefresh * 2) / 4;
              }
            }
            return Math.round(distance);
        },
    },
    render(){
        const renderPull = ()=>(
            this.$slots.pull || <div>下拉刷新</div>
        )

        const renderLoading = ()=>(
            // <div>加载中...</div>
            this.$slots.loading || 
            <mx-loading type="spinner" size={18}/>
        )

        const renderLoose = ()=>(
            this.$slots.loose || <div>释放刷新</div>
        )

        const renderFinished = ()=>(
            this.$slots.finished || <div>- 没有更多内容了 -</div>
        )

        const renderInfo = ()=>(
            <div class={this.infoCls} style={this.infoStyle}>
                {!this.isFinished && this.isPulling && renderPull()}
                {!this.isFinished && this.isLoosing && renderLoose()}
                {!this.isFinished && this.isLoading && renderLoading()}
                {this.isFinished && renderFinished()}
            </div>
        )

        const renderViewer = ()=>(
            <div ref={'viewer'} class={this.viewerCls}>
                {this.$slots.default}
            </div>
        )

        return (
            <div class={this.cls}>
                <div class={this.containerCls} style={this.containerStyle}
                    onTouchstart = {this.onTouchStart}
                    onTouchmove = {this.onTouchMove}
                    onTouchend = {this.onTouchEnd}
                    onTouchcancel = {this.onTouchEnd}
                >
                    {renderInfo()}
                    {renderViewer()}
                </div>
            </div>
        )
    }
}