using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Reflection;
using System.Data.SqlClient;

namespace XMLExtractor
{
    public class ChartMediaDeiPrezzi {
        public string asseX { get; set; }
        public string asseY { get; set; }
        public string descrizione { get; set; }
        public string posizione { get; set; }
        public List<ValueMediaDeiPrezzi> listMediaPrezzi { get; set; }
        public int idCapitolo { get; set; }
        public int idSezione { get; set; }
        public int idPagina { get; set; }
        public int idOrdinamento { get; set; }
        public List<Legenda> legenda { get; set; }
        //public List<Nota> note { get; set; }

        public void writeDB(SqlConnection conn)
        {

            string sqlCommand = "(idREP_IMM_MON_Grafico, idREP_IMM_MON_Pagina, idTipologia, descrizione, asseX, asseY, posizione, "
                + "idREP_IMM_MON_Legenda) VALUES (@idREP_IMM_MON_Grafico, @idREP_IMM_MON_Pagina, @idTipologia, @descrizione, "
                + "@asseX, @asseY, @posizione, @idREP_IMM_MON_Legenda)";
            SqlCommand insertTo = new SqlCommand("INSERT INTO REP_IMM_MON_Grafici " + sqlCommand, conn);
            int primaryKey = Convert.ToInt32((new SqlCommand("SELECT count(*) from REP_IMM_MON_Grafici", conn)).ExecuteScalar()) + 1;
            insertTo.Parameters.AddWithValue("@idREP_IMM_MON_Grafico", primaryKey);
            insertTo.Parameters.AddWithValue("@idREP_IMM_MON_Pagina", this.idPagina);
            insertTo.Parameters.AddWithValue("@idTipologia", 2);
            insertTo.Parameters.AddWithValue("@descrizione", this.descrizione);
            insertTo.Parameters.AddWithValue("@asseX", this.asseX);
            insertTo.Parameters.AddWithValue("@asseY", this.asseY);
            insertTo.Parameters.AddWithValue("@posizione", this.posizione);
            insertTo.Parameters.AddWithValue("@idREP_IMM_MON_Legenda", Legenda.writeDB(conn, this.legenda));
           
            int rowsUpdatedInserted = insertTo.ExecuteNonQuery();
            if (rowsUpdatedInserted != 0)
                foreach(var item in this.listMediaPrezzi)
                    item.writeDB(conn, primaryKey);
        }

        public List<string> getProperties() {
            List<string> properties = new List<string>();
            ChartMediaDeiPrezzi objectChart = new ChartMediaDeiPrezzi();
            foreach (var prop in objectChart.GetType().GetProperties())
            {
                properties.Add(prop.Name.ToLower());
            }

            properties.Remove("idcapitolo");
            properties.Remove("idsezione");
            properties.Remove("idordinamento");
            properties.Remove("idpagina");
            //properties.Remove("note");
            return properties;
        }

        public static void writeChartMediaDeiPrezzi(XmlNode attribute, List<string> tagList, string nextTag, Data data)
        {
            ChartMediaDeiPrezzi chart = new ChartMediaDeiPrezzi();
            ValueMediaDeiPrezzi chartValues = new ValueMediaDeiPrezzi();
            List<Legenda> legendaList = new List<Legenda>();
            List<ValueMediaDeiPrezzi> chartValuesList = new List<ValueMediaDeiPrezzi>();
            List<String> chartAttributes = chart.getProperties();
            PropertyInfo propertyInfo;
            //bool presenzaNota = attribute.ChildNodes.Cast<XmlNode>().Any(x => x.Name.Equals("note"));
            //if (presenzaNota)
                //chartAttributes.Add("note");
                
            foreach (XmlNode attr in attribute.ChildNodes)
            {
                //if (attr.Name.ToString().Equals("note"))
                    //chartAttributes.Add("note");

                if (!tagList.Contains(attr.Name.ToString()))
                {
                    if (!attr.Name.ToLower().Equals("listmediaprezzi") && !attr.Name.ToLower().Equals("legenda") /*&& !attr.Name.ToLower().Equals("note")*/)
                    {
                        propertyInfo = chart.GetType().GetProperty(attr.Name);
                        propertyInfo.SetValue(chart, Convert.ChangeType(attr.InnerText, propertyInfo.PropertyType), null);
                        chartAttributes.Remove(attr.Name.ToLower());
                    }
                    else
                    {
                        if (attr.Name.ToLower().Equals("listmediaprezzi")) {
                            //foreach (XmlNode listAttr in attr.ChildNodes)
                            chartValuesList = ValueMediaDeiPrezzi.getMediaDeiPrezzi(attr);
                            propertyInfo = chart.GetType().GetProperty(attr.Name);
                            propertyInfo.SetValue(chart, Convert.ChangeType(chartValuesList, propertyInfo.PropertyType), null);
                        }
                        else /*if (attr.Name.ToLower().Equals("legenda"))*/
                        {
                            legendaList = Legenda.getLegenda(attr);
                            propertyInfo = chart.GetType().GetProperty(attr.Name);
                            propertyInfo.SetValue(chart, Convert.ChangeType(legendaList, propertyInfo.PropertyType), null);

                        }

                        /*else 
                        {
                            propertyInfo = chart.GetType().GetProperty(attr.Name);
                            propertyInfo.SetValue(chart, Convert.ChangeType(Nota.getNote(attr), propertyInfo.PropertyType), null);

                        }*/
                        
                        chartAttributes.Remove(attr.Name.ToLower());
                    }
                    if (!(chartAttributes.Count > 0))
                    {
                        chart.idCapitolo = ReadXML.idCapitolo;
                        chart.idSezione = ReadXML.idSezione;
                        chart.idOrdinamento = ReadXML.idOrdinamento;
                        chart.idPagina = ReadXML.idPagina;
                        ReadXML.idOrdinamento++;
                        data.chartMediaDeiPrezziList.Add(chart);
                        chart = new ChartMediaDeiPrezzi();
                        chartValues = new ValueMediaDeiPrezzi();
                        chartAttributes = chart.getProperties();
                    }
                }
                else ReadXML.extractTag(attr, attr.Name.ToString());
            }
        }

        public class ValueMediaDeiPrezzi
        {
            public string key { get; set; }
            public double valMin { get; set; }
            public double valMax { get; set; }
            public double prezzo1 { get; set; }
            public double prezzo2 { get; set; }
            public string mesi { get; set; }

            public void writeDB(SqlConnection conn, int primaryKey)
            {
                string sqlCommand = "(idREP_IMM_MON_PuntiGrafico, idREP_IMM_MON_Grafico, chiave, valMin, valMax, prezzo1, prezzo2, mesi) "
                    + "VALUES (@idREP_IMM_MON_PuntiGrafico, @idREP_IMM_MON_Grafico, @chiave, @valMin, @valMax, @prezzo1, @prezzo2, @mesi) ";


                SqlCommand insertTo = new SqlCommand("INSERT INTO REP_IMM_MON_PuntiGrafico " + sqlCommand, conn);
                insertTo.Parameters.AddWithValue("@idREP_IMM_MON_Grafico", primaryKey);
                insertTo.Parameters.AddWithValue("@idREP_IMM_MON_PuntiGrafico", Convert.ToInt32((new SqlCommand("SELECT count(*) from REP_IMM_MON_PuntiGrafico", conn)).ExecuteScalar()) + 1);
                insertTo.Parameters.AddWithValue("@chiave", this.key);
                insertTo.Parameters.AddWithValue("@valMin", this.valMin);
                insertTo.Parameters.AddWithValue("@valMax", this.valMax);
                insertTo.Parameters.AddWithValue("@prezzo1", this.prezzo1);
                insertTo.Parameters.AddWithValue("@prezzo2", this.prezzo2);
                insertTo.Parameters.AddWithValue("@mesi", this.mesi);

                int rowsUpdatedInserted = insertTo.ExecuteNonQuery();
            }

            public static List<ValueMediaDeiPrezzi> getMediaDeiPrezzi(XmlNode attr)
            {
                ValueMediaDeiPrezzi valueMediaDeiPrezziObject = new ValueMediaDeiPrezzi();
                List<ValueMediaDeiPrezzi> valueMediaDeiPrezziList = new List<ValueMediaDeiPrezzi>();
                foreach (XmlNode innerAttr in attr.ChildNodes)
                {
                    foreach (XmlNode inner in innerAttr.ChildNodes)
                    {
                        PropertyInfo propertyInfo = valueMediaDeiPrezziObject.GetType().GetProperty(inner.Name);
                        if (inner.Name.Equals("mesi") || inner.Name.Equals("key"))
                            propertyInfo.SetValue(valueMediaDeiPrezziObject, Convert.ChangeType(inner.InnerText, propertyInfo.PropertyType), null);
                        else
                        {
                            string valore = inner.InnerText.Replace(".", ",");
                            propertyInfo.SetValue(valueMediaDeiPrezziObject, Convert.ChangeType(Convert.ToDecimal(valore), propertyInfo.PropertyType), null);

                        }
                    }
                    valueMediaDeiPrezziList.Add(valueMediaDeiPrezziObject);
                    valueMediaDeiPrezziObject = new ValueMediaDeiPrezzi();
                }
                return valueMediaDeiPrezziList;
            }
        }
        
    }
}
