using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using DDUtilityApp.LOGPARSER.DATA;
using JWH;
using JWH.DATA;

namespace DDUtilityApp.LOGPARSER
{

    public partial class FrmMessageReplyTime : Form
    {


        #region [ Deleage ] ===================================================
        #endregion

        #region [ Events ] ====================================================
        #endregion

        #region [ Variables ] =================================================
        #endregion

        #region [ Properties ] ================================================

        public StandardCollection StandardCollection { get; set; } = null;

        public Dictionary<string, List<StandardDataPair>> MessageCollection { get; set; } = new Dictionary<string, List<StandardDataPair>>();
        
        #endregion

        #region [ Constructor ] ===============================================

        public FrmMessageReplyTime()
        {
            InitializeComponent();

            this.SetLayout();
            this.SetEventHandler();
        }

        public FrmMessageReplyTime(StandardCollection standardCollection) : this()
        {
            this.StandardCollection = standardCollection;
        }

        private void SetLayout()
        {
            Font font = new Font("돋움체", 9);
            this.cboxMessageName.Font = font;

            this.RadGrid_Setting();
            this.Chart_Setting();
        }

        private void SetEventHandler()
        {
            this.btnGenerate.Click += this.BtnGenerate_Click;
            this.cboxMessageName.SelectedIndexChanged += this.CboxMessageName_SelectedIndexChanged;
            this.button1.Click += this.Button1_Click;
        }

        #endregion

        #region [ Control Events ] ============================================

        private void BtnGenerate_Click(object sender, EventArgs e)
        {
            this.Generate();

            List<string> lstMessage = new List<string>();
            lstMessage.Add("");
            lstMessage.AddRange(this.MessageCollection.Keys.ToArray());
            lstMessage.Sort();
            this.cboxMessageName.DataSource = lstMessage.ToArray();
            this.cboxMessageName.SelectedIndex = 0;
        }

        private void Generate()
        {
            Dictionary<string, List<StandardDataPair>> dicSrc = new Dictionary<string, List<StandardDataPair>>();

            try
            {
                this.MessageCollection.Clear();

                string[] arrServer = new string[] { "MES", "FDC", "RMS", "RTD" };
                foreach (StandardData data in this.StandardCollection)
                {
                    if (arrServer.Contains(data.Server) == false) continue;
                    if (string.IsNullOrWhiteSpace(data.TID)) continue;

                    string key = data.MessageName.Replace("Reply", "");
                    if (dicSrc.ContainsKey(key) == false)
                    {
                        dicSrc.Add(key, new List<StandardDataPair>());
                        StandardDataPair pair = dicSrc[key].Where(x => x.TID == data.TID).FirstOrDefault();
                        if (pair == null) dicSrc[key].Add(new StandardDataPair(data));
                        else pair.Add(data);
                    }
                    else
                    {
                        StandardDataPair pair = dicSrc[key].Where(x => x.TID == data.TID).FirstOrDefault();
                        if (pair == null) dicSrc[key].Add(new StandardDataPair(data));
                        else pair.Add(data);
                    }
                }

                foreach (KeyValuePair<string, List<StandardDataPair>> srcPair in dicSrc)
                {
                    string key = srcPair.Key;
                    foreach (StandardDataPair pair in srcPair.Value)
                    {
                        if (pair.Request == null || pair.Response == null) continue;

                        if (this.MessageCollection.ContainsKey(key) == false) MessageCollection.Add(key, new List<StandardDataPair>());
                        this.MessageCollection[key].Add(pair);
                    }
                }

            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        private void CboxMessageName_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.chart.Series.Clear();

            List<StandardDataPair> lst = new List<StandardDataPair>();
            if (string.IsNullOrEmpty(this.cboxMessageName.Text))
            {
                foreach (KeyValuePair<string, List<StandardDataPair>> pair in this.MessageCollection)
                {
                    lst.AddRange(pair.Value.ToArray());
                    this.Chart_AddSeries(pair.Key).Points.DataBind(pair.Value.ToArray(), "RequestTime", "Interval", "Label=Interval");
                }
            }
            else
            {
                string key = this.cboxMessageName.Text;
                if (this.MessageCollection.ContainsKey(key) == false) return;

                lst.AddRange(this.MessageCollection[key].ToArray());
                //this.Chart_AddSeries(this.cboxMessageName.Text);
                this.Chart_AddSeries(key).Points.DataBind(this.MessageCollection[key].ToArray(), "RequestTime", "Interval", "Label=Interval");
            }

            this.grid.AutoBinding(lst.ToArray());
            //this.chart.DataSource = lst.ToArray();
            //this.chart.DataBindCrossTable(lst.ToArray(), "MessageName", "RequestTime", "Interval", "Label=MessageName");
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            this.Chart_Setting();
            //this.chart.Series.Clear();
            //CartesianSeries series = this.chart.Series[0] as  CartesianSeries;
            //series.CombineMode = ChartSeriesCombineMode.None;
        }

        #endregion

        #region [ Public Method ] =============================================
        #endregion

        #region [ Method ] ====================================================

        private void RadGrid_Setting()
        {
            this.grid.MultiSelect = true;
            this.grid.Columns.Clear();
            this.grid.TableElement.RowHeight = 20;

            this.grid.AddColumn("MessageName");
            this.grid.AddColumn("RequestTime");
            this.grid.AddColumn("ResponseTime");
            this.grid.AddColumn("Interval", "", true, "{0:#,##0.000}");
        }

        private void Chart_Setting()
        {
            //this.chart.ChartAreas[0].AxisX.ScaleView.Zoom()
            //ChartArea chartArea = new ChartArea();
            //this.chart.ChartAreas.Add(chartArea);

            //Legend legend = new Legend();
            //this.chart.Legends.Add(legend);
        }

        private Series Chart_AddSeries(string name)
        {
            Series series = new Series();
            series.Name = name;
            series.LegendText = name;
            series.ChartType = SeriesChartType.Line;
            series.XValueType = ChartValueType.Time;
            series.XValueMember = "RequestTime";
            series.YValueType = ChartValueType.Double;
            series.YValueMembers = "Interval";
            this.chart.Series.Add(series);

            return series;
        }

        #endregion

    }

    public class StandardDataPair : DataTableBase
    {

        public StandardData Request { get; set; } = null;

        public StandardData Response { get; set;} = null;

        public string MessageName { get; set; } = string.Empty;

        public string TID { get; set; } = string.Empty;

        public DateTime RequestTime { get { return (this.Request == null ? DateTime.MinValue : this.Request.DateTime); } }

        public DateTime ResponseTime { get { return (this.Response == null ? DateTime.MinValue : this.Response.DateTime); } }

        public double Interval { get { return this.GetInterval(); } }

        public StandardDataPair() { }

        public StandardDataPair(params StandardData[] datas)
        {
            foreach(StandardData data in datas)
                this.Add(data);
        }

        public override string ToString()
        {
            return this.GetInterval().ToString();
        }

        public void Add(StandardData data)
        {
            if (data == null) return;

            if (string.IsNullOrWhiteSpace(this.TID)) this.TID = data.TID;
            else if (this.TID != data.TID) return;

            if (data.MessageName.ToUpper().EndsWith("Reply".ToUpper())) this.Response = data;
            else { this.Request = data; this.MessageName = data.MessageName; }
        }

        /// <summary>
        /// 응답시간(초)
        /// </summary>
        /// <returns></returns>
        public double GetInterval()
        {
            double interval = 0;
            if (this.Request == null || this.Response == null) return interval;

            TimeSpan timeSpan = this.Response.DateTime.Subtract(this.Request.DateTime);
            interval = timeSpan.TotalSeconds;

            return interval;
        }

    }


}
