import { extend } from '../../utils'
import { createStyle } from '../style'

function _class(attrs, cls: string) {
    const clsKey = attrs['class'] ? 'class' : (attrs['className'] ? 'className' : null)
    const clsArr = cls.split(' ')
    return {
        clsKey,
        clsArr,
    }
}

function addClass(this: any, cls: string) {
    const attrs = this.node.attrs
    const { clsKey, clsArr } = _class(attrs, cls)
    let changed = false

    if (clsKey) {
        clsArr.map((cls) => {
            if (!attrs[clsKey].includes(cls)) {
                attrs[clsKey] += ` ${cls}`
                changed = true
            }
        })
    } else {
        attrs['class'] = cls
        changed = true
    }
    if (changed) {
        extend(true, this, this.node.attrs)
        this.setStyle(createStyle(this.node))
    }
    return this
}
function hasClass(this: any, cls: string) {
    const attrs = this.node.attrs
    const { clsKey, clsArr } = _class(attrs, cls)
    let flag = false
    if (clsKey) {
        const match: boolean[] = []
        clsArr.map((c) => {
            if (attrs[clsKey].includes(c)) {
                match.push(true)
            }
        })
        if (match.length === clsArr.length) {
            flag = true
        }
    }
    return flag
}

function removeClass(this: any, cls: string) {
    const attrs = this.node.attrs
    const { clsKey, clsArr } = _class(attrs, cls)
    let changed = false
    if (clsKey) {
        clsArr.map((c: string) => {
            if (hasClass.bind(this)(c)) {
                attrs[clsKey] = attrs[clsKey].replace(c, '')
                changed = true
            }
        })
    }
    if (changed) {
        extend(true, this, this.node.attrs)
        this.setStyle(createStyle(this.node), {
            replaceStyle: true,
        })
    }
    return this
}
function toggleClass(this: any, cls: string) {
    const attrs = this.node.attrs
    const { clsArr } = _class(attrs, cls)

    clsArr.map((c: string) => {
        if (hasClass.bind(this)(c)) {
            removeClass.bind(this)(c)
        } else {
            addClass.bind(this)(c)
        }
    })
    return this
}

export default { addClass, removeClass, hasClass, toggleClass }
