using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Runtime.InteropServices;
using tsEFCore7.Extensiones;
using tsUtilidades;


namespace bdAntifraude.dbcontext
{
    public class tsGestionAntifraude : gestionantifraudeContext, tsUtilidades.ItsContexto
    {
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.HasDefaultSchema(null);
        }
        public tsGestionAntifraude(DbContextOptions<gestionantifraudeContext> Opciones) : base(Opciones)
        {
            if (_Ip == null) { ip = "pendiente"; }
            else { ip = _Ip; }
        }

        public string Aplicaciones { get; private set; }
        private static String? _Ip = null;
        public string? ip
        {
            get
            {
                return _Ip;
            }
            set
            {
                _Ip = value;
            }
        }

        private bool NoTracking;
        public bool Lazy;



        public static readonly Microsoft.Extensions.Logging.LoggerFactory _myLoggerFactory =
            new LoggerFactory(new[] {
        new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider()
    });



        public static void EstableceCBD(string WriteConnection, string ReadOnlyConnection, bool soloLectura = false)
        {
            Comun.CadenaConexionBD = soloLectura ? ReadOnlyConnection : WriteConnection;
            Comun.CadenaConexionBD_SL = ReadOnlyConnection;
        }

        // Método para crear un nuevo contexto basado en SoloLectura
        public static tsGestionAntifraude NuevoContexto(bool SoloLectura = false, bool UseLazyLoadingProxies = true, bool ConEventoSavingChanges = false, string aplicaciones = "")
        {
            //if (string.IsNullOrEmpty(Comun.CadenaConexionBD))
            //{
            //    EstableceCBD(SoloLectura);
            //}
            //else
            //{
            //    Si el contexto actual no coincide con el requerido, actualiza la cadena
            //    bool esLecturaActual = Comun.CadenaConexionBD == ReadOnlyConnection;
            //    if (SoloLectura && !esLecturaActual)
            //    {
            //        EstableceCBD(true);
            //    }
            //    else if (!SoloLectura && esLecturaActual)
            //    {
            //        EstableceCBD(false);
            //    }
            //}
            string cn = Comun.CadenaConexionBD;
            if (SoloLectura) cn = Comun.CadenaConexionBD_SL;
            var ob = new DbContextOptionsBuilder<gestionantifraudeContext>();
            ob.UseOracle(cn, options => options.UseOracleSQLCompatibility("11"));
            if (UseLazyLoadingProxies) ob.UseLazyLoadingProxies();
            if (SoloLectura && UseLazyLoadingProxies == false) ob.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
            var Opciones = ob.Options;
            tsGestionAntifraude bd = new tsGestionAntifraude(Opciones);
            bd.Aplicaciones = aplicaciones;
            if (ConEventoSavingChanges) bd.SavingChanges += GuardandoCambios;
            return bd;
        }


        //public tsGestionAntifraude(bool v, string v1, DbContextOptions<tsGestionAntifraude> Opciones) : base(Opciones)
        //{
        //    if (_Ip == null) { ip = tsUtilidades.bbdd.ObtieneIPMysql(this); }
        //    else { ip = _Ip; }
        //}

        //public tsGestionAntifraude (bool SoloLectura ,string CadenaConexion, bool UseLazyLoadingProxies = true )

        //{
        //    Lazy = UseLazyLoadingProxies;
        //    CadenaConexionBD= CadenaConexion;
        //    if (Comun.CadenaConexionBD != "") Comun.CadenaConexionBD = CadenaConexion;
        //    NoTracking = SoloLectura;



        //    // tscGestionGuadex ctx = new tscGestionGuadex();
        //    //if (Lazy) ctx.ChangeTracker.LazyLoadingEnabled = true;
        //    //db.usuarios? usu = ctx.usuarios.FirstOrDefault(x => x.Usuario == "jjj" );
        //    //var tb = tsUtilidades.Extensiones.EntityExtensions.ObtieneSet(usu,ctx);
        //    //bool EsUnico = !tb.Any("Usuario" + "==\"" + "manmog" + "\"", null);

        //}


        //public event ItsContexto.GuardandoCambiosEventHandler GuardandoCambios;
        private static void GuardandoCambios(object? sender, SavingChangesEventArgs e)
        {
            try
            {
                tsGestionAntifraude bd = (tsGestionAntifraude)sender;
                var lap = bd.Aplicaciones.Split("|");
                foreach (string ap in lap)
                {
                    switch (ap.ToLower())
                    {
                        //case "facturas":
                        //    {
                        //        tsGestionAntifraude.db.facturas.GuardandoCambios(bd, ap);
                        //        break;
                        //    }
                    }
                }
            }
            catch (Exception)
            {

                throw;
            }
        }
        public void AñadeObjeto(object Registro)
        {
            this.Add(Registro);
        }

        public bool CompruebaUnico(EstadosAplicacion estado, string NombreCampo, object Valor, string NombreTablaBase, object DataContext)
        {
            return this.CompruebaRegistroUnico(estado == EstadosAplicacion.ModificandoRegistro, "bdGestionAntifraude.db", NombreTablaBase, NombreCampo, Valor, DataContext);

            //string Busqueda = NombreCampo + "==\"" + (string)Valor + "\"";
            //if (estado == EstadosAplicacion.ModificandoRegistro)
            //{
            //    string CampoIndice = this.ObtieneCampoIndice(uc.DataContext);
            //    string ValorCampoIndice = (string)this.Entry(uc.DataContext).Property(CampoIndice).CurrentValue.ToString();
            //    Busqueda += " && " + CampoIndice + "!=" + ValorCampoIndice;
            //}
            //bool resp = this.Query("bdGestionGuadex.db." + uc.NombreTablaBase).Any(Busqueda);
            //return resp;
        }
        public void EliminaObjeto(object Registro)
        {
            if (this.Entry(Registro).State == Microsoft.EntityFrameworkCore.EntityState.Detached)
            {
                this.Entry(Registro).State = Microsoft.EntityFrameworkCore.EntityState.Unchanged;
            }
            else if (this.Entry(Registro).State == Microsoft.EntityFrameworkCore.EntityState.Added)
            {
                this.Remove(Registro);
                this.Entry(Registro).State = Microsoft.EntityFrameworkCore.EntityState.Unchanged;
            }
            else
            {
                this.Remove(Registro);
            }

        }

        public int GuardarCambios()
        {
            return this.SaveChanges();
        }

        public bool HayModificaciones()
        {
            IEnumerable<Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry> res = from e in this.ChangeTracker.Entries()
                                                                                        where e.State.HasFlag(Microsoft.EntityFrameworkCore.EntityState.Added) ||
                                                                                            e.State.HasFlag(Microsoft.EntityFrameworkCore.EntityState.Modified) ||
                                                                                            e.State.HasFlag(Microsoft.EntityFrameworkCore.EntityState.Deleted)
                                                                                        select e;

            if (res.Any())
                return true;
            return false;
        }
        public int ObtieneLongitudCampo(string NombreTablaBase, string NombreCampo)
        {
            return this.ObtieneMaximaLongitudCampo("bdAntifraude.db", NombreTablaBase, NombreCampo);
        }
    }
}

