namespace InnovEnergy.Lib.Units;

public static class Units
{
    public static Byte DisplaySignificantDigits { get; set; } = 3;
    public static Byte JsonSignificantDigits    { get; set; } = 3;
    
    public static Current       A      (this Decimal value) => value;
    public static Voltage       V      (this Decimal value) => value;
    public static Power         W      (this Decimal value) => value;
    public static ReactivePower Var    (this Decimal value) => value;
    public static ApparentPower Va     (this Decimal value) => value;
    public static Resistance    Ohm    (this Decimal value) => value;
    public static Frequency     Hz     (this Decimal value) => value;
    public static Angle         Rad    (this Decimal value) => value;
    public static Temperature   Celsius(this Decimal value) => value;
    public static Energy        KWh    (this Decimal value) => value;
    public static Percent       Percent(this Decimal value) => value;
}

public static class Prefixes
{
    private static readonly IReadOnlyList<String> Big = new[]
    {
        "",
        "k",
        "M",
        "G",
        "T",
        "P",
        "E",
        "Y",
    };

    private static readonly IReadOnlyList<String> Small = new[]
    {
        "", 
        "m",
        "ยต",
        "n",
        "p",
        "f",
        "a",
        "z",
        "y",
    };

    public static String TestGetPrefix(Double v, String unit)
    {
        if (v == 0)
            return "";

        var log10 = Math.Log10(v / 10);
        var l = (Int32)Math.Floor(log10 / 3);
        var lookUp = l > 0 ? Big : Small;
        var i = Math.Abs(l);

        return $"{v / Math.Pow(10.0, l * 3.0)} {lookUp[i]}{unit}";
    }
    
    
    public static String TestGetPrefix(Decimal v, String unit)
    {
        if (v == 0m)
            return "";

        var d = (Double)v;
        var log10 = Math.Log10(d / 10);
        var l = (Int32)Math.Floor(log10 / 3);
        var lookUp = l > 0 ? Big : Small;
        var i = Math.Abs(l);

        return $"{d / Math.Pow(10.0, l * 3.0)} {lookUp[i]}{unit}";
    }
    
    public static String TestGetPrefix2(Decimal v, String unit)
    {
        if (v == 0m)
            return "";

        var a = Math.Abs(v);
        var s = Math.Sign(v);
        
        var i = 0;

        while (a >= 10000m)
        {
            a /= 1000;
            i++;
        }
        while (a < 10m)
        {
            a *= 1000;
            i--;
        }

        var lookUp = i >= 0 ? Big : Small;
        
        var r = Decimal.Floor(a * 10m) / 10m;      

        return $"{r*s} {lookUp[Math.Abs(i)]}{unit}";
    }

}