import { Namespace } from "../../utils/namespace";
import { MathExtension } from '../../utils/extensions/math';
import { mixParent } from '../../mixins/relation/parent'
import Badge from '../badge/badge.jsx'
import Icon from '../icon/icon.jsx'

export const namespace =Namespace.Create('tab')

export default {
    name: namespace.name,
    mixins:[
        mixParent(namespace.name)
    ],
    components:{
        Badge,
        Icon
    },
    props:{
        value:{
            type: String | Number,
            default: 0
        },
        type:{
            type: String,
            default: 'line'
        },
        position:{
            type: String,
            default: 'top'
        },
        duration:{
            type: String | Number,
            default: 0.36
        },
        lineColor:{
            type: String,
            default: '#000000'
        },
        lineSize:{
            type: String | Number,
            default: '2'
        },
        animated:{
            type: Boolean,
            default: false
        },
        headerClass:{
            type: String
        },
        titleActiveColor:{
            type: String,
            default:'#000000'
        },
        titleActiveBackground:{
            type: String,
            default:'#000000'
        },
        titleInactiveBackground:{
            type: String,
            default: '#F2F2F2'
        },
        titleInactiveColor:{
            type: String,
            default:'#8A8A8F'
        }
    },
    model:{
        prop:'value',
        event:'change'
    },
    data(){
        return {
            inited:false,
            isLineInited:false
        }
    },
    computed:{
        cls(){
            return namespace.derive([this.position])
        },
        headerCls(){
            return [namespace.derive('header',[this.position]),this.headerClass]
        },
        navCls(){
            return namespace.derive('nav',[this.position])
        },
        navStyle(){
            const style = {}
            if(this.inited){
                const nav = this.$refs.nav
                const maxOffset =this.isHorizental ?  (nav.scrollWidth - nav.offsetWidth): (nav.scrollHeight - nav.offsetHeight)
                const el = this.$refs[`nav_button_${this.value}`]
                const offset = this.isHorizental ? 
                    (el.offsetLeft + el.offsetWidth / 2 - nav.offsetWidth / 2) 
                    : (el.offsetTop + el.offsetHeight / 2 - nav.offsetHeight / 2)
                
                style.transform = `translate${this.isHorizental ? 'X':'Y'}(${-MathExtension.Clamp(offset, 0, maxOffset)}px)`
            }
            return style
        },
        lineCls(){
            return namespace.derive('nav-line',[this.position])
        },
        lineStyle(){
            if(this.type !== 'line'){
                return
            }
            const style={
                background: this.lineColor,
                [this.isHorizental?'height':'width']: `${this.lineSize}px`,
            }
            if(this.inited){
                const el = this.$refs[`nav_button_text_${this.value}`]
                style[this.isHorizental?'width':'height'] = `${this.isHorizental ? el.offsetWidth : el.offsetHeight}px`
                style.transform = `translate${this.isHorizental?'X':'Y'}(${this.isHorizental ? el.offsetLeft : el.offsetTop}px)`
                if(!this.isLineInited){
                    style.transitionDuration = '0s'
                    this.isLineInited = true
                }
            }
            return style
        },
        bodyCls(){
            return namespace.derive('body',[this.position])
        },
        trackCls(){
            return namespace.derive('body-track')
        },
        trackStyle(){
            const style = {
                transform:`translateX(${-this.value * 100}%)`,
                transitionDuration: (!this.inited || !this.animated) ? '0s' : `${this.duration}s`
            }
            return style
        },
        buttonIconCls(){
            return namespace.derive('nav-button-text--button-icon')
        },
        isFrontHeader(){
            return this.position === 'top' || this.position === 'left'
        },
        isRearHeader(){
            return this.position === 'bottom' || this.position === 'right'
        },
        isVertical(){
            return this.position === 'left' || this.position === 'right'
        },
        isHorizental(){
            return this.position === 'top' || this.position === 'bottom'
        }
    },
    mounted(){
        this.$nextTick(()=>this.inited = true)
    },
    methods:{
        onButtonClick(button,index,e){
            this.$emit('change', index)
        }
    },
    render(){
        const renderNav= ()=> this.children.map((x,index)=>{
            const isActive = this.value === index
            const buttonCls = namespace.derive('nav-button',[this.position,this.type])
            const textCls = namespace.derive('nav-button-text',[this.type=== 'button' ? 'button': 'text', {active:isActive}])
            const textStyle = {
                color: isActive ? this.titleActiveColor: this.titleInactiveColor
            }
            if(this.type === 'button'){
                textStyle.background = isActive ? this.titleActiveBackground : this.titleInactiveBackground
            }
            const tag = this.type === 'button'? 'div' : 'span'
            const text = <tag ref={`nav_button_text_${index}`} class={textCls} style={textStyle}>
                { 
                    x.$scopedSlots.title?.({active: isActive}) 
                    ||[
                       x.icon && <Icon class={this.buttonIconCls} name={x.icon} size={x.iconSize} color={textStyle.color} />,
                       x.title  
                    ]
                }
            </tag>

            const content = (x.dot || x.badge ) ?
                <Badge dot={x.dot} content={x.badge} small>{text}</Badge>
                : text
            
            return (
                <div ref={`nav_button_${index}`} class={buttonCls} onClick={e=>this.onButtonClick(x,index,e)}>
                    {content}
                </div>
            )
        })

        const renderHeader = ()=>(
            <div ref="header" class={this.headerCls}>
                <div ref="nav" class={this.navCls} style={this.navStyle}>
                    {renderNav()}
                    {this.type === 'line' && <div class={this.lineCls} style={this.lineStyle}/>}
                </div>
            </div>
        )

        return (
            <div class={this.cls}>
                {this.isFrontHeader && renderHeader()}
                <div class={this.bodyCls}>
                    <div class={this.trackCls} style={this.trackStyle}>
                        {this.$slots.default}
                    </div>
                </div>
                {this.isRearHeader && renderHeader()}
            </div>
        )
    }
}