using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
using bdAntifraude.dbcontext;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.Linq.Expressions;
using SwaggerAntifraude.DTOs;
using System.Linq.Dynamic.Core;
using bdAntifraude.db;
using System.Runtime.CompilerServices;
using Serialize.Linq.Serializers;
using SwaggerAntifraude.Controllers;



namespace SwaggerAntifraude.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class PERSONASController : GenericoController<PERSONAS, int>
    {
        public PERSONASController()
            : base()
        {
        }



        [HttpGet]
        public override async Task<IActionResult> GetAll()
        {
            try
            {
                using (var context = tsGestionAntifraude.NuevoContexto(SoloLectura: true, UseLazyLoadingProxies: false))
                {
                    var entities = await context.PERSONAS
                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                            .ThenInclude(rpt => rpt.IDRPTNavigation)
                                .ThenInclude(sit => sit.IDSITUACIONNavigation)
                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                            .ThenInclude(ocu => ocu.IDOCUPACIONNavigation)
                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                            .ThenInclude(rpt => rpt.IDRPTDESNavigation)
                                .ThenInclude(rpt => rpt.IDUNIDADADMINISTRATIVANavigation)
                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                        .Include(cp => cp.IDDEPARTAMENTONavigation)
                        .Include(cp => cp.CODIGOMUNICIPIONavigation)
                            .ThenInclude(cpro => cpro.CODIGOPROVINCIANavigation)
                        .Include(cp => cp.IDSITUACIONACTUALIRPFNavigation)
                        .Include(cp => cp.CODIGOMUNICIPIONavigation)       
                        .Include(cp=>cp.IDTIPONavigation)
                        .Include(cp=>cp.IDDEPARTAMENTONavigation)
                        .Include(cp => cp.IDSEXONavigation)
                        .Include(cp => cp.INCIDENCIAS)
                        .AsNoTracking()
                        .ToListAsync();
                    //.Include(v => v.IDSERVICIOADSCRITONavigation)
                    //.Include(v => v.IDUNIDADADMINISTRATIVANavigation)
                    return Ok(entities);
                }
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Error interno del servidor: {ex.Message}");
            }
        }

        [Authorize(Policy = "LecturaPolicy")]
        [HttpGet("PersonaNominaNif/{nif}")]
        public IActionResult GetByNifNom(string nif)
        {
            try
            {
                using (var context = tsGestionAntifraude.NuevoContexto(SoloLectura: true, UseLazyLoadingProxies: false))
                {
                    var persona = context.PERSONAS.Include(pue => pue.PUESTOSIDPERSONALNavigation)
                                                            .ThenInclude(rpt => rpt.IDRPTNavigation)
                                                                .ThenInclude(sit => sit.IDSITUACIONNavigation)
                                                        .Include(pue => pue.IDSEXONavigation)
                                                        .Include(pue => pue.IDTIPONavigation)
                                                        .Include(pue => pue.IDNIVELRPTNavigation)
                                                        .Include(pue => pue.ASCENDIENTES)
                                                        .ThenInclude(dis => dis.IDDISCAPACIDADNavigation)
                                                        .Include(pue => pue.HIJOS)
                                                            .ThenInclude(dis => dis.IDDISCAPACIDADNavigation)
                                                        .Include(pue => pue.DIFERENCIAPAGODELEGADO)
                                                        .Include(pue => pue.DIFERENCIATRIENIOS)
                                                        .Include(pue => pue.REDUCCIONDEJORNADA)
                                                        .Include(pue => pue.TRABAJADORTIEMPOPARCIAL)
                                                        .Include(cp => cp.ENFERMEDADES)
                                                            .ThenInclude(y => y.IDTIPONavigation)
                                                        .Include(cp => cp.MATERNIDADES)
                                                        .Include(cp => cp.IDOCUPACIONNavigation)
                                                        .Include(cp => cp.HUELGAS)
                                                            .ThenInclude(cpro => cpro.IDNOMINAORIGENDATOSNavigation)
                                                        .Include(cp => cp.HUELGAS)
                                                            .ThenInclude(cpro => cpro.IDNOMINAAPLICACIONNavigation)
                                                        .Include(cp => cp.INCIDENCIAS)
                                                            .ThenInclude(idnom => idnom.IDNOMINANavigation)
                                                        .Include(cp => cp.INCIDENCIAS)
                                                            .ThenInclude(idnom => idnom.IDCONCEPTONOMINANavigation)
                                                        .Include(n => n.NOMINATRABAJADORCABECERA)
                                                            .ThenInclude(pr => pr.IDNOMINANavigation)
                                                        .Include(n => n.NOMINATRABAJADORCABECERA)
                                                            .ThenInclude(pr => pr.NOMINATRABAJADORLINEA)
                                                            .ThenInclude(y => y.IDCONCEPTOGENERALNavigation)
                                                        .Include(n => n.NOMINATRABAJADORCABECERA)
                                                            .ThenInclude(pr => pr.NOMINATRABAJADORPAGOESPECIE)
                                                        .Include(n => n.NOMINATRABAJADORCABECERA)
                                                            .ThenInclude(pr => pr.PERIODOSSILTRA)
                                                            .ThenInclude(y => y.IDCONTRATONavigation)
                                                        .Include(n => n.NOMINATRABAJADORCABECERA)
                                                            .ThenInclude(pr => pr.PERIODOSSILTRA)
                                                            .ThenInclude(y => y.IDESTADONavigation)
                                                        .Include(n => n.NOMINATRABAJADORCABECERA)
                                                            .ThenInclude(y => y.IDSINDICATO1Navigation)
                                                        .Include(n => n.NOMINATRABAJADORCABECERA)
                                                            .ThenInclude(y => y.IDSINDICATO2Navigation)
                                                        .Include(pue => pue.OTRASRETRIBUCIONES)
                                                          .Include(cp => cp.PERMISOSSINRETRIBUCION)
                                                            .ThenInclude(cpro => cpro.IDNOMINAORIGENDEDATOSNavigation)
                                                        .Include(cp => cp.PERMISOSSINRETRIBUCION)
                                                            .ThenInclude(cpro => cpro.IDNOMINAAPLICACIONNavigation)
                                                        .Include(pue => pue.PRESTAMOS)
                                                            .ThenInclude(pre => pre.IDNOMINAINICIONavigation)
                                                        .Include(cp => cp.PUESTOSTRABAJO)
                                                            .ThenInclude(cpro => cpro.IDTIPOPUESTOTRABAJONavigation)
                                                        .Include(cp => cp.PUESTOSTRABAJO)
                                                           .ThenInclude(cpro => cpro.IDGRUPOFUNCIONARIONavigation)
                                                        .Include(pue => pue.REDUCCIONDEJORNADA)
                                                        .Include(pue => pue.RETENCIONJUDICIAL)
                                                            .ThenInclude(ret => ret.IDPLANTILLANavigation)
                                                        .Include(pue => pue.PRODUCTIVIDAD)
                                                        .Include(pue => pue.IDSITUACIONACTUALIRPFNavigation)
                                                            .ThenInclude(situ => situ.IDDISCAPACIDADNavigation)
                                                        .Include(pue => pue.IDSITUACIONACTUALIRPFNavigation)
                                                            .ThenInclude(situ => situ.IDSITUACIONFAMILIARNavigation)
                                                        .Include(pue => pue.IDSITUACIONACTUALIRPFNavigation)
                                                            .ThenInclude(situ => situ.IDSITUACIONLABORALNavigation)
                                                        .Include(pue => pue.IDSITUACIONACTUALIRPFNavigation)
                                                            .ThenInclude(situ => situ.IDCONTRATOORELACIONNavigation)
                                                        .Include(pue => pue.HISTORICOIRPF)
                                                        .Include(pue => pue.IDMUTUANavigation)
                                                        .Include(pue => pue.IDMUTUA2Navigation)
                                                        .Include(pue => pue.IDPUESTOTRABAJOOPOSICIONNavigation)
                                                        .Include(pue => pue.IDCAUSABAJAPARNavigation)
                                                        .Include(pue => pue.IDCONTRATONavigation)
                                                        .Include(pue => pue.IDGRUPOFUNCIONARIONavigation)
                                                        .Include(pue => pue.IDCUENTACOTIZACIONPATRONALNavigation)
                                                        .Include(pue => pue.IDDEPARTAMENTONavigation)
                                                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                                                            .ThenInclude(ocu => ocu.IDOCUPACIONNavigation)
                                                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                                                            .ThenInclude(rpt => rpt.IDRPTDESNavigation)
                                                                .ThenInclude(rpt => rpt.IDUNIDADADMINISTRATIVANavigation)
                                                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                                                                .ThenInclude(rpt => rpt.IDRPTDESNavigation)
                                                                    .ThenInclude(x => x.IDDEPARTAMENTONavigation)
                                                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                                                        .Include(pue => pue.EXCEPCIONESPERMISOSIDPERSONANavigation)
                                                            .ThenInclude(exc=>exc.IDDEPARTAMENTONavigation)
                                                      .Include(pue => pue.EXCEPCIONESPERMISOSIDPERSONANavigation)
                                                            .ThenInclude(exc => exc.IDPERSONAPERMISONavigation)
                                                        .Include(cp=>cp.DIFERENCIAPAGODELEGADO)
                                                        .Include(cp => cp.IDDEPARTAMENTONavigation)                                                     
                                                        .Include(cp => cp.CODIGOMUNICIPIONavigation)
                                                            .ThenInclude(cpro => cpro.CODIGOPROVINCIANavigation)
                                                        .AsSplitQuery()
                                                        .FirstOrDefault(p => p.NIF == nif);
                    if (persona == null)
                        return NotFound();

                    return Ok(persona);
                }
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Error interno del servidor: {ex.Message}");
            }
        }


        [Authorize(Policy = "LecturaPolicy")]
        [HttpGet("nif/{nif}")]
        public IActionResult GetByNif(string nif)
        {
            try
            {
                using (var context = tsGestionAntifraude.NuevoContexto(SoloLectura: true, UseLazyLoadingProxies: false))
                {
                    var persona = context.PERSONAS.Include(pue=> pue.PUESTOSIDPERSONALNavigation)
                                                        .ThenInclude(rpt => rpt.IDRPTNavigation)
                                                        .ThenInclude(sit=> sit.IDSITUACIONNavigation)
                                                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                                                        .ThenInclude(ocu => ocu.IDOCUPACIONNavigation)
                                                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                                                        .ThenInclude(rpt => rpt.IDRPTDESNavigation)
                                                        .ThenInclude(rpt => rpt.IDUNIDADADMINISTRATIVANavigation)
                                                        .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                                                        //.Include(n => n.NOMINATRABAJADORCABECERA)
                                                        //.ThenInclude(pr => pr.IDPERSONANavigation)
                                                        .Include(cp => cp.IDDEPARTAMENTONavigation)
                                                        .Include(cp => cp.CODIGOMUNICIPIONavigation)                                                        
                                                        .ThenInclude(cpro => cpro.CODIGOPROVINCIANavigation)
                                                                                                                .Include(pue => pue.PUESTOSIDPERSONALNavigation)
                                                                .ThenInclude(rpt => rpt.IDRPTDESNavigation)
                                                                    .ThenInclude(x => x.IDDEPARTAMENTONavigation)
                                                        .AsNoTracking()
                                                        .FirstOrDefault(p => p.NIF == nif);
                    if (persona == null)
                        return NotFound();

                    return Ok(persona);
                }
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Error interno del servidor: {ex.Message}");
            }
        }

        [Authorize(Policy = "LecturaPolicy")]
        [HttpPost("getPersonaVidaAdm")]
        public virtual async Task<IActionResult> getPersonaVidaAdm([FromBody] ExpressionWrapper request)
        {
            try
            {
                using (var context = tsGestionAntifraude.NuevoContexto(SoloLectura: true, UseLazyLoadingProxies: false))
                {
                    // Crear el deserializador
                    var serializer = new ExpressionSerializer(new Serialize.Linq.Serializers.JsonSerializer());
                    // Deserializar la expresión
                    var deserializedExpression = serializer.DeserializeText(request.Expression) as Expression<Func<PERSONAS, bool>>;
                    if (deserializedExpression == null)
                    {
                        return BadRequest("La expresión deserializada es nula o incorrecta.");
                    }

                    var entities = await context.Set<PERSONAS>()
                        .Where(deserializedExpression)
                        .Include(v => v.IDGRADOPERSONALCONSOLIDADONavigation) // Incluyendo la navegación principal                            
                        .Include(v => v.IDNIVELRPTNavigation)                        
                        .Include(v => v.IDGRUPOFUNCIONARIONavigation)                           
                        .Include(v => v.IDTIPONavigation)
                        .Include(cp => cp.IDDEPARTAMENTONavigation)
                        .Include(v => v.IDADSCRIPCIONRPTNavigation)
                        .Include(v => v.IDCUERPORPTNavigation)
                        .AsNoTracking()
                        .ToListAsync();


                    // Verificar si el resultado es vacío
                    if (entities.Count == 0)
                    {
                        Console.WriteLine("La consulta no devolvió resultados.");
                    }

                    return Ok(entities.First());
                }
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Error interno del servidor: {ex.Message}");
            }
        }

        [Authorize(Policy = "LecturaPolicy")]
        [HttpPost("filtrar")] 
        public override async Task<IActionResult> Filtrar([FromBody] ExpressionWrapper request)
        {
            try
            {
                using (var context = tsGestionAntifraude.NuevoContexto(SoloLectura: true, UseLazyLoadingProxies: false))
                {
                    // Crear el deserializador
                    var serializer = new ExpressionSerializer(new Serialize.Linq.Serializers.JsonSerializer());

                    // Deserializar la expresión
                    var deserializedExpression = serializer.DeserializeText(request.Expression) as Expression<Func<PERSONAS, bool>>;
                    if (deserializedExpression == null)
                    {
                        return BadRequest("La expresión deserializada es nula o incorrecta.");
                    }
                    var entities = await context.PERSONAS.Where(deserializedExpression)
                                           .Include(v => v.IDSITUACIONADMINISTRATIVARPTNavigation)
                                           
                                           .AsNoTracking()
                                           .ToListAsync();

                    // Verificar si el resultado es vacío
                    if (entities.Count == 0)
                    {
                        Console.WriteLine("La consulta no devolvió resultados.");
                    }

                    return Ok(entities);
                }
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Error interno del servidor: {ex.Message}");
            }
        }
    }
}
