using SignalsTest;
using System;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Newtonsoft.Json;

public class Picasso{
    public static void DrawChart(List<TAReport> reports, decimal max, decimal min, string filename="test"){
        // float height = (float)Math.Ceiling(max - min) * 2f;
        // float width = ((float)height / 9f) * 16f;
        float multiplier = 1;
        if(min < 1000){
            multiplier = 10000;
        }
        float heightRange = (float)Math.Ceiling((float)(max - min) * multiplier);
        float height=1080;
        float width = 1920;
        float widthMultiplier = width / (float)reports.Count;
        using (Image img = new Image<Rgba32>((int)width + 100, (int)height)){
            
            //Draw Candles
            for(int i=0; i < reports.Count; i++){
                // img.Mutate(ctx=> ctx.DrawLine()))
                PointF[] points = new PointF[2];
                points[0] =new PointF(i * widthMultiplier, (float)(reports[i].candle.Open - min) * multiplier);
                points[1] =new PointF(i * widthMultiplier, (float)(reports[i].candle.Close - min)* multiplier);

                PointF[] rangePoints = new PointF[2];
                rangePoints[0] = new PointF(i * widthMultiplier, (float)(reports[i].candle.High-min)* multiplier);
                rangePoints[1] = new PointF(i * widthMultiplier, (float)(reports[i].candle.Low-min)* multiplier);

                img.Mutate(ctx=> ctx.DrawLine(reports[i].candle.Close > reports[i].candle.Open ? Color.Green : Color.Red, 10, points).DrawLine(
                    reports[i].candle.Close > reports[i].candle.Open ? Color.Green : Color.Red, 3, rangePoints
                ));

            }
            // Console.WriteLine("Getting paths");
            // object t = GetPropByName(reports[reports.Count- 1], "SMA7");
            // Console.WriteLine(t);
            // Console.WriteLine(float.Parse(t.ToString()));
            
            //Overlay
            IPath sma7Path = GetPath(reports, "SMA7", widthMultiplier,heightRange, (float)min);
            IPath sma25Path = GetPath(reports, "SMA25", widthMultiplier,heightRange, (float)min);
            IPath stPath = GetPath(reports, "ST", widthMultiplier,heightRange, (float)min);

            //NewChart
            FontFamily fontFamily;
            float TextFontSize = 64f;
            string TextFont = "Arial";
            if (!SystemFonts.TryGet(TextFont, out fontFamily))
                throw new Exception($"Couldn't find font {TextFont}");

            var font = fontFamily.CreateFont(TextFontSize, FontStyle.Regular);

            img.Mutate(ctx => ctx.Draw(Color.Yellow, 2, sma7Path).
            Draw(Color.Purple, 2, sma25Path).
            Draw(Color.Green, 3, stPath).
            Flip(FlipMode.Vertical).
            DrawText(filename, font,new Color(Rgba32.ParseHex("#000000FF")), new PointF(10,10)));
            
            img.Save($"{filename}.png");
        }
    }

    static IPath GetPath(List<TAReport> reports, string propName, float widthMultiplier,float heightRange, float min, float offset =0){
        PathBuilder builder = new PathBuilder();
        builder.SetOrigin(new PointF(0,0));
        float multiplier = 1;
        if(min < 1000){
            multiplier = 10000;
        }
        for(int i=0; i < reports.Count; i++){
            float newVal = float.Parse(GetPropByName(reports[i],propName).ToString() ?? "0");
           // Console.WriteLine( newVal);

            float prevVal = i > 0 ? float.Parse(GetPropByName(reports[i-1],propName).ToString() ?? "0") : 0;
           // Console.WriteLine( prevVal);
            float preValY = (prevVal * multiplier) - (min * multiplier);
            float newValY=(newVal* multiplier) - (min* multiplier);
            PointF prevPoint = new PointF((i-1)* widthMultiplier, preValY);
            PointF newPoint = new PointF(i * widthMultiplier, newValY);
            // Console.WriteLine(newValY);
            builder.AddLine(prevPoint, newPoint);
        }

        return builder.Build();
    }

    static object GetPropByName(TAReport report, string propName){
        string json = report.toJson();
        Dictionary<string,string> dic = JsonConvert.DeserializeObject<Dictionary<string,string>>(json) ?? new Dictionary<string, string>();
       // Console.WriteLine(dic[propName]);
        return dic[propName];
    }
}