import Foundation

/// Parses and renders MCMS timestamps. MCMS emits UTC timestamps with a literal
/// space (e.g. `2026-05-04 21:51:57.394127`), so `ISO8601DateFormatter` will not
/// parse them. Try microsecond precision first, then seconds (field guide
/// §3.7 / §8.5). The `en_US_POSIX` locale forces stable parse rules regardless
/// of the device's 12/24-hour setting.
enum MongoTimestamp {
    private static let withMicroseconds = parser("yyyy-MM-dd HH:mm:ss.SSSSSS")
    private static let seconds = parser("yyyy-MM-dd HH:mm:ss")

    private static func parser(_ format: String) -> DateFormatter {
        let f = DateFormatter()
        f.locale = Locale(identifier: "en_US_POSIX")
        f.timeZone = TimeZone(identifier: "UTC")
        f.dateFormat = format
        return f
    }

    static func date(from string: String) -> Date? {
        withMicroseconds.date(from: string) ?? seconds.date(from: string)
    }

    /// Human duration between two MCMS timestamps — e.g. uptime computed as
    /// (device state `Time` − `Online Time`), so it uses the device's own clock
    /// rather than the phone's. Returns nil if either is unparseable or end < start.
    static func duration(from startString: String?, to endString: String?) -> String? {
        guard let startString, let start = date(from: startString),
              let endString, let end = date(from: endString) else { return nil }
        let total = Int(end.timeIntervalSince(start))
        guard total >= 0 else { return nil }
        let days = total / 86400, hours = (total % 86400) / 3600, mins = (total % 3600) / 60
        if days > 0 { return "\(days)d \(hours)h" }
        if hours > 0 { return "\(hours)h \(mins)m" }
        return "\(mins)m"
    }

    private static let display: DateFormatter = {
        let f = DateFormatter()
        f.dateStyle = .medium
        f.timeStyle = .short
        return f
    }()

    /// Render a raw MCMS timestamp in the device's locale/zone, falling back to
    /// the original string if it doesn't parse.
    static func displayString(_ string: String?) -> String? {
        guard let string else { return nil }
        guard let date = date(from: string) else { return string }
        return display.string(from: date)
    }
}
