using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing.Imaging;
using System.Linq;
using System.Net;
using System.Configuration;
using System.IO;
using Consulenza.ExternalServices.PrometeiaCatasto;
using Consulenza.ExternalServices.Structure;
using Consulenza.ReportCommon;

namespace Consulenza.ExternalServices
{
    public class Prometeia
    {
        private readonly WebProxy _proxy;
        private readonly string _userNamePrometeiaCatasto = ConfigurationManager.AppSettings["UserNamePrometeiaCatasto"];
        private readonly string _passwordPrometaiaCatasto = ConfigurationManager.AppSettings["PasswordPrometeiaCatasto"];

        /// <summary>
        /// Modalità di visualizzazione delle Immagini recuperate dal servizio validatore
        /// </summary>
        public enum ViewModeImage
        {
            RoadMap,
            Satellite,
            StreetView
        }

        /// <summary>
        /// Costruttore
        /// </summary>
        public Prometeia()
        {
            var proxy = ConfigurationManager.AppSettings["ProxyUrl"];

            if (!string.IsNullOrEmpty(proxy))
            {
                _proxy = new WebProxy(proxy, true)
                    {
                        Credentials = new NetworkCredential(
                            ConfigurationManager.AppSettings["ProxyUserName"],
                            ConfigurationManager.AppSettings["ProxyPassword"])
                    };
            }
        }

        public Stream GetImageMonitoraggioFromValidator(string codFis)
        {
            try
            {
                var url = string.Empty;
                url = string.Format("{0}/{1}", ConfigurationManager.AppSettings["UrlImageMonitoraggioValidator"], "Italia_" + codFis + "_" + DateTime.Now.ToString("dd-MM-yyyy") + ".png");

                return Helper.GetImage(url).ToStream(ImageFormat.Png);
            }
            catch (System.Exception ex)
            {
                throw new System.Exception(string.Format("Prometeia.GetImageFromValidator: {0}", ex.Message));
            }
        }

        /// <summary>
        /// Recupera l'immagine dal servizio validator
        /// </summary>
        /// <param name="idImmobileCatasto">IdImmobileCatasto</param>
        /// <param name="mode">Modalità di visualizzazione</param>
        /// <returns></returns>
        public Stream GetImageFromValidator(string idImmobileCatasto, ViewModeImage mode)
        {
            idImmobileCatasto = Uri.EscapeDataString(idImmobileCatasto);
            try
            {
                var url = string.Empty;
                switch (mode)
                {
                    case ViewModeImage.RoadMap:
                        url = string.Format("{0}/{1}/{2}", ConfigurationManager.AppSettings["UrlImageValidator"], "roadMap", idImmobileCatasto);
                        break;
                    case ViewModeImage.Satellite:
                        url = string.Format("{0}/{1}/{2}", ConfigurationManager.AppSettings["UrlImageValidator"], "satellite", idImmobileCatasto);
                        break;
                    case ViewModeImage.StreetView:
                        url = string.Format("{0}/{1}/{2}", ConfigurationManager.AppSettings["UrlImageValidator"], "streetView", idImmobileCatasto);
                        break;
                }

                return Helper.GetImage(url).ToStream(ImageFormat.Png);
            }
            catch (System.Exception ex)
            {
                throw new System.Exception(string.Format("Prometeia.GetImageFromValidator: {0}", ex.Message));
            }
        }

        /// <summary>
        /// Recupera l'immagine dal servizio validator
        /// </summary>
        /// <param name="idImmobileCatasto">IdImmobileCatasto</param>
        /// <param name="codicefiscale">cf del cliente o partitaiva nel caso di cliente giuridico.</param>
        /// <param name="agente">codice del private banker</param>
        /// <param name="numeroimmagine">numero dell'immagine da visualizzare</param>
        /// <returns></returns>
        public Stream GetImageFromValidator(string idImmobileCatasto, string codicefiscale, string agente, int numeroimmagine)
        {
            idImmobileCatasto = Uri.EscapeDataString(idImmobileCatasto);

            try
            {
                var url = string.Format("{0}/{1}/{2}/{3}/{4}/{5}/{6}", ConfigurationManager.AppSettings["UrlImageValidator"], "estate", agente, codicefiscale, numeroimmagine,"cadastral-id",idImmobileCatasto);

                return Helper.GetImage(url).ToStream(ImageFormat.Png);
            }
            catch (System.Exception ex)
            {
                throw new System.Exception(string.Format("Prometeia.GetImageFromValidator: {0}", ex.Message));
            }
        }

        public Stream GetImageMonitoraggioFromValidator(string idImmobileCatasto, string codicefiscale, string agente, int numeroimmagine)
        {
            idImmobileCatasto = Uri.EscapeDataString(idImmobileCatasto);

            try
            {
                var url = string.Format("{0}/{1}/{2}/{3}/{4}/{5}/{6}", ConfigurationManager.AppSettings["UrlImageValidator"], "estate", agente, codicefiscale, numeroimmagine, "cadastral-id", idImmobileCatasto);

                return Helper.GetImage(url).ToStream(ImageFormat.Png);
            }
            catch (System.Exception ex)
            {
                throw new System.Exception(string.Format("Prometeia.GetImageFromValidator: {0}", ex.Message));
            }
        }

        public Stream GetMapComuniItalyMappatura(List<Consulenza.ExternalServices.PrometeiaWSPuc.mapComune> codiciComuneMarker)
        {
           
            // necessario per chiamate SSL
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            /*System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            var client = new CatastoServiceService
            {
                PreAuthenticate = true,
                Url = ConfigurationManager.AppSettings["UrlPrometeiaCatasto"],
                Credentials = new NetworkCredential(_userNamePrometeiaCatasto, _passwordPrometaiaCatasto),
                Proxy = _proxy
            };*/

            try
            {
                var client1 = new PrometeiaWSPuc.PrometeiaProxyServices();
                var response = client1.getMapComuniItaly(
                new Consulenza.ExternalServices.PrometeiaWSPuc.mapComuniItalyRequest
                {
                    user = new Consulenza.ExternalServices.PrometeiaWSPuc.user
                    {
                        username = _userNamePrometeiaCatasto,
                        password = _passwordPrometaiaCatasto
                    },
                    codiciComune = null,
                    markerUrl = "",
                    comuni = codiciComuneMarker.ToArray()
                });
                /*FOR TLS 1.2 DEBUG PURPOSE MC*/
                //var xmlinput = Helper.SerializeXml(new mapComuniItalyRequest
                //{
                //    user = new user
                //    {
                //        username = _userNamePrometeiaCatasto,
                //        password = _passwordPrometaiaCatasto
                //    },
                //    codiciComune = null,
                //    markerUrl = "",
                //    comuni = codiciComuneMarker.ToArray()
                //});
                //var xml = Helper.SerializeXml(response);
                ////System.Diagnostics.Debug.WriteLine("response :"+ response);
                //System.Diagnostics.Debug.WriteLine("dati input :" + xmlinput);
                //System.Diagnostics.Debug.WriteLine("response xml :" + xml);
                /*FOR TLS 1.2 DEBUG PURPOSE MC*/
                return response == null ? null : new MemoryStream(response.stream);
            }
            catch (System.Exception ex)
            {
                throw new System.Exception(string.Format("Prometeia.GetMapComuniItaly: {0}", ex.Message));
            }

        }
        /// <summary>
        /// Ritorna un'immagine della cartina dell'italia con il placeholder sui comuni in input (codiciComune).
        /// </summary>
        /// <param name="codiciComune">array dei codici dei comuni da evidenziare</param>
        /// <returns></returns>
        public Stream GetMapComuniItaly(string[] codiciComune)
        {
            // necessario per chiamate SSL
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        
            //var client = new CatastoServiceService
            //{
            //    PreAuthenticate = true,
            //    Url = ConfigurationManager.AppSettings["UrlPrometeiaCatasto"],
            //    Credentials = new NetworkCredential(_userNamePrometeiaCatasto, _passwordPrometaiaCatasto),
            //    Proxy = _proxy
            //};

            try
            {
                var client1 = new PrometeiaWSPuc.PrometeiaProxyServices();
                var response = client1.getMapComuniItaly(
                new Consulenza.ExternalServices.PrometeiaWSPuc.mapComuniItalyRequest
                {
                    codiciComune = codiciComune,
                    markerUrl = "http://sla.prometeia.it/tmp/puntatore63_v3.png",
                    comuni = null,
                    user = new Consulenza.ExternalServices.PrometeiaWSPuc.user
                    {
                        username = _userNamePrometeiaCatasto,
                        password = _passwordPrometaiaCatasto
                    }
                });
                /*FOR TLS 1.2 DEBUG PURPOSE MC*/
                //var xmlinput = Helper.SerializeXml(new mapComuniItalyRequest
                //{
                //    codiciComune = codiciComune,
                //    markerUrl = "http://sla.prometeia.it/tmp/puntatore63_v3.png",
                //    comuni = null,
                //    user = new user
                //    {
                //        username = _userNamePrometeiaCatasto,
                //        password = _passwordPrometaiaCatasto
                //    }
                //});
                //var xml = Helper.SerializeXml(response);
                ////System.Diagnostics.Debug.WriteLine("response :"+ response);
                //System.Diagnostics.Debug.WriteLine("dati input :" + xmlinput);
                //System.Diagnostics.Debug.WriteLine("response xml :" + xml);
                /* FOR TLS 1.2 DEBUG PURPOSE MC*/
               
                return response == null ? null : new MemoryStream(response.stream);
            }
            catch (System.Exception ex)
            {
                throw new System.Exception(string.Format("Prometeia.GetMapComuniItaly: {0}", ex.Message));
            }

        }

        /// <summary>
        /// Ritorna una lista di FiscalitaImmobile per ogni immobile passato in input effettuando la chiamata al metodo "fiscalitaImmobili".
        /// </summary>
        /// <param name="datiInput">dati di input</param>
        public List<FiscalitaImmobile> GetFiscalitaImmobili(DataRow[] datiInput)
        {
            // necessario per chiamate SSL
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            //System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
          
            //var client = new CatastoServiceService
            //{
            //    PreAuthenticate = true,
            //    Url = ConfigurationManager.AppSettings["UrlPrometeiaCatasto"],
            //    Credentials = new NetworkCredential(_userNamePrometeiaCatasto, _passwordPrometaiaCatasto),
            //    Proxy = _proxy
            //};

            try
            {
                #region chiamata

                var input = new Consulenza.ExternalServices.PrometeiaWSPuc.aliquoteImmobiliRequest 
                {
                    user = new Consulenza.ExternalServices.PrometeiaWSPuc.user
                    {
                        username = _userNamePrometeiaCatasto,
                        password = _passwordPrometaiaCatasto
                    },

                    immobili = (from DataRow row in datiInput
                                select new Consulenza.ExternalServices.PrometeiaWSPuc.aliquotaImmobileInput
                                {
                                    abitazionePrincipale = row["abitazionePrincipale"] != DBNull.Value && Convert.ToBoolean(row["abitazionePrincipale"]),
                                    abitazionePrincipaleSpecified = true,
                                    pertinenzaAbPrincipale = row["pertinenzaAbPrincipale"] != DBNull.Value && Convert.ToBoolean(row["pertinenzaAbPrincipale"]),
                                    pertinenzaAbPrincipaleSpecified = true,
                                    categoria = row["categoria"].ToString(),
                                    chiaveImmobile = row["chiaveImmobile"].ToString(),
                                    comune = row["comune"].ToString(),
                                    indirizzo = row["indirizzo"].ToString(),
                                    tipoCatasto = row["tipoCatasto"].ToString(),
                                    mesiPossesso = 12, // Fisso e sempre valorizzato a '12'
                                    mesiPossessoSpecified = true,
                                    presenzaDetentore = false, // Fisso e sempre valorizzato a 'no'
                                    presenzaDetentoreSpecified = true,
                                    renditaCatastale = row["renditaCatastale"] == DBNull.Value ? 0 : Convert.ToDecimal(row["renditaCatastale"]),
                                    renditaCatastaleSpecified = true,
                                    destinazioneUso = row["destinazioneUso"].ToString(),
                                    codAliquota = string.Empty,
                                    detrazioniImu = null,
                                    detrazioniTasi = null,
                                    codSubAliquoteImu = string.Empty,
                                    codSubAliquoteTasi = string.Empty
                                }).ToArray(),

                    rangeValori = true, //Fisso e sempre valorizzato a 'TRUE',
                    rangeValoriSpecified = true


                };

                //var xml = Helper.SerializeXml(input);
                #endregion

                #region risposta
                /* dubug options MC*/
                //catastoSR.CatastoServiceClient cs = new catastoSR.CatastoServiceClient();
                //var response = cs.fiscalitaImmobili(input);
                //Console.WriteLine("response :" + response);
                //Console.WriteLine("response xml :" + xml);
                var xmlinput = Helper.SerializeXml(input);
                //System.Diagnostics.Debug.WriteLine("client :" + client);
                //var response = client.fiscalitaImmobili(input);
                var client1 = new PrometeiaWSPuc.PrometeiaProxyServices();
                var response = client1.fiscalitaImmobili(input);
                var xml = Helper.SerializeXml(response);
                //System.Diagnostics.Debug.WriteLine("response :"+ response);
                //System.Diagnostics.Debug.WriteLine("dati input :" + xmlinput);
                System.Diagnostics.Debug.WriteLine("response xml :" + xml);
                //System.Diagnostics.Debug.WriteLine("dati input :" + datiInput);
                //System.Diagnostics.Debug.WriteLine("client :" + client);
                /* dubug options MC*/
             
                //var response = client.fiscalitaImmobili(input);

                #endregion

                #region ritorno

                return datiInput
                    .Select(row =>
                        response.immobili.FirstOrDefault(o => o.chiaveImmobile.Equals(row["chiaveImmobile"].ToString())))
                    .Select(aliquotaResponse => new FiscalitaImmobile
                    {
                        ChiaveImmobile = aliquotaResponse.chiaveImmobile,
                        ImuValoreMinimo = aliquotaResponse.imu == null ? (decimal?)null : aliquotaResponse.imu.valoreMin,
                        ImuValoreMassimo = aliquotaResponse.imu == null ? (decimal?)null : aliquotaResponse.imu.valoreMax,
                        TasiValoreMinimo = aliquotaResponse.tasi == null ? (decimal?)null : aliquotaResponse.tasi.valoreMin,
                        TasiValoreMassimo = aliquotaResponse.tasi == null ? (decimal?)null : aliquotaResponse.tasi.valoreMax

                    }).ToList();

                #endregion
            }
            catch (System.Exception ex)
            {
                /*FOR TLS 1.2 DEBUG PURPOSE MC*/
                //System.Diagnostics.Debug.WriteLine(ex.InnerException.ToString());
                //System.Diagnostics.Debug.WriteLine(ex.ToString());
                /*FOR TLS 1.2 DEBUG PURPOSE MC*/
                throw new System.Exception(string.Format("Prometeia.GetFiscalitaImmobili: {0}", ex.Message));
            }
        }

        /// <summary>
        /// Ritorna una lista di coppie <min,max> della Tari per ogni immobile passato in input effettuando la chiamata al metodo "GetFiscalitaTari".
        /// </summary>
        /// <param name="datiInput">dati di input</param>
        public List<FiscalitaImmobile> GetFiscalitaTari(DataRow[] datiInput)
        {
            // necessario per chiamate SSL
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            //System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            //var client = new CatastoServiceService
            //{
            //    PreAuthenticate = true,
            //    Url = ConfigurationManager.AppSettings["UrlPrometeiaCatasto"],
            //    Credentials = new NetworkCredential(_userNamePrometeiaCatasto, _passwordPrometaiaCatasto),
            //    Proxy = _proxy
            //};

            try 
            { 
                #region Chiamata

                var input = new Consulenza.ExternalServices.PrometeiaWSPuc.tariImmobiliRequest
                {
                    user = new Consulenza.ExternalServices.PrometeiaWSPuc.user
                    {
                        username = _userNamePrometeiaCatasto,
                        password = _passwordPrometaiaCatasto
                    },
                    immobili = (from DataRow row in datiInput
                                select new Consulenza.ExternalServices.PrometeiaWSPuc.tariImmobileInput
                                {
                                    categoriaCatastale = row["categoriaCatastale"].ToString(),
                                    chiaveImmobile = row["chiaveImmobile"].ToString(),
                                    codComune = row["CodComune"].ToString(),
                                    destinazioneUso = row["destinazioneUso"].ToString(),
                                    pertinenzaUtDomestica = (row["categoriaCatastale"].ToString() == "C/2" || row["categoriaCatastale"].ToString() == "C/6" || row["categoriaCatastale"].ToString() == "C/7") ? true : false,
                                    superficieTARI = Convert.ToDecimal(Helper.FormatDecimal(row["superficieTARI"].ToString(),2)) != 0 ? Convert.ToDecimal(row["superficieTARI"]) : 0,
                                    tipoCatasto = row["tipoCatasto"].ToString(),
                                    superficieTARISpecified = Convert.ToDecimal(Helper.FormatDecimal(row["superficieTARI"].ToString(), 2)) != 0 ? true : false,
                                    pertinenzaUtDomesticaSpecified = true
                                }).ToArray(),

                    rangeValori = true, //Fisso e sempre valorizzato a 'TRUE',
                    rangeValoriSpecified = true
                };
                #endregion

                #region Risposta
                var client1 = new PrometeiaWSPuc.PrometeiaProxyServices();
                var response = client1.fiscalitaTari(input);
                //var response = client.tariImmobili(input);
                var xml = Helper.SerializeXml(response);
                #endregion

                #region Ritorno

                return datiInput
                    .Select(row =>
                        response.immobili.FirstOrDefault(o => o.chiaveImmobile.Equals(row["chiaveImmobile"].ToString())))
                    .Select(aliquotaResponse => new FiscalitaImmobile
                    {
                        ChiaveImmobile = aliquotaResponse.chiaveImmobile,
                        TariValoreMinimo= aliquotaResponse.tariMin == null ? (decimal?)null : aliquotaResponse.tariMin,
                        TariValoreMassimo = aliquotaResponse.tariMax == null ? (decimal?)null : aliquotaResponse.tariMax,
                    }).ToList();

                #endregion
            }
            catch (System.Exception ex)
            {
                throw new System.Exception(string.Format("Prometeia.GetFiscalitaTari: {0}", ex.Message));
            }
        }
    }
}
