package no.svorka.mcms.core

import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone

/**
 * Parses/renders MCMS timestamps: UTC with a literal space, e.g.
 * `2026-05-04 21:51:57.394127`. Try microsecond precision first, then seconds.
 */
object MongoTimestamp {
    private val withMicros = utc("yyyy-MM-dd HH:mm:ss.SSSSSS")
    private val seconds = utc("yyyy-MM-dd HH:mm:ss")
    private val display = SimpleDateFormat("d MMM yyyy, HH:mm", Locale.getDefault())

    private fun utc(pattern: String) = SimpleDateFormat(pattern, Locale.US).apply {
        timeZone = TimeZone.getTimeZone("UTC")
        isLenient = false
    }

    fun parse(s: String?): Date? {
        if (s == null) return null
        return runCatching { withMicros.parse(s) }.getOrNull()
            ?: runCatching { seconds.parse(s) }.getOrNull()
    }

    fun displayString(s: String?): String? {
        if (s == null) return null
        val d = parse(s) ?: return s
        return display.format(d)
    }

    /** Uptime etc., computed from two MCMS timestamps so it uses the device clock. */
    fun duration(from: String?, to: String?): String? {
        val start = parse(from) ?: return null
        val end = parse(to) ?: return null
        val total = (end.time - start.time) / 1000
        if (total < 0) return null
        val days = total / 86400
        val hours = (total % 86400) / 3600
        val mins = (total % 3600) / 60
        return when {
            days > 0 -> "${days}d ${hours}h"
            hours > 0 -> "${hours}h ${mins}m"
            else -> "${mins}m"
        }
    }
}

/** Compact human formatting for counters in the UI. */
object Format {
    fun bps(value: Double?): String {
        if (value == null || value < 0) return "—"
        val units = listOf("bps", "kbps", "Mbps", "Gbps", "Tbps")
        var x = value; var i = 0
        while (x >= 1000 && i < units.size - 1) { x /= 1000; i++ }
        return if (i == 0 || x >= 100) "${x.toLong()} ${units[i]}" else "${"%.1f".format(x)} ${units[i]}"
    }

    fun bytes(value: Double?): String {
        if (value == null || value < 0) return "—"
        val units = listOf("B", "KB", "MB", "GB", "TB", "PB")
        var x = value; var i = 0
        while (x >= 1024 && i < units.size - 1) { x /= 1024; i++ }
        return if (i == 0 || x >= 100) "${x.toLong()} ${units[i]}" else "${"%.1f".format(x)} ${units[i]}"
    }

    fun percent(value: Int?): String = value?.let { "$it%" } ?: "—"
}
