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

namespace Consulenza.ReportWriter.Manager.Section.Immobiliare.Finalita
{
    /// <summary>   
    /// Patrimonio Immobiliare Stima delle imposte (id 147) Fabbricati
    /// </summary>
    public class S8 : Entity.Section
    {
        public S8(EnvironmentFacade environmentFacade, int idSection)
            : base(environmentFacade, idSection)
        {
            try
            {
                Draw();
            }
            catch (Exception ex)
            {
                SectionLogger.Write("S8", ex.Message, SectionLoggerMessageLevel.E, EnvironmentFacade.ReportEnvironment);
            }
        }

        /// <summary>
        /// Scheda8. Patrimonio immobiliare –Stima delle imposte dei Fabbricati
        /// </summary>
        protected override sealed void Draw()
        {
            var dati = GetDataSet();

            if (dati == null || dati.Tables["Dati"].Rows.Count == 0) return;

            var testi = GetText();

            // Abitazione principale       
            var abitazionePrincipale = dati.Tables["Dati"].AsEnumerable().Where(r => r.Field<bool>("Abitazioneprincipale"));

            var icona = new ImagePDF(EnvironmentFacade.RendererFacade.XLeftLimit, 0.20F, "StimaValore.png") { AutoIncrementYWritable = false };
            var titolo = new FormattedTextAreaPDF(testi.Rows[0]["testo1"].ToString(), 82, 600) { FontSize = 10, FontColor = ColorPDF.Immobiliare_Grigio_TestoStandard, DeltaY = 5 };

            #region Oggetti da ripetere al salto pagina della tabella

            var listaOggettiDaRipetere = new List<ObjectPDF> { new SpacePDF(40), icona, titolo, new SpacePDF(20) };
            AddElement(new RepeaterPDF(listaOggettiDaRipetere));

            #endregion

            #region Tabella

            var tabella = new TablePDF(EnvironmentFacade.RendererFacade.XLeftLimit, dati.Tables["Dati"])
            {
                Style = Style.Immobiliare,
                RowsPadding = 3,
                Footer = true,
                HeaderHeight = 130,
                MinimumRowHeight = 12,
                AdditionalSpaceBelow = 90 //Spazio aggiuntivo per le avvertenze
            };


            #region definizione larghezza colonne

            const int larghezzaTabella = 755; // massima larghezza tabella
            var larghezzaImmagine = abitazionePrincipale.Any() ? 17 : 0;
            const int larghezzaRenditaCatastale = 60;
            const int larghezzaImuTasiTari = 50;
            const int larghezzaCliente = 45;
            const int larghezzaTotaleImposte = 50;

            //La colonna descrizione è l'unica variabile.
            var larghezzaDescrizione = larghezzaTabella - larghezzaImmagine - larghezzaRenditaCatastale - (larghezzaImuTasiTari * 6) - (larghezzaCliente * 2) - (larghezzaTotaleImposte * 2);

            #endregion

            #region colonne
            // Colonna di tipo Immagine
            if (abitazionePrincipale.Any())
            {
                tabella.Columns.Add(new ColumnPDF("immagine0", larghezzaImmagine, HorizontalAlignmentType.Sinistra, false, false, 7, ColumnType.Immagine, string.Empty, string.Empty) { ScaleColumnTypeImage = 0.1F });
            }

            tabella.Columns.Add(new ColumnPDF("descrizione", larghezzaDescrizione, HorizontalAlignmentType.Sinistra, false, false, 7, ColumnType.Testo, "Descrizione", "Descrizione") { HeaderVerticalAlignment = VerticalAlignmentType.Basso, HeaderFontBold = true, PaddingLeft = abitazionePrincipale.Any() ? 5 : 0, PaddingRight = 3 });
            tabella.Columns.Add(new ColumnPDF("renditacatastale", larghezzaRenditaCatastale, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "RenditaCatastaleStringa", "Rendita catastale") { HeaderTextVerticalDirection = true });

            tabella.FooterColumns.Add(new ColumnPDF("descrizione", tabella.Columns.Sum(p => p.Width), HorizontalAlignmentType.Sinistra, false, true, 7, ColumnType.Testo));
            tabella.FooterCells[0, 0].Value = "Totale (€)";
            if(dati.Tables["Dati"].Columns.Contains("ImuValoreMinimoStringa"))
            {
                #region IMU
                tabella.Columns.Add(new ColumnPDF("ImuMin", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "ImuValoreMinimoStringa", "min")
                {
                    HeaderGroupText = new List<string> { "IMU" },
                    HeaderGroupBorderLine = false,
                    HeaderGroupWidth = larghezzaImuTasiTari * 2,
                    HeaderGroupTextDeltaX = -5,
                    HeaderGroupTextDeltaY = -15,
                    HeaderGroupTextVerticalDirection = true,
                    HeaderVerticalAlignment = VerticalAlignmentType.Basso
                });
                tabella.Columns.Add(new ColumnPDF("ImuMax", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "ImuValoreMassimoStringa", "max")
                {
                    HeaderVerticalAlignment = VerticalAlignmentType.Basso
                });

                tabella.FooterColumns.Add(new ColumnPDF("ImuMinTotale", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, true, 7, ColumnType.Testo));
                var totaleImuMin = Convert.ToDecimal(dati.Tables["Dati"].Compute("SUM(ImuValoreMinimo)", string.Empty));
                tabella.FooterCells[1, 0].Value = totaleImuMin.Equals(0) ? "-" : Helper.FormatCurrency(totaleImuMin.ToString());
            
                tabella.FooterColumns.Add(new ColumnPDF("ImuMaxTotale", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, true, 7, ColumnType.Testo));
                var totaleImuMax = Convert.ToDecimal(dati.Tables["Dati"].Compute("SUM(ImuValoreMassimo)", string.Empty));
                tabella.FooterCells[2, 0].Value = totaleImuMax.Equals(0) ? "-" : Helper.FormatCurrency(totaleImuMax.ToString());

                #endregion

                #region TASI
                /**************************** Disabilitato Colonne TASI 08/03/2021 - Pino ****************************************/
                //tabella.Columns.Add(new ColumnPDF("TasiMin", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "TasiValoreMinimoStringa", "min")
                //{
                //    HeaderGroupText = new List<string> { "TASI" },
                //    HeaderGroupBorderLine = false,
                //    HeaderGroupWidth = larghezzaImuTasiTari * 2,
                //    HeaderGroupTextDeltaX = -5,
                //    HeaderGroupTextDeltaY = -15,
                //    HeaderGroupTextVerticalDirection = true,
                //    HeaderVerticalAlignment = VerticalAlignmentType.Basso
                //});
                //tabella.Columns.Add(new ColumnPDF("TasiMax", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "TasiValoreMassimoStringa", "max")
                //{
                //    HeaderVerticalAlignment = VerticalAlignmentType.Basso,
                //    PaddingRight = 3,
                //    HeaderPaddingRight = 3
                //});

                //tabella.FooterColumns.Add(new ColumnPDF("TasiMinTotale", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, true, 7, ColumnType.Testo));
                //var totaleTasiMin = Convert.ToDecimal(dati.Tables["Dati"].Compute("SUM(TasiValoreMinimo)", string.Empty));
                //tabella.FooterCells[3, 0].Value = totaleTasiMin.Equals(0) ? "-" : Helper.FormatCurrency(totaleTasiMin.ToString());

                //tabella.FooterColumns.Add(new ColumnPDF("TasiMaxTotale", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, true, 7, ColumnType.Testo) { PaddingRight = 3 });
                //var totaleTasiMax = Convert.ToDecimal(dati.Tables["Dati"].Compute("SUM(TasiValoreMassimo)", string.Empty));
                //tabella.FooterCells[4, 0].Value = totaleTasiMax.Equals(0) ? "-" : Helper.FormatCurrency(totaleTasiMax.ToString());
                /******************************************************************************************************************************/
                #endregion

                //MODIFICA_TARI 
                #region TARI
                tabella.Columns.Add(new ColumnPDF("TariMin", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "TariValoreMinimoStringa", "min")
                {
                    HeaderGroupText = new List<string> { "TARI" },
                    HeaderGroupBorderLine = false,
                    HeaderGroupWidth = larghezzaImuTasiTari * 2,
                    HeaderGroupTextDeltaX = -5,
                    HeaderGroupTextDeltaY = -15,
                    HeaderGroupTextVerticalDirection = true,
                    HeaderVerticalAlignment = VerticalAlignmentType.Basso
                });
                tabella.Columns.Add(new ColumnPDF("TariMax", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "TariValoreMassimoStringa", "max")
                {
                    HeaderVerticalAlignment = VerticalAlignmentType.Basso,
                    PaddingRight = 3,
                    HeaderPaddingRight = 3
                });
                tabella.FooterColumns.Add(new ColumnPDF("TariMinTotale", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, true, 7, ColumnType.Testo));
                var totaleTariMin = Convert.ToDecimal(dati.Tables["Dati"].Compute("SUM(TariValoreMinimo)", string.Empty));
                /**************************** Disabilitato Colonne TASI 08/03/2021 - Pino ****************************************/
                //tabella.FooterCells[5, 0].Value = totaleTariMin.Equals(0) ? "-" : Helper.FormatCurrency(totaleTariMin.ToString());
                tabella.FooterCells[3, 0].Value = totaleTariMin.Equals(0) ? "-" : Helper.FormatCurrency(totaleTariMin.ToString());
                /******************************************************************************************************************************/

                tabella.FooterColumns.Add(new ColumnPDF("TariMaxTotale", larghezzaImuTasiTari, HorizontalAlignmentType.Destra, false, true, 7, ColumnType.Testo) { PaddingRight = 3 });
                var totaleTariMax = Convert.ToDecimal(dati.Tables["Dati"].Compute("SUM(TariValoreMassimo)", string.Empty));
                /**************************** Disabilitato Colonne TASI 08/03/2021 - Pino ****************************************/
                //tabella.FooterCells[6, 0].Value = totaleTariMax.Equals(0) ? "-" : Helper.FormatCurrency(totaleTariMax.ToString());
                tabella.FooterCells[4, 0].Value = totaleTariMax.Equals(0) ? "-" : Helper.FormatCurrency(totaleTariMax.ToString());
                /******************************************************************************************************************************/

                #endregion

                #region ProQuota
                tabella.Columns.Add(new ColumnPDF("proquotaMin", larghezzaCliente, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "ImposteProQuotaMinStringa", "min")
                {
                    HeaderGroupText = new List<string> { dati.Tables["Dati"].Rows[0]["nominativo"].ToString(), "Imposte pro quota (€)" },
                    HeaderGroupBorderLine = false,
                    HeaderGroupWidth = larghezzaCliente * 2,
                    HeaderGroupTextDeltaX = -15,
                    HeaderGroupTextDeltaY = -15,
                    HeaderGroupTextVerticalDirection = true,
                    HeaderVerticalAlignment = VerticalAlignmentType.Basso,

                    HeaderBackgroundColor = ColorPDF.Immobiliare_Marrone,
                    HeaderFontColor = ColorPDF.Bianco,
                    HeaderFontBold = true,
                    BackgroundColor = ColorPDF.Immobiliare_Marrone,
                    FontColor = ColorPDF.Bianco,
                    FontBold = true
                });

                tabella.FooterColumns.Add(new ColumnPDF("proquotaMinTotale", larghezzaCliente, HorizontalAlignmentType.Destra, false, true, 7, ColumnType.Testo)
                {
                    BackgroundColor = ColorPDF.Immobiliare_Marrone,
                    FontColor = ColorPDF.Bianco,
                    FontBold = true
                });

                var totaleProQuotaMin = Convert.ToDecimal(dati.Tables["Dati"].Compute("Sum(ImposteProQuotaMin)", string.Empty)); ;
                /**************************** Disabilitato Colonne TASI 08/03/2021 - Pino ****************************************/
                //tabella.FooterCells[7, 0].Value = totaleProQuotaMin.Equals(0) ? "-" : Helper.FormatCurrency(totaleProQuotaMin.ToString());
                tabella.FooterCells[5, 0].Value = totaleProQuotaMin.Equals(0) ? "-" : Helper.FormatCurrency(totaleProQuotaMin.ToString());
                /******************************************************************************************************************************/

                tabella.Columns.Add(new ColumnPDF("proquotaMax", larghezzaCliente, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "ImposteProQuotaMaxStringa", "max")
                {
                    HeaderVerticalAlignment = VerticalAlignmentType.Basso,
                    HeaderBackgroundColor = ColorPDF.Immobiliare_Marrone,
                    HeaderFontColor = ColorPDF.Bianco,
                    HeaderFontBold = true,
                    BackgroundColor = ColorPDF.Immobiliare_Marrone,
                    FontColor = ColorPDF.Bianco,
                    FontBold = true
                });
                tabella.FooterColumns.Add(new ColumnPDF("proquotaMaxTotale", larghezzaCliente, HorizontalAlignmentType.Destra, false, true, 7, ColumnType.Testo)
                {
                    BackgroundColor = ColorPDF.Immobiliare_Marrone,
                    FontColor = ColorPDF.Bianco,
                    FontBold = true
                });
                var totaleProQuotaMax = Convert.ToDecimal(dati.Tables["Dati"].Compute("Sum(ImposteProQuotaMax)", string.Empty)); ;
                /**************************** Disabilitato Colonne TASI 08/03/2021 - Pino ****************************************/
                //tabella.FooterCells[8, 0].Value = totaleProQuotaMax.Equals(0) ? "-" : Helper.FormatCurrency(totaleProQuotaMax.ToString());
                tabella.FooterCells[6, 0].Value = totaleProQuotaMax.Equals(0) ? "-" : Helper.FormatCurrency(totaleProQuotaMax.ToString());
                /******************************************************************************************************************************/

                #endregion

                #region Totale imposte
                tabella.Columns.Add(new ColumnPDF("ImposteMin", larghezzaTotaleImposte, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "TotaleImposteMinStringa", "min")
                {
                    HeaderGroupText = new List<string> { "Totale imposte (€)" },
                    HeaderGroupBorderLine = false,
                    HeaderGroupWidth = larghezzaTotaleImposte * 2,
                    HeaderGroupTextDeltaX = 0,
                    HeaderGroupTextDeltaY = -15,
                    HeaderGroupTextVerticalDirection = true,
                    HeaderVerticalAlignment = VerticalAlignmentType.Basso
                });
                tabella.Columns.Add(new ColumnPDF("ImposteMax", larghezzaTotaleImposte, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Testo, "TotaleImposteMaxStringa", "max")
                {
                    HeaderVerticalAlignment = VerticalAlignmentType.Basso
                });

                tabella.FooterColumns.Add(new ColumnPDF("ImposteMinTotale", larghezzaTotaleImposte, HorizontalAlignmentType.Destra, false, true, 7, ColumnType.Testo));
                var totaleImposteMin = Convert.ToDecimal(dati.Tables["Dati"].Compute("SUM(TotaleImposteMin)", string.Empty));
                /**************************** Disabilitato Colonne TASI 08/03/2021 - Pino ****************************************/
                //tabella.FooterCells[9, 0].Value = totaleImposteMin.Equals(0) ? "-" : Helper.FormatCurrency(totaleImposteMin.ToString());
                tabella.FooterCells[7, 0].Value = totaleImposteMin.Equals(0) ? "-" : Helper.FormatCurrency(totaleImposteMin.ToString());
                /******************************************************************************************************************************/

                tabella.FooterColumns.Add(new ColumnPDF("ImposteMaxTotale", larghezzaTotaleImposte, HorizontalAlignmentType.Destra, false, true, 7, ColumnType.Testo));
                var totaleImposteMax = Convert.ToDecimal(dati.Tables["Dati"].Compute("SUM(TotaleImposteMax)", string.Empty));
                /**************************** Disabilitato Colonne TASI 08/03/2021 - Pino ****************************************/
                //tabella.FooterCells[10, 0].Value = totaleImposteMax.Equals(0) ? "-" : Helper.FormatCurrency(totaleImposteMax.ToString());
                tabella.FooterCells[8, 0].Value = totaleImposteMax.Equals(0) ? "-" : Helper.FormatCurrency(totaleImposteMax.ToString());
                /******************************************************************************************************************************/
                #endregion
            }
            #endregion

            #region immagini e border nelle colonne di tipo immagine

            #region Abitazione principale

            foreach (var item in abitazionePrincipale)
            {
                int indiceRiga = Convert.ToInt32(item["indice"]) - 1;

                tabella.Cells[0, indiceRiga].Value = "abitazprincipale.png";
            }
            #endregion

            #endregion

            #region note della tabella

            // Nota immagine (Abitazione principale)
            if (abitazionePrincipale.Any())
                tabella.Notes.Add(new TableNotePDF(TableNotePDF.TableNotePositionType.PièDiTabella, Helper.ReplaceVariables(testi.Rows[0]["testo2"].ToString(), base.EnvironmentFacade.ReportEnvironment)) { FontBold = true, FontSize = 7, DeltaY = 3, Image = new ImagePDF(EnvironmentFacade.RendererFacade.XLeftLimit, 0.1F, "abitazprincipale.png") });

            // Nota immagine (Avvertenze)
            tabella.Notes.Add(new TableNotePDF(TableNotePDF.TableNotePositionType.PièDiTabella, Helper.ReplaceVariables(testi.Rows[0]["testo3"].ToString(), base.EnvironmentFacade.ReportEnvironment)) { FontBold = true, FontSize = 7, DeltaY = 3, Image = new ImagePDF(EnvironmentFacade.RendererFacade.XLeftLimit, 0.1F, "warning.png") });


            #endregion

            #region avvertenze

            var testoInizialeAvvertenze = new FormattedTextAreaPDF(Helper.ReplaceVariables(testi.Rows[0]["testo4"].ToString(), base.EnvironmentFacade.ReportEnvironment), EnvironmentFacade.RendererFacade.XLeftLimit + 20, 800) { FontSize = 7 };

            var elencoAvvertenze = new List<string> { 
                Helper.ReplaceVariables(testi.Rows[0]["testo5"].ToString() , base.EnvironmentFacade.ReportEnvironment) , 
                Helper.ReplaceVariables(testi.Rows[0]["testo6"].ToString() , base.EnvironmentFacade.ReportEnvironment) ,
                Helper.ReplaceVariables(testi.Rows[0]["testo7"].ToString() , base.EnvironmentFacade.ReportEnvironment) ,
                Helper.ReplaceVariables(testi.Rows[0]["testo8"].ToString() , base.EnvironmentFacade.ReportEnvironment) ,
                Helper.ReplaceVariables(testi.Rows[0]["testo9"].ToString() , base.EnvironmentFacade.ReportEnvironment) ,
                Helper.ReplaceVariables(testi.Rows[0]["testo10"].ToString(), base.EnvironmentFacade.ReportEnvironment) ,
                Helper.ReplaceVariables(testi.Rows[0]["testo11"].ToString(), base.EnvironmentFacade.ReportEnvironment)
            };

            var elenco = new UnorderedListPDF(EnvironmentFacade.RendererFacade.XLeftLimit + 10, elencoAvvertenze, BulletType.Trattino)
            {
                Width = 800,
                Margin = 2,
                FontSize = 7
            };

            var testoFinaleAvvertenze = new FormattedTextAreaPDF(Helper.ReplaceVariables(Helper.ReplaceVariables(testi.Rows[0]["testo12"].ToString(), base.EnvironmentFacade.ReportEnvironment), base.EnvironmentFacade.ReportEnvironment), EnvironmentFacade.RendererFacade.XLeftLimit + 20, 800) { FontSize = 7 };

            #endregion

            #endregion
            AddElement(new SpacePDF(40));
            AddElement(icona);
            
            AddElement(titolo);
            AddElement(new SpacePDF(20));
            AddElement(tabella);

            // Avvertenze
            AddElement(new SpacePDF(5));
            AddElement(testoInizialeAvvertenze);
            AddElement(elenco);
            AddElement(testoFinaleAvvertenze);
        }

        /// <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 sealed override DataSet GetDataSet()
        {
            #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 dsOriginal = EnvironmentFacade.ReportEnvironment.FinalitaImmobiliare.ImmobiliareCEUnica ? DataAccess.ExecuteDataSetStoredProcedure(DBProvider.SqlServerConsulenzaUnica, "REP_FinalitaImmobiliare_S8_StimaImposte", parametri)
                : DataAccess.ExecuteDataSetStoredProcedure(DBProvider.SqlServerConsulenzaEvoluta, "REP_FinalitaImmobiliare_S8_StimaImposte", parametri);
            if (dsOriginal.Tables[1].Rows.Count == 0)
                return null;

            var dt1 = dsOriginal.Tables[1].Copy();
            dt1.TableName = "Dati";

            #region Chiamata Prometeia (FiscalitaImmobili)
            //inizializzo gli oggetti che andranno valorizzati nel try da prometeia..
            var dtInput = dsOriginal.Tables[0].AsEnumerable().Where(o => o.Field<string>("tipoCatasto").ToString().Equals("F")).ToArray();
            #region dichiarazioni
            List<ExternalServices.Structure.FiscalitaImmobile> listaFiscalitaImmobili = new List<ExternalServices.Structure.FiscalitaImmobile>();
            List<ExternalServices.Structure.FiscalitaImmobile> listaTari = new List<ExternalServices.Structure.FiscalitaImmobile>();
            
            var dtInput2 = new DataTable("dtInput2");
            dtInput2.Columns.Add(new DataColumn("chiaveImmobile", typeof(string)));
            dtInput2.Columns.Add(new DataColumn("codComune", typeof(string)));
            dtInput2.Columns.Add(new DataColumn("categoriaCatastale", typeof(string)));
            dtInput2.Columns.Add(new DataColumn("tipoCatasto", typeof(string)));
            dtInput2.Columns.Add(new DataColumn("superficieTARI", typeof(string)));
            dtInput2.Columns.Add(new DataColumn("pertinenzaUtDomestica", typeof(bool)));
            dtInput2.Columns.Add(new DataColumn("destinazioneUso", typeof(string)));
            // Colonne aggiuntive per formattazione in stringa
            dt1.Columns.Add("Indice", typeof(int));
            dt1.Columns.Add("RenditaCatastaleStringa", typeof(string));

            //IMU
            dt1.Columns.Add("ImuValoreMinimo", typeof(decimal));
            dt1.Columns.Add("ImuValoreMinimoStringa", typeof(string));
            dt1.Columns.Add("ImuValoreMassimo", typeof(decimal));
            dt1.Columns.Add("ImuValoreMassimoStringa", typeof(string));

            //TASI
            dt1.Columns.Add("TasiValoreMinimo", typeof(decimal));
            dt1.Columns.Add("TasiValoreMinimoStringa", typeof(string));
            dt1.Columns.Add("TasiValoreMassimo", typeof(decimal));
            dt1.Columns.Add("TasiValoreMassimoStringa", typeof(string));

            //TARI
            dt1.Columns.Add("TariValoreMinimo", typeof(decimal));
            dt1.Columns.Add("TariValoreMinimoStringa", typeof(string));
            dt1.Columns.Add("TariValoreMassimo", typeof(decimal));
            dt1.Columns.Add("TariValoreMassimoStringa", typeof(string));

            //ProQuota Cliente
            dt1.Columns.Add("ImposteProQuotaMin", typeof(decimal));
            dt1.Columns.Add("ImposteProQuotaMax", typeof(decimal));
            dt1.Columns.Add("ImposteProQuotaMinStringa", typeof(string));
            dt1.Columns.Add("ImposteProQuotaMaxStringa", typeof(string));

            //Totale imposte
            dt1.Columns.Add("TotaleImposteMin", typeof(decimal));
            dt1.Columns.Add("TotaleImposteMax", typeof(decimal));
            dt1.Columns.Add("TotaleImposteMinStringa", typeof(string));
            dt1.Columns.Add("TotaleImposteMaxStringa", typeof(string));

            //Colonna di formattazione
            dt1.Columns.Add("ReplaceIfZero", typeof(string));
            #endregion
            try
            {
                listaFiscalitaImmobili = new Prometeia().GetFiscalitaImmobili(dtInput).ToList();
                #region Join + Chiamata Prometeia (Estrazione TARI)

                foreach (var item in from c in dsOriginal.Tables[0].AsEnumerable()
                                     join l in dsOriginal.Tables[1].AsEnumerable()
                                     on c.Field<string>("chiaveImmobile") equals l.Field<string>("idimmobilecatasto")
                                     select new
                                     {
                                         chiaveImmobile = c.Field<string>("chiaveImmobile"),
                                         codComune = c.Field<string>("comune"),
                                         categoriaCatastale = c.Field<string>("categoria"),
                                         tipoCatasto = c.Field<string>("tipoCatasto"),
                                         superficieTARI = l.Field<decimal>("superficiestimata"),
                                         pertinenzaUtDomestica = true,
                                         destinazioneUso = c.Field<string>("destinazioneUso").Equals("S") ? "NS" : c.Field<string>("destinazioneUso")
                                     }
                         )
                {
                    dtInput2.Rows.Add(
                        item.chiaveImmobile,
                        item.codComune,
                        item.categoriaCatastale,
                        item.tipoCatasto,
                        item.superficieTARI,
                        item.pertinenzaUtDomestica,
                        item.destinazioneUso
                    );

                }

                listaTari = new Prometeia().GetFiscalitaTari(dtInput2.AsEnumerable().ToArray());
                var indice = 0;
                foreach (DataRow item in dt1.Rows)
                {
                    var riferimentoImmobileFiscalita =
                        listaFiscalitaImmobili.FirstOrDefault(
                            o => o.ChiaveImmobile.Equals(item["IdImmobileCatasto"].ToString()));

                    var riferimentoTariFiscalita =
                        listaTari.FirstOrDefault(
                            o => o.ChiaveImmobile.Equals(item["IdImmobileCatasto"].ToString()));

                    item["Indice"] = indice;
                    item["RenditaCatastaleStringa"] = item["RenditaCatastale"] == DBNull.Value ? "-" : Helper.FormatCurrency(item["RenditaCatastale"].ToString());

                    //IMU
                    item["ImuValoreMinimo"] = riferimentoImmobileFiscalita.ImuValoreMinimo.HasValue ? riferimentoImmobileFiscalita.ImuValoreMinimo.Value : 0;
                    item["ImuValoreMinimoStringa"] = Helper.FormatCurrency((Convert.ToDecimal(item["ImuValoreMinimo"]).ToString()));

                    item["ImuValoreMassimo"] = riferimentoImmobileFiscalita.ImuValoreMassimo.HasValue ? riferimentoImmobileFiscalita.ImuValoreMassimo.Value : 0;
                    item["ImuValoreMassimoStringa"] = Helper.FormatCurrency((Convert.ToDecimal(item["ImuValoreMassimo"]).ToString()));

                    //TASI
                    item["TasiValoreMinimo"] = riferimentoImmobileFiscalita.TasiValoreMinimo.HasValue ? riferimentoImmobileFiscalita.TasiValoreMinimo.Value : 0;
                    item["TasiValoreMinimoStringa"] = Helper.FormatCurrency((Convert.ToDecimal(item["TasiValoreMinimo"]).ToString()));

                    item["TasiValoreMassimo"] = riferimentoImmobileFiscalita.TasiValoreMassimo.HasValue ? riferimentoImmobileFiscalita.TasiValoreMassimo.Value : 0;
                    item["TasiValoreMassimoStringa"] = Helper.FormatCurrency((Convert.ToDecimal(item["TasiValoreMassimo"]).ToString()));

                    //TARI
                    item["TariValoreMinimo"] = riferimentoTariFiscalita.TariValoreMinimo.HasValue ? riferimentoTariFiscalita.TariValoreMinimo.Value : 0;
                    item["TariValoreMinimoStringa"] = Helper.FormatCurrency((Convert.ToDecimal(item["TariValoreMinimo"]).ToString()));

                    item["TariValoreMassimo"] = riferimentoTariFiscalita.TariValoreMassimo.HasValue ? riferimentoTariFiscalita.TariValoreMassimo.Value : 0;
                    item["TariValoreMassimoStringa"] = Helper.FormatCurrency((Convert.ToDecimal(item["TariValoreMassimo"]).ToString()));

                    //ProQuota Cliente
                    var percentualeAliquotaImu = Convert.ToDecimal(item["PercAliquotaImu"]);
                    var percentualeAliquotaTasi = Convert.ToDecimal(item["PercAliquotaTasi"]);

                    var proquotaMin = (percentualeAliquotaImu * Convert.ToDecimal(item["ImuValoreMinimo"])) +
                                      (percentualeAliquotaTasi * Convert.ToDecimal(item["TasiValoreMinimo"])) +
                                      (percentualeAliquotaImu * Convert.ToDecimal(item["TariValoreMinimo"]));

                    var proquotaMax = (percentualeAliquotaImu * Convert.ToDecimal(item["ImuValoreMassimo"])) +
                                      (percentualeAliquotaTasi * Convert.ToDecimal(item["TasiValoreMassimo"])) +
                                      (percentualeAliquotaImu * Convert.ToDecimal(item["TariValoreMassimo"]));

                    item["ImposteProQuotaMin"] = proquotaMin;
                    item["ImposteProQuotaMax"] = proquotaMax;
                    item["ImposteProQuotaMinStringa"] = Helper.FormatCurrency(proquotaMin.ToString());
                    item["ImposteProQuotaMaxStringa"] = Helper.FormatCurrency(proquotaMax.ToString());

                    //Totale imposte
                    item["TotaleImposteMin"] = Convert.ToDecimal(item["ImuValoreMinimo"]) + Convert.ToDecimal(item["TasiValoreMinimo"]) + Convert.ToDecimal(item["TariValoreMinimo"]);
                    item["TotaleImposteMinStringa"] = Helper.FormatCurrency(item["TotaleImposteMin"].ToString());
                    item["TotaleImposteMax"] = Convert.ToDecimal(item["ImuValoreMassimo"]) + Convert.ToDecimal(item["TasiValoreMassimo"]) + Convert.ToDecimal(item["TariValoreMassimo"]);
                    item["TotaleImposteMaxStringa"] = Helper.FormatCurrency(item["TotaleImposteMax"].ToString());

                    item["ReplaceIfZero"] = "-";
                    indice++;
                }

                #endregion
            }
            catch (Exception et)
            { }
            //finally
            //{
            //    foreach (DataRow row in dtInput.ToList())
            //    {
            //        dtInput2.Rows.Add(
            //                row["chiaveImmobile"],
            //                row["comune"],
            //                row["categoria"],
            //                row["tipoCatasto"],
            //                "-",
            //                true,
            //                row["tipoCatasto"].ToString().Equals("S") ? "NS" : row["tipoCatasto"].ToString()
            //            );
            //    }
            //    var indice = 0;
            //    foreach (DataRow item in dt1.Rows)
            //    {
            //        item["Indice"] = indice;
            //        item["RenditaCatastaleStringa"] = item["RenditaCatastale"] == DBNull.Value ? "-" : Helper.FormatCurrency(item["RenditaCatastale"].ToString());

            //        //IMU
            //        item["ImuValoreMinimo"] = 0;
            //        item["ImuValoreMinimoStringa"] = "-";

            //        item["ImuValoreMassimo"] = 0;
            //        item["ImuValoreMassimoStringa"] = "-";

            //        //TASI
            //        item["TasiValoreMinimo"] = 0;
            //        item["TasiValoreMinimoStringa"] = "-";

            //        item["TasiValoreMassimo"] = 0;
            //        item["TasiValoreMassimoStringa"] = "-";

            //        //TARI
            //        item["TariValoreMinimo"] = 0;
            //        item["TariValoreMinimoStringa"] = "-";

            //        item["TariValoreMassimo"] = 0;
            //        item["TariValoreMassimoStringa"] = "-";
            //        item["ImposteProQuotaMin"] = 0;
            //        item["ImposteProQuotaMax"] = 0;
            //        item["ImposteProQuotaMinStringa"] = "-";
            //        item["ImposteProQuotaMaxStringa"] = "-";

            //        //Totale imposte
            //        item["TotaleImposteMin"] = 0;
            //        item["TotaleImposteMinStringa"] = "-";
            //        item["TotaleImposteMax"] = 0;
            //        item["TotaleImposteMaxStringa"] = "-";

            //        item["ReplaceIfZero"] = "-";
            //        indice++;
            //    }
            //}
            #endregion

            #region Join + Chiamata Prometeia (Estrazione TARI)
            /*
            var dtInput2 = new DataTable("dtInput2");
            dtInput2.Columns.Add(new DataColumn("chiaveImmobile", typeof(string)));
            dtInput2.Columns.Add(new DataColumn("codComune", typeof(string)));
            dtInput2.Columns.Add(new DataColumn("categoriaCatastale", typeof(string)));
            dtInput2.Columns.Add(new DataColumn("tipoCatasto", typeof(string)));
            dtInput2.Columns.Add(new DataColumn("superficieTARI", typeof(decimal)));
            dtInput2.Columns.Add(new DataColumn("pertinenzaUtDomestica", typeof(bool)));
            dtInput2.Columns.Add(new DataColumn("destinazioneUso", typeof(string)));

            foreach (var item in from c in dsOriginal.Tables[0].AsEnumerable()
                                 join l in dsOriginal.Tables[1].AsEnumerable()
                                 on c.Field<string>("chiaveImmobile") equals l.Field<string>("idimmobilecatasto")
                                 select new 
                                 {
                                         chiaveImmobile = c.Field<string>("chiaveImmobile"),
                                         codComune = c.Field<string>("comune"),
                                         categoriaCatastale = c.Field<string>("categoria"),
                                         tipoCatasto = c.Field<string>("tipoCatasto"),
                                         superficieTARI = l.Field<decimal>("superficiestimata"),
                                         pertinenzaUtDomestica = true,
                                         destinazioneUso = c.Field<string>("destinazioneUso").Equals("S") ? "NS" : c.Field<string>("destinazioneUso")
                                     }
                     )
            {
                dtInput2.Rows.Add(
                    item.chiaveImmobile,
                    item.codComune,
                    item.categoriaCatastale,
                    item.tipoCatasto,
                    item.superficieTARI,
                    item.pertinenzaUtDomestica,
                    item.destinazioneUso
                );

            }
            
            var listaTari = new Prometeia().GetFiscalitaTari(dtInput2.AsEnumerable().ToArray());
            */
            #endregion

           

            
            #region Ordinamento

            //L’odinamento dei fabbricati elencati nella tabella è costruito con le seguenti regole:
            // 1.	Immobile di residenza (se indicato)
            // 2.	Pertinenza dell’immobile di residenza (se indicata)
            // 3.	Fabbricati del comune di residenza:
            //      	Abitazioni (per valore decrescente);
            //      	Box/posti auto (per valore decrescente);
            //      	Altre categorie fabbricati (per valore decrescente).
            // 4.	Fabbricati di altri comuni (per valore aggregato complessivo decrescente):
            //      	Abitazioni (per valore decrescente);
            //      	Box/posti auto (per valore decrescente);
            //      	Altre categorie fabbricati (per valore decrescente).

            var codiceComuneResidenza = dt1.Rows[0]["codComuneResidenza"] != DBNull.Value ? dt1.Rows[0]["codComuneResidenza"].ToString() : string.Empty;
            DataTable dtOrdinamentoStep1;
            DataTable dtOrdinamentoStep2;

            if (string.IsNullOrEmpty(codiceComuneResidenza))
            {
                dtOrdinamentoStep1 = dt1.AsEnumerable()
                 .OrderByDescending(o => o.Field<int>("ordResidenza"))
                .ThenByDescending(o => o.Field<int>("ordPertinenza"))
                .ThenByDescending(o => o.Field<int>("ordindirizzo"))
                .ThenByDescending(o => o.Field<decimal>("controvaloreComune"))
                .ThenBy(o => o.Field<string>("indirizzo"))
                .ThenByDescending(o => o.Field<int>("ordFabbricati"))
                .ThenByDescending(o => o.Field<decimal>("ValoreStimaTotale"))
                .CopyToDataTable();

                dtOrdinamentoStep2 = dtOrdinamentoStep1;
            }
            else
            {
                dtOrdinamentoStep1 = dt1.AsEnumerable().CopyToDataTable();

                // prima recupero i CodComune = codiceComuneResidenza
                // - verifico che siano presenti prima di ordinare
                if (dtOrdinamentoStep1.AsEnumerable().Any(o => o.Field<string>("CodComune").Equals(codiceComuneResidenza)))
                {
                    dtOrdinamentoStep2 = dtOrdinamentoStep1.AsEnumerable().Where(o => o.Field<string>("CodComune").Equals(codiceComuneResidenza))
                        .OrderByDescending(o => o.Field<int>("ordResidenza"))
                        .ThenByDescending(o => o.Field<int>("ordPertinenza"))
                        .ThenByDescending(o => o.Field<int>("ordindirizzo"))
                        .ThenByDescending(o => o.Field<decimal>("controvaloreComune"))
                         .ThenBy(o => o.Field<string>("indirizzo"))
                        .ThenByDescending(o => o.Field<int>("ordFabbricati"))
                        .ThenByDescending(o => o.Field<decimal>("ValoreStimaTotale"))
                        .CopyToDataTable();
                }
                else
                    dtOrdinamentoStep2 = dtOrdinamentoStep1;

                // poi recupero tutti gli altri
                // - verifico che siano presenti prima di ordinare
                if (dtOrdinamentoStep1.AsEnumerable().Any(o => o.Field<string>("CodComune") != codiceComuneResidenza))
                {
                    dtOrdinamentoStep2.Merge(dtOrdinamentoStep1.AsEnumerable().Where(o => o.Field<string>("CodComune") != codiceComuneResidenza)
                        // .OrderByDescending(o => o.Field<decimal>("controvaloreComune"))
                         .OrderBy(o => o.Field<string>("indirizzo"))
                         .ThenByDescending(o => o.Field<int>("ordFabbricati"))
                         .ThenByDescending(o => o.Field<decimal>("ValoreStimaTotale"))
                         .CopyToDataTable());
                }
            }

            // Riordino l'indice
            int indiceRiga = 1;
            foreach (DataRow item in dtOrdinamentoStep2.Rows)
            {
                item["Indice"] = indiceRiga;
                indiceRiga++;
            }

            //Rinomino dt di output
            dtOrdinamentoStep2.TableName = "Dati";

            #endregion


            // Dataset di ritorno
            var dsResult = new DataSet();
            dsResult.Tables.Add(dtOrdinamentoStep2.Copy());

            return dsResult;
        }
    }
}
