using Consulenza.DataServices.fideuram.data.service;
using System.Configuration;
using System;
using System.Data;
using System.Collections.Generic;

namespace Consulenza.DataServices
{
    /// <summary>
    /// Classe astratta da cui erediteranno tutte le classi di Consulenza.DataServices.
    /// Contiene tutti gli oggetti necessari per la chiamata al servizio dati (fideuram.data.service).
    /// </summary>
    public abstract class FideuramData
    {
        private ReportManagerService _dataservice;
        private const string ClassName = "FideuramData";

        /// <summary>
        /// Recupera il servizio attraverso cui recuperare i dati.
        /// </summary>
        public ReportManagerService DataService { get { return _dataservice ?? (_dataservice = GetDataService()); } }

        /// <summary>
        /// Recupera il servizio dati.
        /// </summary>
        /// <returns></returns>
        private static ReportManagerService GetDataService()
        {
            return new ReportManagerService
            {
                Url = ConfigurationManager.AppSettings["UrlFideuramDati"],
                UseDefaultCredentials = true,
                Timeout = Convert.ToInt32(ConfigurationManager.AppSettings["TimeoutFideuramDati"]) * 1000
            };
        }


        private uidConsulenza _userIdConsulenza;

        /// <summary>
        /// La chiave con cui accedere al servizio dati.
        /// </summary>
        public uidConsulenza UserIdConsulenza { get { return _userIdConsulenza ?? (_userIdConsulenza = GetUserIdConsulenza()); } }

        /// <summary>
        /// Recupera la UserIdConsulenza. La chiave con cui accedere al servizio dati.
        /// </summary>
        /// <returns></returns>
        private uidConsulenza GetUserIdConsulenza()
        {
            var keyForCache = GetKeyForCache(ClassName, "GetUserIdConsulenza");
            uidConsulenza uidConsulenza;

            //if (CacheStore.Exists<uidConsulenza>(keyForCache))
            //{
            //    // Rileggo dalla cache
            //    uidConsulenza = CacheStore.Get<uidConsulenza>(keyForCache);
            //}
            //else
            //{
                DataTable dtCliente;

                try
                {
                    dtCliente = DataAccess.ExecuteDataTableStoredProcedure(
                         DBProvider.SqlServerConsulenzaUnica,
                         "REP_INFOCLIENTEPB",
                         new List<Parametro> { new Parametro
                    {
                        Direction = ParameterDirection.Input,
                        DbType = DbType.Int64,
                        ParameterName = "chiaveClientePb",
                        Value = ChiaveClientePb
                    }});

                    if (dtCliente.Rows.Count <= 0)
                        throw new Exception("Consulenza.DataServices.GetUserIdConsulenza: Cliente non trovato");
                }
                catch (Exception ex)
                {
                    throw new Exception("Consulenza.DataServices.GetUserIdConsulenza:" + ex.Message);
                }

                uidConsulenza = new uidConsulenza
                {
                    codiceAgente = dtCliente.Rows[0]["CodAge"].ToString().ToUpper(),
                    codiceFiscale = dtCliente.Rows[0]["CodFis"].ToString().ToUpper(),
                    codiceRete = dtCliente.Rows[0]["Rete"].ToString().ToUpper(),
                    codiceMandato = dtCliente.Rows[0]["CodMan"].ToString().ToUpper()
                };

                // Memorizzo in chache
            //    CacheStore.Add(keyForCache, uidConsulenza);
            //}

            return uidConsulenza;
        }


        /// <summary>
        /// Imposta o recupera la ChiaveClientePb.
        /// </summary>
        public Int64 ChiaveClientePb { get; set; }

        /// <summary>
        /// Recupera la chiave di memorizzazione in cache.
        /// </summary>
        /// <param name="className">nome della classe</param>
        /// <param name="methodName">nome del metodo</param>
        /// <returns></returns>
        public string GetKeyForCache(string className, string methodName)
        {
            return string.Format("{0}.{1}_{2}", className, methodName, ChiaveClientePb);
        }

        /// <summary>
        /// Esegue la request passata in input restituendo un oggetto di response popolato con la stessa struttura di input.
        /// </summary>
        /// <param name="requestdata">oggetto request</param>
        /// <returns></returns>
        public rsReportManager Execute(rqData requestdata)
        {
            throw new Exception("class FideuramData Deprecated");
            try
            {
               
                var data = DataService.reportManagerWS(new rqReportManager
                          {
                              chiaveClientePB = UserIdConsulenza,
                              requestData = requestdata
                          });

                if (data.info.elencoErrori.Length > 0)
                    throw new Exception(string.Format("Consulenza.DataServices.Execute: {0}-{1}-{2}", data.info.elencoErrori[0].tipoErrore, data.info.elencoErrori[0].codiceErrore, data.info.elencoErrori[0].messaggio));

                return data;
            }
            catch (Exception ex)
            {
                throw new Exception("Consulenza.DataServices.Execute: " + ex.Message);
            }
        }
    }

    /// <summary>
    /// Interfaccia
    /// </summary>
    public interface IFideuramData
    {
        decimal GetTotale(TipoTotaleOutput output);
        //List<rsPosizione> GetListaProdotti();

        rsComposizione GetDistribuzioneAssetClass();
        rsComposizione GetDistribuzioneMacroAssetClass();

        rsComposizione GetDistribuzioneCategoriaProdotto();
        rsComposizione GetDistribuzioneMacroCategoriaProdotto();
    }

    /// <summary>
    /// Enumeratore del tipo di totale in output
    /// </summary>
    public enum TipoTotaleOutput
    {
        NonSpecificato, // Totale non specificato
        RisorseFinanziarie, // Richiesto il totale delle sole Risorse Finanziarie
        Complessivo, // Richiesto il totale compessivo
        ContiCorrentiPositivi, // Totale dei conticorrenti positivi
        ContiCorrentiNegativi,  // Totale dei conticorrenti negativi
        ContiCorrentiComplessivi,  // Totale dei conticorrenti (somma tra positivi e negativi)
        EligoFondiNegativi, //Totale eligo fondi negativi
        EligoTitoliNegativi,  //Totale eligo titoli negativi
        EligoComplessivi, // Totale delgi Eligo(linea Self) (somma tra EligoFondiNegativi e EligoTitoliNegativi)
        OperazioniInCorso, // Totale delle operazioni in corso (partite viaggianti)

        ProdottiNonRappresentabili_MacroAssetClass, //Totale dei prodotti non rappresentabili per Macro Asset Class
    }


    /// <summary>
    /// Enumerato della tipologia di non rappresentabilità del prodotto.
    /// </summary>
    public enum TipoNonRappresentabilitaProdotto
    {
        AssetClass, //Prodotto non rappresentabile in termini di AssetClass
        EsposizioneValutaria, //Prodotto non rappresentabile in termini di Esposizione Valutaria
        CalcoloRendimenti, // Prodotto non rappresentabile in termine di Calcolo dei Rendimenti
        NonCopertoRischioCredito // Prodotto non rappresentabile in termine di Rischio di Credito
    }
}
