import toHex from 'colornames'
import { utils } from 'pixi.js'

export * from "./eventify"
export * from "./extend"
export * from "./usesify"

export function string2hex(string: any) {
    if (typeof string === 'string') {
        let str
        if (string.startsWith('#') || string.startsWith('0x')) {
            str = string
        } else {
            const hex = toHex.get(string)
            if (hex) str = hex.value
        }
        if (!str) {
            warn('the color value is invalid')
            return str
        } else {
            return utils.string2hex(str)
        }
    } else {
        return string
    }
}

export function forin(object: object, fn: (key?: string, value?: any) => void) {
    if (typeof object === 'object') {
        for (const key in object) {
            if (object.hasOwnProperty(key)) {
                const value = object[key]
                fn(key, value)
            }
        }
    }
}

export function type(object: any) {
    const class2type = {}
    const type = class2type.toString.call(object)
    const typeString = 'Boolean Number String Function Array Date RegExp Object Error Symbol'

    if (object == null) return object + ''

    typeString.split(' ').forEach((type) => {
        class2type[`[object ${type}]`] = type.toLowerCase()
    })

    const isObject = typeof object === 'object'
    const isFn = typeof object === 'function'
    return isObject || isFn ? class2type[type] || 'object' : typeof object
}

export const getValue = (root: any, get: string) => {
    if (typeof (root) !== 'object' || type(root) === 'null') return root
    let value = root
    const keyArr = get.split('.')
    for (let i = 0, l = keyArr.length; i < l; i++) {
        const v = keyArr[i]
        if (v) {
            value = value[v]
            if (typeof (value) !== 'object') break
        }
    }
    return value
}

export const setValue = (tar: any, key: string, value: any) => {
    if (type(tar) !== 'object') {
        error('setValue tar muse be a object!')
    } else {
        const pIndex = key.trim().indexOf('.')
        if (pIndex > 0 && pIndex < key.length - 1) {
            const keyArr = key.trim().split('.')
            let _obj = tar
            for (let i = 0, l = keyArr.length - 1; i < l; i++) {
                const v = keyArr[i]
                const typeValue = type(_obj[v])
                if (typeValue === 'object') {
                    _obj = _obj[v]
                } else if (typeValue === 'undefined') {
                    _obj[v] = {}
                    _obj = _obj[v]
                }
            }

            const lastKey = keyArr[keyArr.length - 1]
            _obj[lastKey] = value
        } else {
            tar[key.replace(/\./g, '')] = value
        }
    }
    return tar
}

export const getCoverRect = (target: any) => {
    const { width: cw, height: ch } = target.getGlobalBounds()
    const { x: scaleX, y: scaleY } = target.layout.realScale
    const { anchor = { x: .5, y: .5 } } = target.layout.style
    const width = cw / scaleX
    const height = ch / scaleY
    const x = - width * anchor.x
    const y = - height * anchor.y
    return { x, y, width, height }
}

export function mountApi(instance: any, from: string, apis: Array<string | { [key: string]: string }>) {
    const _fromObj = getValue(instance, from)
    apis.map((api: string | object) => {
        if (typeof api === 'string') {
            instance[api] = (...extra) => _fromObj[api](...extra)
        } else if (typeof api === 'object') {
            forin(api, (key: string, value: string) => {
                instance[key] = (...extra) => _fromObj[value](...extra)
            })
        }
    })
}

export function error(msg: string) {
    throw Error(`[@amoy/components]Error: ${msg};`)
}

export function warn(msg: string) {
    console.warn(`[@amoy/components]Warn: ${msg};`)
}
