using System;
using System.Collections.Generic;
using System.Linq;
using Consulenza.ExternalServices;
using Consulenza.ReportWriter.Business;
using Consulenza.ReportWriter.Business.OBJ_PDF;
using System.Data;
using Consulenza.ReportWriter.Business.CHART_PDF;
using Consulenza.ReportCommon;
using Consulenza.ReportWriter.Business.Entity;

namespace Consulenza.ReportWriter.Manager.Section.Immobiliare.Diagnosi
{
    /// <summary>
    /// Distribuzione geografica Fabbricati (id 35)
    /// </summary>
    public class S3 : Entity.Section
    {
        private readonly float _xLocalizzazioneGeografica;
        private int maxRigheTabella = 10;
        private bool addNewPage = false;
        public S3(EnvironmentFacade environmentFacade, int idSection)
            : base(environmentFacade, idSection)
        {
            try
            {
                _xLocalizzazioneGeografica = EnvironmentFacade.RendererFacade.XLeftLimit + 420;
                Draw();
            }
            catch (Exception ex)
            {
                SectionLogger.Write("S3", ex.Message, SectionLoggerMessageLevel.E, EnvironmentFacade.ReportEnvironment);
            }
        }

        /// <summary>
        /// Scheda3. Patrimonio immobiliare –Distribuzione geografica (fabbricati) (distribuzione dei fabbricati del cliente divisa per Comune e categoria catastale)
        /// </summary>
        protected override sealed void Draw()
        {
            var dati = GetDataSet();
  
            if (dati.Tables[0].Rows.Count == 0) return;

            var testi = GetText();

            #region Recupero immagine della cartina

            var codiciComune = (from codice in dati.Tables[0].AsEnumerable()
                                select codice.Field<string>("codComune")).Distinct();


            var immagine = new Prometeia().GetMapComuniItaly(codiciComune.ToArray());

            #endregion

            bool cartinaPresente = immagine != null;

            ImagePDF iconaFabbricato;
            FormattedTextAreaPDF titoloFabbricato;
            ImagePDF iconaLocalizzazione = null;
            FormattedTextAreaPDF titoloLocalizzazione = null;
            ImagePDF cartina = null;

            #region Localizzazione geografica

            AddElement(new ResetterYPDF());
            AddElement(new SpacePDF(35));

            if (cartinaPresente)
            {
                iconaLocalizzazione = new ImagePDF(_xLocalizzazioneGeografica, 0.20F, "LocGeografica.png") { AutoIncrementYWritable = false };
                titoloLocalizzazione = new FormattedTextAreaPDF("Localizzazione geografica", _xLocalizzazioneGeografica + 30) { FontSize = 14, FontColor = ColorPDF.Immobiliare_Grigio_TitoloGrande };

                cartina = new ImagePDF(_xLocalizzazioneGeografica + 30, 0.35F, immagine) { AutoIncrementYWritable = true };

                AddElement(iconaLocalizzazione);
                AddElement(titoloLocalizzazione);
                AddElement(new SpacePDF(20));
                AddElement(cartina);
            }
            else
            {
                AddElement(new SpacePDF(20));
                // Al posto della cartina verrà disegnato il Grafico (definito sotto)
                AddChart(dati.Tables[2], false);
            }

            #endregion

            #region Fabbricati

            AddElement(new ResetterYPDF());
            AddElement(new SpacePDF(35));

            iconaFabbricato = new ImagePDF(EnvironmentFacade.RendererFacade.XLeftLimit, 0.20F, "Fabbricati.png") { AutoIncrementYWritable = false };
            titoloFabbricato = new FormattedTextAreaPDF("Fabbricati", 82) { FontSize = 14, FontColor = ColorPDF.Immobiliare_Grigio_TitoloGrande };

            #region Tabella

            var datiTabella = dati.Tables[1];

            #region definizione delle note

            var campiAsterisco = new[] { "comune_tipologia" }; // campi del datasource su cui aggiungere gli asterischi di rimando alla note.
            var notaUnitaUrbane = datiTabella.Select("codice_tipologia = 'F1'").Any();
            var notaUnitaCollabenti = datiTabella.Select("codice_tipologia = 'F2'").Any();
            var notaUnitaInCostruzione = datiTabella.Select("codice_tipologia = 'F3'").Any();
            var notaUnitaInDefinizione = datiTabella.Select("codice_tipologia = 'F4'").Any();
            var notaFabbricatoInAttesaDichiarazione = datiTabella.Select("codice_tipologia = 'F6'").Any();

            #endregion

            var tabella = new TablePDF(EnvironmentFacade.RendererFacade.XLeftLimit + 30, datiTabella)
            {
                Style = Style.Immobiliare,
                RowsPadding = 4
            };

            tabella.Columns.Add(new ColumnPDF("comune_tipologia", 150, HorizontalAlignmentType.Sinistra, false, false, 8, ColumnType.Testo, "comune_tipologia", "Comune / Tipologia"));
            tabella.Columns.Add(new ColumnPDF("immobili", 40, HorizontalAlignmentType.Centrato, false, false, 8, ColumnType.Intero, "numeroimmobili", "Numero<BR>immobili"));
            tabella.Columns.Add(new ColumnPDF("stimatoproprieta", 75, HorizontalAlignmentType.Destra, false, false, 8, ColumnType.Decimale, "valorestimatoproprieta", "Valore stimato<BR>pro quota (€)") { PaddingRight = 3});
            tabella.Columns.Add(new ColumnPDF("stimatototale", 80, HorizontalAlignmentType.Destra, false, false, 8, ColumnType.Decimale, "valorestimatototale", "Valore stimato<BR>totale (€)"));

            tabella.FooterColumns.Add(new ColumnPDF("comune_tipologia", 150, HorizontalAlignmentType.Sinistra, false, true, 8, ColumnType.Testo));
            tabella.FooterColumns.Add(new ColumnPDF("immobili", 40, HorizontalAlignmentType.Centrato, false, true, 8, ColumnType.Intero));
            tabella.FooterColumns.Add(new ColumnPDF("stimatoproprieta", 75, HorizontalAlignmentType.Destra, false, true, 8, ColumnType.Decimale));
            tabella.FooterColumns.Add(new ColumnPDF("stimatototale", 80, HorizontalAlignmentType.Destra, false, true, 8, ColumnType.Decimale));

            tabella.FooterCells[0, 0].Value = "Totale";
            tabella.FooterCells[1, 0].Value = Convert.ToDecimal(datiTabella.Compute("Sum(numeroimmobili)", string.Empty)).ToString();
            tabella.FooterCells[2, 0].Value = Convert.ToDecimal(datiTabella.Compute("Sum(valorestimatoproprieta)", string.Empty)).ToString();
            tabella.FooterCells[3, 0].Value = Convert.ToDecimal(datiTabella.Compute("Sum(valorestimatototale)", string.Empty)).ToString();

            #region note

            if (notaUnitaUrbane)
                tabella.Notes.Add(new TableNotePDF(TableNotePDF.TableNotePositionType.PièDiTabella, testi.Rows[0]["testo1"].ToString(), campiAsterisco, "codice_tipologia = 'F1'") { FontSize = 7 });

            if (notaUnitaCollabenti)
                tabella.Notes.Add(new TableNotePDF(TableNotePDF.TableNotePositionType.PièDiTabella, testi.Rows[0]["testo2"].ToString(), campiAsterisco, "codice_tipologia = 'F2'") { FontSize = 7 });

            if (notaUnitaInCostruzione)
                tabella.Notes.Add(new TableNotePDF(TableNotePDF.TableNotePositionType.PièDiTabella, testi.Rows[0]["testo3"].ToString(), campiAsterisco, "codice_tipologia = 'F3'") { FontSize = 7 });

            if (notaUnitaInDefinizione)
                tabella.Notes.Add(new TableNotePDF(TableNotePDF.TableNotePositionType.PièDiTabella, testi.Rows[0]["testo4"].ToString(), campiAsterisco, "codice_tipologia = 'F4'") { FontSize = 7 });

            if (notaFabbricatoInAttesaDichiarazione)
                tabella.Notes.Add(new TableNotePDF(TableNotePDF.TableNotePositionType.PièDiTabella, testi.Rows[0]["testo5"].ToString(), campiAsterisco, "codice_tipologia = 'F6'") { FontSize = 7 });

            #endregion

            //Righe separatorie.
            for (int i = 0; i < datiTabella.Rows.Count; i++)
            {
                tabella.Row[i].Border = Convert.ToBoolean(datiTabella.Rows[i]["fontbold"]) && i > 0;
                tabella.Row[i].BorderType = BorderRowType.Alto;
            }

            #endregion

            AddElement(iconaFabbricato);
            AddElement(titoloFabbricato);

            //Aggionta gestione max righe per visualizzazione grafico a pagina successiva
            addNewPage = datiTabella.Rows.Count > maxRigheTabella ? true : false;
            AddElement(new SpacePDF(20));
            if (!addNewPage)
            {
                AddElement(tabella);
                AddElement(new SpacePDF(-5));
            }
            else
            {               
           
                AddElement(tabella);
                AddElement(new PagePDF());
            }
            

            #endregion

            #region Grafico

            if (cartinaPresente)
            {
                var listaOggettiDaRipetere = new List<ObjectPDF>();

                // Ripeto la parte destra  (localizzazione geografica)
                listaOggettiDaRipetere.Add(new ResetterYPDF());
                listaOggettiDaRipetere.Add(new SpacePDF(35));
                listaOggettiDaRipetere.Add(iconaLocalizzazione);
                listaOggettiDaRipetere.Add(titoloLocalizzazione);
                listaOggettiDaRipetere.Add(new SpacePDF(20));
                listaOggettiDaRipetere.Add(cartina);

                // Ripeto la parte sinistra  (fabbricati)
                listaOggettiDaRipetere.Add(new ResetterYPDF());
                listaOggettiDaRipetere.Add(new SpacePDF(35));
                listaOggettiDaRipetere.Add(iconaFabbricato);
                listaOggettiDaRipetere.Add(titoloFabbricato);
                //listaOggettiDaRipetere.Add(new SpacePDF(10));

                AddElement(new RepeaterPDF(listaOggettiDaRipetere));

                // Aggiungo il grafico
                if ( !addNewPage)
                   AddChart(dati.Tables[2], true);
                else
                    AddChart(dati.Tables[2], true,20);
            }

            #endregion
        }

        /// <summary>
        /// Disegna il grafico. Se presente la cartina verra disegnato dopo la tabella altrimenti al posto della cartina.
        /// </summary>
        /// <param name="dati"></param>
        /// <param name="cartinaPresente"></param>
        protected virtual void AddChart(DataTable dati, bool cartinaPresente,int spazioInizale=40)
        {
            // Il grafico sarà disegnato al posto della cartina se questa non è presente
            float xGrafico = EnvironmentFacade.RendererFacade.XLeftLimit + 100;
            if (!cartinaPresente)
            {
                xGrafico = _xLocalizzazioneGeografica + 50;
                AddElement(new ResetterYPDF());
                AddElement(new SpacePDF(35));
            }

            var serieCollezione = new List<Serie>();
            var datiGrafico = dati;
            var graficoBarre = new StackedPDF(xGrafico, 1F)
            {
                HeightSingleBar = datiGrafico.Rows.Count > 13 && datiGrafico.Rows.Count != 4 ? 25 : 23,
                Width = 250,
                ShowLegend = true,
                BorderLineTop = true,
                BorderLineX = xGrafico - 100,
                BorderLineWidth = 360,
                PageBreak = datiGrafico.Rows.Count > 13,
                MarginAxisYFromTop = 0,
                MarginAxisY = datiGrafico.Rows.Count != 4 ? 7 : 5,
                DinamicFloatXEtichettaLateraleBarra = false,  
            };

            serieCollezione.Add(new Serie { Name = "ProprietaCliente", Text = "Proprietà del cliente", Color = new ColorPDF(174, 150, 81) });
            serieCollezione.Add(new Serie { Name = "ProprietaAltriIntestatari", Text = "Proprietà di altri intestatari", Color = new ColorPDF(206, 219, 209) });
           
            foreach (DataRow item in datiGrafico.Rows)
            {
                serieCollezione[0].Points.Add(new Point
                {
                    LabelAxisX = item["Comune"].ToString(),
                    Color = serieCollezione[0].Color,
                    Value = Convert.ToDouble(item["ValoreStimatoProprieta"]),
                    ShowLabelAxisX = true,
                    ShowLabelAxisY = false
                   
                });

                serieCollezione[1].Points.Add(new Point
                {
                    LabelAxisY = Helper.FormatCurrency(item["ValoreStimatoTotale"].ToString()),
                    Color = serieCollezione[1].Color,
                    Value = Convert.ToDouble(item["ValoreStimatoAltri"]),
                    ShowLabelAxisY = true,
                    ShowLabelAxisX = false
                });
            }
            graficoBarre.SeriesCollection = serieCollezione;
            //if (datiGrafico.Rows.Count > 13)
            //    AddElement(new SpacePDF(10));
            //else if (datiGrafico.Rows.Count > 5)
            //    AddElement(new SpacePDF(30));
            //else
            //    AddElement(new SpacePDF(8));
            AddElement(new SpacePDF(spazioInizale));
            AddElement(graficoBarre);
        }

        /// <summary>
        /// Recupera i dati necessari alla Section restituendo un DataTable.
        /// </summary>
        /// <returns></returns>
        protected sealed override DataTable GetDataTable()
        {
            return null;
        }

        /// <summary>
        /// Recupera i dati necessari alla Section restituendo un DataSet.
        /// </summary>
        /// <returns></returns>
        protected override DataSet GetDataSet()
        {
            var ds = new DataSet();

            #region Definizione dei parametri

            var parametri = new List<Parametro>
            {
                new Parametro
                {
                    Direction = ParameterDirection.Input,
                    DbType = DbType.Int64,
                    ParameterName = "ChiaveClientePB",
                    Value = EnvironmentFacade.ReportEnvironment.Cliente.Chiave
                }
            };

            #endregion

            var dt = EnvironmentFacade.ReportEnvironment.Immobiliare.ImmobiliareCEUnica ? DataAccess.ExecuteDataTableStoredProcedure(DBProvider.SqlServerConsulenzaUnica, "REP_Immobiliare_S3_DistribuzioneGeograficaFabbricati", parametri)
                : DataAccess.ExecuteDataTableStoredProcedure(DBProvider.SqlServerConsulenzaEvoluta, "REP_Immobiliare_S3_DistribuzioneGeograficaFabbricati", parametri);

            #region Riaggregazioni

            var dt1 = new DataTable();
            dt1.Columns.Add("Comune_Tipologia", typeof(string));
            dt1.Columns.Add("NumeroImmobili", typeof(decimal));
            dt1.Columns.Add("ValoreStimatoProprieta", typeof(decimal));
            dt1.Columns.Add("ValoreStimatoTotale", typeof(decimal));
            dt1.Columns.Add("FontBold", typeof(bool));
            dt1.Columns.Add("ReplaceIfZero", typeof(string));
            dt1.Columns.Add("CanLastRow", typeof(bool));
            dt1.Columns.Add("Codice_Tipologia", typeof(string));

            var dt2 = new DataTable();
            dt2.Columns.Add("Comune", typeof(string));
            dt2.Columns.Add("ValoreStimatoProprieta", typeof(decimal));
            dt2.Columns.Add("ValoreStimatoAltri", typeof(decimal));
            dt2.Columns.Add("ValoreStimatoTotale", typeof(decimal));


            // Distinct sui comuni            
            var distinctComuni = new DataView(dt).ToTable(true, "Comune");

            foreach (DataRow comune in distinctComuni.Rows)
            {
                IEnumerable<DataRow> query = from tipologie in dt.AsEnumerable()
                                             where tipologie.Field<string>("Comune").Equals(comune["Comune"].ToString())
                                             select tipologie;

                var intestazione = true;
                foreach (var item in query)
                {
                    if (intestazione)
                    {
                        dt1.Rows.Add(string.Format("{0} ({1})", item["comune"], item["provincia"]), 0, 0, 0, true, " ", false, string.Empty); // Intestazione                    
                        dt2.Rows.Add(
                            string.Format("{0} ({1})",
                            item["comune"], item["provincia"]),
                            Convert.ToDecimal(query.Sum(o => o.Field<decimal>("valorestimatoproprieta"))),
                            //Convert.ToDecimal(query.Sum(o => o.Field<decimal>("valorestimatototale")) - query.Sum(o => o.Field<decimal>("valorestimatoproprieta"))),
                            Convert.ToDecimal(query.Sum(o => o.Field<decimal>("valorestimatototale")) - query.Sum(o => o.Field<decimal>("valorestimatoproprieta"))) < 0 ? 0 : Convert.ToDecimal(query.Sum(o => o.Field<decimal>("valorestimatototale")) - query.Sum(o => o.Field<decimal>("valorestimatoproprieta"))),
                            Convert.ToDecimal(query.Sum(o => o.Field<decimal>("valorestimatototale"))));
                        intestazione = false;
                    }

                    dt1.Rows.Add(item["tipologia"], Convert.ToDecimal(item["numeroimmobili"]), Convert.ToDecimal(item["valorestimatoproprieta"]), Convert.ToDecimal(item["valorestimatototale"]), false, "-", true, item["codicetipologia"]); // Dettaglio

                }
            }

            #endregion

            ds.Tables.Add(dt.Copy());
            ds.Tables.Add(dt1);
            ds.Tables.Add(dt2);

            return ds;
        }
    }
}
