using OxyPlot;
using OxyPlot.Annotations;
using OxyPlot.Axes;
using OxyPlot.Legends;
using OxyPlot.Series;
using OxyPlot.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using static ExampleLibrary.RenderingCapabilities;

namespace Txgy.EWS.Client.Common.Helpers
{
    public class ReportFreqImage
    {
        public int SeriesCount { get; set; }
        public string Title { get; set; }
        public string SubTitle { get; set; } = "";
        public Legend PlotLegend { get; set; }
        public bool ShowLabel { get; set; }
        public OxyColor Background { get; set; } = OxyColors.White;
        public List<LabelPlacement> Placements { get; set; } = new List<LabelPlacement>();
        public List<BarSeries> BarSeriesList { get; set; } = new List<BarSeries>();

        public CategoryAxis categoryAxes { get; set; } = new CategoryAxis();
        public PlotModel plotModel { get; set; }
        public LinearAxis linearAxis { get; set; } = new LinearAxis();
        public List<string> categoryColors = new List<string>();
        public ReportFreqImage()
        {
            //OxyColor.Parse
        }
        public ReportFreqImage(string title, OxyColor background)
        {
            this.Title = title;
            this.Background = background;
            this.plotModel = new PlotModel { Title = title };
        }
        public void AddSeries(string seriesTitle, OxyColor fillColor, OxyColor strokeColor, OxyColor textColor, LabelPlacement placement, List<double> values, double strokeThickness = 0, string labelFormatString = "{0}", double fontSize = 12, double fontWeight = 5)
        {
            var s1 = new BarSeries
            {
                Title = seriesTitle,
                IsStacked = true,
                StrokeColor = strokeColor,
                StrokeThickness = strokeThickness,
                FontSize = fontSize,
                FontWeight = fontWeight,
                TextColor = textColor,
                FillColor = fillColor
            };
            double sum = values.Sum();
            if (sum > 0)
            {
                s1.LabelPlacement = placement;
                s1.LabelFormatString = labelFormatString;
            }
            foreach (var item in values)
            {
                s1.Items.Add(new BarItem { Value = item });
            }
            this.BarSeriesList.Add(s1);
        }
        public void SetSeriesValues(int index, List<double> values)
        {
            foreach (double value in values)
            {
                this.BarSeriesList[index].Items.Add(new BarItem { Value = value });
            }
        }
        public System.Windows.Media.Imaging.BitmapSource ExportToBitmap(int height = 800, int width = 1200)
        {
            var exporter = new PngExporter() { Width = width, Height = height };
            return exporter.ExportToBitmap(this.plotModel);
        }
        public bool ExportPng(string filename, int height = 800, int width = 1200)
        {
            try
            {
                var pngExporter = new PngExporter { Height = height, Width = width };
                pngExporter.ExportToFile(this.plotModel, filename);
               
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        public void CreateModeWithValues(string title, OxyColor background, bool transpose, double titleFontSize = 20, string titleFontName = "微软雅黑", double titleFontWeight = 10)
        {
            this.plotModel = new PlotModel { Title = title };
            this.plotModel.TitleFontSize = titleFontSize;
            this.plotModel.TitleFont = titleFontName;
            this.plotModel.TitleFontWeight = titleFontWeight;
            this.plotModel.Background = background;
            this.plotModel.Legends.Add(this.PlotLegend);

            foreach (var item in this.BarSeriesList)
            {
                this.plotModel.Series.Add(item);
            }
            this.plotModel.Axes.Add(categoryAxes);
            this.plotModel.Axes.Add(linearAxis);
            if (this.SubTitle != "")
            {
                //this.plotModel.Annotations.Add();
                this.plotModel.Annotations.Add(new DelegateAnnotation(rc =>
                {
                    var origin = new ScreenPoint(44, 52);
                    rc.DrawText(origin, this.SubTitle, OxyColors.Black, fontSize: 20, horizontalAlignment: HorizontalAlignment.Left, verticalAlignment: VerticalAlignment.Top);
                }));
            }
            if (transpose)
            {
                Transpose(this.plotModel);
            }
            //return this.plotModel;
        }
        public PlotModel Transpose(PlotModel model)
        {
            ((IPlotModel)model).Update(updateData: false);
            foreach (Axis axis in model.Axes)
            {
                switch (axis.Position)
                {
                    case AxisPosition.Bottom:
                        axis.Position = AxisPosition.Left;
                        break;
                    case AxisPosition.Left:
                        axis.Position = AxisPosition.Bottom;
                        break;
                    case AxisPosition.Right:
                        axis.Position = AxisPosition.Top;
                        break;
                    case AxisPosition.Top:
                        axis.Position = AxisPosition.Right;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                    case AxisPosition.None:
                        break;
                }
            }

            foreach (Annotation annotation in model.Annotations)
            {
                if (annotation.XAxis != null && annotation.XAxisKey == null)
                {
                    if (annotation.XAxis.Key == null)
                    {
                        annotation.XAxis.Key = "x";
                    }

                    annotation.XAxisKey = annotation.XAxis.Key;
                }

                if (annotation.YAxis != null && annotation.YAxisKey == null)
                {
                    if (annotation.YAxis.Key == null)
                    {
                        annotation.YAxis.Key = "y";
                    }

                    annotation.YAxisKey = annotation.YAxis.Key;
                }
            }

            foreach (XYAxisSeries item in model.Series.OfType<XYAxisSeries>())
            {
                if (item.XAxisKey == null)
                {
                    if (item.XAxis == null)
                    {
                        item.XAxisKey = "x";
                    }
                    else
                    {
                        if (item.XAxis.Key == null)
                        {
                            item.XAxis.Key = "x";
                        }

                        item.XAxisKey = item.XAxis.Key;
                    }
                }

                if (item.YAxisKey != null)
                {
                    continue;
                }

                if (item.YAxis == null)
                {
                    item.YAxisKey = "y";
                    continue;
                }

                if (item.YAxis.Key == null)
                {
                    item.YAxis.Key = "y";
                }

                item.YAxisKey = item.YAxis.Key;
            }

            return model;
        }
    }
}
