import Foundation
import ComposeApp

// MARK: - KotlinDouble Extensions (for Kotlin Multiplatform interop)

extension KotlinDouble {
    /// Formats as currency (e.g., "$1,234.56")
    func toCurrency() -> String {
        self.doubleValue.toCurrency()
    }

    /// Formats with comma separators (e.g., "1,234.56")
    func toDecimalString(fractionDigits: Int = 2) -> String {
        self.doubleValue.toDecimalString(fractionDigits: fractionDigits)
    }
}

// MARK: - Cached NumberFormatters

/// Static cached NumberFormatter instances to avoid per-call allocation overhead.
/// These formatters are mutated per-call for variable parameters (fractionDigits, currencyCode)
/// and are safe because all callers run on the main thread (@MainActor ViewModels / SwiftUI views).
private enum CachedFormatters {
    static let currency: NumberFormatter = {
        let f = NumberFormatter()
        f.numberStyle = .currency
        f.currencyCode = "USD"
        return f
    }()

    static let decimal: NumberFormatter = {
        let f = NumberFormatter()
        f.numberStyle = .decimal
        return f
    }()

    static let percent: NumberFormatter = {
        let f = NumberFormatter()
        f.numberStyle = .percent
        return f
    }()
}

// MARK: - Double Extensions for Currency and Number Formatting

extension Double {
    /// Formats as currency (e.g., "$1,234.56")
    func toCurrency() -> String {
        let formatter = CachedFormatters.currency
        formatter.currencyCode = "USD"
        return formatter.string(from: NSNumber(value: self)) ?? "$\(self)"
    }

    /// Formats as currency with currency symbol (e.g., "$1,234.56")
    func toCurrencyString(currencyCode: String = "USD") -> String {
        let formatter = CachedFormatters.currency
        formatter.currencyCode = currencyCode
        return formatter.string(from: NSNumber(value: self)) ?? "$\(self)"
    }

    /// Formats with comma separators (e.g., "1,234.56")
    func toDecimalString(fractionDigits: Int = 2) -> String {
        let formatter = CachedFormatters.decimal
        formatter.minimumFractionDigits = fractionDigits
        formatter.maximumFractionDigits = fractionDigits
        return formatter.string(from: NSNumber(value: self)) ?? String(format: "%.\(fractionDigits)f", self)
    }

    /// Formats as percentage (e.g., "45.5%")
    func toPercentage(fractionDigits: Int = 1) -> String {
        let formatter = CachedFormatters.percent
        formatter.minimumFractionDigits = fractionDigits
        formatter.maximumFractionDigits = fractionDigits
        return formatter.string(from: NSNumber(value: self / 100)) ?? "\(self)%"
    }

    /// Formats file size in bytes to human-readable format
    func toFileSize() -> String {
        var size = self
        let units = ["B", "KB", "MB", "GB", "TB"]
        var unitIndex = 0

        while size >= 1024 && unitIndex < units.count - 1 {
            size /= 1024
            unitIndex += 1
        }

        return String(format: "%.1f %@", size, units[unitIndex])
    }

    /// Rounds to specified decimal places
    func rounded(to places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}

// MARK: - Int Extensions

extension Int {
    /// Formats with comma separators (e.g., "1,234")
    func toFormattedString() -> String {
        let formatter = CachedFormatters.decimal
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 0
        return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
    }

    /// Converts bytes to human-readable file size
    func toFileSize() -> String {
        Double(self).toFileSize()
    }

    /// Returns plural suffix based on count
    func pluralSuffix(_ singular: String = "", _ plural: String = "s") -> String {
        self == 1 ? singular : plural
    }
}

