interface IOption {
    leading: boolean
}
/**
 * parse milliseconds
 * @param milliseconds
 * @returns {
 *  days: number
 *   hours: number
 *  minutes: number
 * seconds: number
 * milliseconds: number
 * }
 */
function parseMs(milliseconds: number): {
    days: number
    hours: number
    minutes: number
    seconds: number
    milliseconds: number
} {
    if (typeof milliseconds !== 'number') {
        throw new TypeError('Expected a number')
    }

    return {
        days: Math.trunc(milliseconds / 86400000),
        hours: Math.trunc(milliseconds / 3600000) % 24,
        minutes: Math.trunc(milliseconds / 60000) % 60,
        seconds: Math.trunc(milliseconds / 1000) % 60,
        milliseconds: Math.trunc(milliseconds) % 1000,
    }
}
/**
 * add Zero at the end
 * @param value
 * @param digits
 * @returns
 */
function appendZero(value: number, digits?: number): string {
    digits = digits || 2

    let str = value.toString()
    let size = 0

    size = digits - str.length + 1
    str = new Array(size).join('0').concat(str)

    return str
}

/**
 * Convert a number in milliseconds to a standard duration string.
 * @param {number} ms - duration in milliseconds
 * @param {IOption} options - formatDuration options object
 * @param {boolean} [options.leading=false] - add leading zero
 * @returns string - formatted duration string
 */
function formatDuration(ms: number, options?: IOption): string {
    const leading = options && options.leading
    const unsignedMs = ms < 0 ? -ms : ms
    const sign = ms <= -1000 ? '-' : ''
    const t = parseMs(unsignedMs)
    const seconds = appendZero(t.seconds)
    if (t.days)
        return (
            sign +
            t.days +
            ':' +
            appendZero(t.hours) +
            ':' +
            appendZero(t.minutes) +
            ':' +
            seconds
        )
    if (t.hours)
        return (
            sign +
            (leading ? appendZero(t.hours) : t.hours) +
            ':' +
            appendZero(t.minutes) +
            ':' +
            seconds
        )
    return sign + (leading ? appendZero(t.minutes) : t.minutes) + ':' + seconds
}

export { formatDuration }
export default formatDuration
