import baseComponent from '../helpers/baseComponent'
import classNames from '../helpers/libs/classNames'
import { useRect } from '../helpers/hooks/useDOM'

const notice = 'data:image/png;base64,[encoded data, 5984 characters]'
const close = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAEAYAAAD6+a2dAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAAASAAAAEgARslrPgAAAyFJREFUeNrt3D9oE1EcB/D3ri2JdSp1kEKlhHTRyVGkuHSQRIQsLaXo0KHkD3RSRMWpk+iikKR06KBIbaEExASHbkV0c1GXSmgKFoeWIkJtUrnn0t8NKeHSNO/u/fl+tpKD/N7v9+1dyLscYwAAAAAAAAAAAAAAYDIu+w0OH2TSo2/Gx9kiHxCLS0veGw+JCX4rk4l8K17dvF8uh92IsNSvZL6MPksmxQ5fFe+LRe+FWbHPZ2dmok+LC5vT6+uy3l9+AAayD+M3trfFDvvNfg4Pey98ZxfEu6MjUeEHYm9ysv9J/nl1rFSSXY8qDuZz92IbqRRPiH4+uLLCLrNdfruvzzsgyqpsrlY7xwsffsyNjMiqwwmtA8cLpgZQQ0KrJyC+g/cOZI9ErxCy65EeADrV03/8iQMsCULbgz/uk3OJPxZOLie7LukBoGu8c1eknHIqxT6yX+xfvX7iQEODQNd4fk1UnTvLy36Dp0tiZC+/UU1XKrLrk/4ZoFVD3Bd8XuTX1th1dpH1RiJ+DdHtM4Iu6ww8ALo1yPR1hRYAXRtm2jpCDwDRtYG61k2UCQDRpaG61OlHuQAQVRusal2dUjYARJWGq1JHtykfABLWAEwdPNEmACSogZg+eKJdAIisAdkyeKJtAEi3Bmbb4In2ASCdDrDnrTvd87nRsG3wxJgAkNPuunl/t7lJY8rgiXEBIG2fEVoxfPAkvBtCJKNtaPGJx9zXU1Mt70doZsngibEBIHSNZ/vsK0+4btj1qAaXgFYsORMYFwB8CDwdYy4Bnd56ZeutakT7MwC+CDobbQOAr4K7Q7sAYDOou7QJALaD5VA+AKoMQJU6uk3ZAKjacFXr6pRyAdClwbrU6UeZAOjaUF3rJqEHQPcG6r4O/DTM8nXhx6GWrzOwAOjSENvWLX0zyGvAK15yk6WSag2Qre0bU5o2neqDubHYQiIhuz7pAfAefmTpdiuhddE6/YLg7orzTqNQkF1XeNvBlgy+WdtBCOgZQdLRY+IOo9k/8XSt9ldkb8Zfbm0FdYpTHfWhuT/e4/UAAAAAAAAAAAAAAADO4D9cvzD+Ik3LBAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wNy0yOFQyMjo1MjoyMiswODowMMq1zi4AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMDctMjhUMjI6NTI6MjIrMDg6MDC76HaSAAAASHRFWHRzdmc6YmFzZS11cmkAZmlsZTovLy9ob21lL2FkbWluL2ljb24tZm9udC90bXAvaWNvbl83NW1saHp1bGx3NS9jbG9zZS5zdmcxNhK3AAAAAElFTkSuQmCC'

baseComponent({
    properties: {
        prefixCls: {
            type: String,
            value: 'wux-notice-bar',
        },
        icon: {
            type: String,
            value: notice,
        },
        content: {
            type: String,
            value: '',
        },
        mode: {
            type: String,
            value: '',
        },
        action: {
            type: String,
            value: close,
        },
        loop: {
            type: Boolean,
            value: false,
        },
        leading: {
            type: Number,
            value: 500,
        },
        trailing: {
            type: Number,
            value: 800,
        },
        speed: {
            type: Number,
            value: 25,
        },
    },
    data: {
        animatedWidth: 0,
        overflowWidth: 0,
        visible: true,
    },
    computed: {
        classes: ['prefixCls', function(prefixCls) {
            const wrap = classNames(prefixCls)
            const hd = `${prefixCls}__hd`
            const icon = `${prefixCls}__icon`
            const bd = `${prefixCls}__bd`
            const container = `${prefixCls}__marquee-container`
            const marquee = `${prefixCls}__marquee`
            const ft = `${prefixCls}__ft`
            const action = `${prefixCls}__action`

            return {
                wrap,
                hd,
                icon,
                bd,
                container,
                marquee,
                ft,
                action,
            }
        }],
    },
    observers: {
        content() {
            this.resetAnimation()
        },
    },
    methods: {
        clearMarqueeTimer() {
            if (this.marqueeTimer) {
                clearTimeout(this.marqueeTimer)
                this.marqueeTimer = null
            }
        },
        startAnimation() {
            this.clearMarqueeTimer()
            const { overflowWidth, loop, leading, trailing, speed } = this.data
            const isLeading = this.data.animatedWidth === 0
            const timeout = isLeading ? leading : speed
            const animate = () => {
                let animatedWidth = this.data.animatedWidth + 1
                const isRoundOver = animatedWidth > overflowWidth

                // 判断是否完成一次滚动
                if (isRoundOver) {
                    if (!loop) return
                    // 重置初始位置
                    animatedWidth = 0
                }

                // 判断是否等待一段时间后进行下一次滚动
                if (isRoundOver && trailing) {
                    setTimeout(() => {
                        this.setData({ animatedWidth })
                        this.marqueeTimer = setTimeout(animate, speed)
                    }, trailing)
                } else {
                    this.setData({ animatedWidth })
                    this.marqueeTimer = setTimeout(animate, speed)
                }
            }

            if (this.data.overflowWidth !== 0) {
                this.marqueeTimer = setTimeout(animate, timeout)
            }
        },
        initAnimation(isForce) {
            const { prefixCls } = this.data

            useRect([`.${prefixCls}__marquee-container`, `.${prefixCls}__marquee`], this)
                .then((rects) => {
                    if (rects.filter((n) => !n).length) return

                    const [container, text] = rects
                    const overflowWidth = text.width - container.width

                    if (this.data.overflowWidth !== overflowWidth || isForce) {
                        this.setData({ overflowWidth, animatedWidth: 0 }, () => {
                            // 当文本内容存在且长度可滚动时，才触发动画
                            if (text.width > 0 && overflowWidth > 0) {
                                this.startAnimation()
                            } else {
                                this.clearMarqueeTimer()
                            }
                        })
                    }
                })
        },
        resetAnimation() {
            this.initAnimation(true)
        },
        stopAnimation() {
            this.clearMarqueeTimer()
        },
        onAction() {
            if (this.data.mode === 'closable') {
                this.clearMarqueeTimer()
                this.setData({ visible: false })
            }
            this.triggerEvent('click')
        },
        onClick() {
            this.triggerEvent('click')
        },
    },
    ready() {
        this.initAnimation()
    },
    detached() {
        this.clearMarqueeTimer()
    },
})
