/**
 * logger
 *
 * @author Cator Vee  hi@catorv.com
 */
const info = require('../../package.json')
const { isWindows } = require('./platform')

const levelValue = { info: 1, error: 2, warning: 3, debug: 4, trace: 5 }
const commands = ['error', 'warn', 'info', 'log', 'debug', 'trace']
const alias = { warn: 'warning', log: 'info' }

const LOG_LEVEL = (process.env.LOG_LEVEL || 'error').toLowerCase()
const level = levelValue[alias[LOG_LEVEL] || LOG_LEVEL]

const original = {}

commands.forEach(command => {
    original[command] = console[command]
    console[command] = function () {
        if (levelValue[alias[command] || command] > level) return
        let args = Array.from(arguments)
        if (command === 'debug' && args.length > 0 && typeof args[0] === 'string') {
            args[0] = '[DEBUG] ' + args[0]
        }
        if (command === 'error' && args.length > 0 && typeof args[0] === 'string') {
            args[0] = '[ERROR] ' + args[0]
        }
        spinner.stop()
        original[command].apply(console, args)
    }
})

/**
 * 显示错误信息并中断程序的执行
 */
console.fatal = function () {
    console.error.apply(console, arguments)
    process.exit(1)
}

/**
 * 显示执行步骤信息
 */
console.step = function () {
    if (!isWindows()) {
        console.log.apply(console, ['\033[36m-'].concat(Array.from(arguments)).concat('\033[0m'))
    } else {
        console.log.apply(console, ['-'].concat(Array.from(arguments)))
    }
}

/**
 * 显示操作成功信息
 */
console.ok = function () {
    if (!isWindows()) {
        console.log.apply(console, ['\033[32m[√]\033[0m'].concat(Array.from(arguments)))
    } else {
        console.log.apply(console, ['[√]'].concat(Array.from(arguments)))
    }
}

/**
 * 显示操作失败信息
 */
console.fail = function () {
    if (!isWindows()) {
        console.log.apply(console, ['\033[31m[x]\033[0m'].concat(Array.from(arguments)))
    } else {
        console.log.apply(console, ['[x]'].concat(Array.from(arguments)))
    }
}

console.printLogo = () => {
    console.log(`      _   _ ____  ____  
__  _| | | |  _ \\|  _ \\ 
\\ \\/ / | | | |_) | | | |
 >  <| |_| |  __/| |_| |
/_/\\_\\\\___/|_|   |____/  Version ${info.version}
`)
}

const SPINNER_COLOR_B = '\033[33m'
const SPINNER_COLOR_E = '\033[0m'

class Spinner {
    running = false
    timer = null
    // ['|/-\\', '⠂-–—–-', '◐◓◑◒', '◴◷◶◵', '◰◳◲◱', '▖▘▝▗', '■□▪▫', '▌▀▐▄', '▉▊▋▌▍▎▏▎▍▌▋▊▉', '▁▃▄▅▆▇█▇▆▅▄▃', '←↖↑↗→↘↓↙', '┤┘┴└├┌┬┐', '◢◣◤◥', '.oO°Oo.', '.oO@*', '🌍🌎🌏', '◡◡ ⊙⊙ ◠◠', '☱☲☴', '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏', '⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓', '⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆', '⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋', '⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁', '⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈', '⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈', '⢄⢂⢁⡁⡈⡐⡠', '⢹⢺⢼⣸⣇⡧⡗⡏', '⣾⣽⣻⢿⡿⣟⣯⣷', '⠁⠂⠄⡀⢀⠠⠐⠈'];
    chars = '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
    step = 0

    start () {
        if (!this.running) {
            this.running = true
            this.run()
        }
    }

    run () {
        let char = this.chars[this.step]
        if (!isWindows()) {
            process.stdout.write(SPINNER_COLOR_B + ' ' + char + SPINNER_COLOR_E + '\b\b')
        } else {
            process.stdout.write(' ' + char + '\b\b')
        }
        this.step = (this.step + 1) % this.chars.length
        this.timer = setTimeout(() => this.run(), 150)
    }

    stop () {
        if (this.running) {
            clearTimeout(this.timer)
            this.running = false
            process.stdout.write('  \b\b')
        }
    }
}

const spinner = new Spinner()

console.spin = () => {
    spinner.start()
    return spinner
}