using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using bdAntifraude.db;             
using bdAntifraude.dbcontext;     
using SwaggerAntifraude.Models;
using DevExpress.CodeParser;

namespace SwaggerAntifraude.Controllers
{
    [Authorize]
    [Route("api/[controller]")]
    [ApiController]
    public class ResultadoIdentificacionController : ControllerBase
    {
        /// <summary>
        /// Carga el perfil de identificación y las incidencias asociadas para el usuario especificado.
        /// Se asignan roles y se consultan incidencias según el origen (WEBINTRANET, GESTDELE o RPT).
        /// Además, se incluyen en el listado tanto el usuario consultante como sus subordinados,
        /// forzando que el usuario consultante se agregue a la lista (incluso si ya apareciera en el listado de subordinados).
        /// </summary>
        /// <param name="nif">NIF del usuario a identificar.</param>
        /// <param name="origen">Origen de la consulta (por ejemplo: "WEBINTRANET", "GESTDELE" o "RPT").</param>
        /// <returns>Objeto ResultadoIdentificacion con la lista de perfiles e incidencias.</returns>
        [Authorize(Policy = "LecturaPolicy")]
        [HttpGet("nif/{nif}/origen/{origen}")]
        public IActionResult CargaPerfilIdentificacion(string nif, string origen)
        {
            var resultadoIdentificacion = new ResultadoIdentificacion
            {
                Personas = new List<Personal>()
            };

            try
            {
                using (var context = tsGestionAntifraude.NuevoContexto(SoloLectura: true, UseLazyLoadingProxies: false))
                {
                    // Se busca la persona por NIF 
                    var persona = context.PERSONAS
                        .Include(p => p.IDDEPARTAMENTONavigation) // Para obtener la descripción del departamento
                        .AsNoTracking()
                        .FirstOrDefault(p => p.NIF.Trim().ToUpper() == nif.Trim().ToUpper());

                    if (persona == null)
                    {
                        resultadoIdentificacion.resultado = 1;
                        resultadoIdentificacion.errores = $"No se encontró persona con NIF: {nif}";
                        return Ok(resultadoIdentificacion);
                    }

                    // Creamos el objeto Personal para el usuario consultante

                    var grup = context.USUARIOS.Include(x => x.IDGRUPONavigation).FirstOrDefault(x => x.USUARIO == persona.NIF).IDGRUPONavigation.DESCRIPCION;


                    var usuarioActual = new Personal
                    {
                        Nombre = persona.APELLIDOS + ", " + persona.NOMBRE,
                        Departamento = persona.IDDEPARTAMENTONavigation?.DESCRIPCION,
                        Dni = persona.NIF,
                        idPersona = persona.IDPERSONA,
                        Roll = string.Empty,
                        Grupo = grup.ToUpper() == "ACCESO WEB RET" ? "RET" : ""
                    };

                    // Creamos la lista de personas y agregamos inmediatamente el usuario consultante
                    var personas = new List<Personal>();
                    personas.Add(usuarioActual);
                    resultadoIdentificacion.Personas = personas;

                    // Lógica de asignación de roles según el origen
                    if (origen == "WEBINTRANET" || origen == "GESTDELE")
                    {
                        if (persona.DELEGADO)
                            usuarioActual.Roll = "DELEGADO";
                        if (persona.SUPERVISORDEPARTAMENTO)
                            usuarioActual.Roll = "SUPERVISOR";
                        if (persona.SUPERVISORDETODO)
                            usuarioActual.Roll = "SUPERVISORDETODO";
                        if (persona.ADMINISTRADORCONTROLHORARIO)
                            usuarioActual.Roll = "ADMINISTRADORCONTROLHORARIO";

                        // Consultar incidencias en la vista V_ASISTENCIAS_EXTENDIDA
                        List<V_ASISTENCIAS_EXTENDIDA> asisYestados;
                        if (usuarioActual.Roll == "ADMINISTRADORCONTROLHORARIO")
                        {
                            asisYestados = context.V_ASISTENCIAS_EXTENDIDA
                                .Where(x => x.ULTIMOESTADO.Contains("VISTO BUENO") || x.ULTIMOESTADO == "SOLICITADA")
                                .ToList();
                        }
                        else if (usuarioActual.Roll == "SUPERVISORDETODO")
                        {
                            asisYestados = context.V_ASISTENCIAS_EXTENDIDA
                                .Where(x => x.ULTIMOESTADO.Contains("PROPUESTA") ||
                                            x.ULTIMOESTADO == "SOLICITADA" ||
                                            x.ULTIMOESTADO.Contains("VISTO BUENO"))
                                .ToList();
                        }
                        else
                        {
                            asisYestados = context.V_ASISTENCIAS_EXTENDIDA
                                .Where(x => x.ULTIMOESTADO.Contains("PROPUESTA"))
                                .ToList();
                        }

                        var asisBorrador = context.V_ASISTENCIAS_EXTENDIDA
                            .Where(x => x.ULTIMOESTADO == "BORRADOR")
                            .ToList();

                        if (!string.IsNullOrEmpty(usuarioActual.Roll))
                        {
                            if (usuarioActual.Roll != "ADMINISTRADORCONTROLHORARIO")
                            {
                                // Para SUPERVISOR o DELEGADO se filtra por departamento
                                if (usuarioActual.Roll == "SUPERVISOR" || usuarioActual.Roll == "DELEGADO")
                                {
                                    asisYestados = asisYestados
                                        .Where(x => x.IDDEPARTAMENTO == persona.IDDEPARTAMENTO)
                                        .ToList();
                                }
                                usuarioActual.NumeroInciPorAceptar = asisYestados.Count;
                                usuarioActual.NumeroInciBorrador = asisBorrador
                                    .Where(x => x.IDPERSONA == usuarioActual.idPersona)
                                    .Count();

                                if (usuarioActual.NumeroInciPorAceptar > 0)
                                {
                                    usuarioActual.FeIniInciPorAceptar = (DateTime)asisYestados
                                        .OrderBy(x => x.FECHAOCURRENCIA)
                                        .First().FECHAOCURRENCIA;
                                    usuarioActual.FeFinInciPorAceptar = (DateTime)asisYestados
                                        .OrderBy(x => x.FECHAOCURRENCIA)
                                        .Last().FECHAOCURRENCIA;
                                }
                                if (usuarioActual.NumeroInciBorrador > 0)
                                {
                                    usuarioActual.FeIniInciBorrador = (DateTime)asisBorrador
                                        .Where(x => x.IDPERSONA == usuarioActual.idPersona)
                                        .OrderBy(x => x.FECHAOCURRENCIA)
                                        .First().FECHAOCURRENCIA;
                                    usuarioActual.FeFinInciBorrador = (DateTime)asisBorrador
                                        .Where(x => x.IDPERSONA == usuarioActual.idPersona)
                                        .OrderBy(x => x.FECHAOCURRENCIA)
                                        .Last().FECHAOCURRENCIA;
                                }
                            }
                            else // Caso ADMINISTRADORCONTROLHORARIO
                            {
                                asisYestados = context.V_ASISTENCIAS_EXTENDIDA
                                    .Where(x => x.ULTIMOESTADO == "VISTO BUENO")
                                    .ToList();
                                usuarioActual.NumeroInciPorAceptar = asisYestados.Count;
                                usuarioActual.NumeroInciBorrador = asisBorrador.Count;
                                if (usuarioActual.NumeroInciPorAceptar > 0)
                                {
                                    usuarioActual.FeIniInciPorAceptar = (DateTime)asisYestados
                                        .OrderBy(x => x.FECHAOCURRENCIA)
                                        .First().FECHAOCURRENCIA;
                                    usuarioActual.FeFinInciPorAceptar = (DateTime)asisYestados
                                        .OrderBy(x => x.FECHAOCURRENCIA)
                                        .Last().FECHAOCURRENCIA;
                                }
                                if (usuarioActual.NumeroInciBorrador > 0)
                                {
                                    usuarioActual.FeIniInciBorrador = (DateTime)asisBorrador
                                        .OrderBy(x => x.FECHAOCURRENCIA)
                                        .First().FECHAOCURRENCIA;
                                    usuarioActual.FeFinInciBorrador = (DateTime)asisBorrador
                                        .OrderBy(x => x.FECHAOCURRENCIA)
                                        .Last().FECHAOCURRENCIA;
                                }
                            }
                        }

                        // Cargar perfiles secundarios (subordinados)
                        if (!string.IsNullOrEmpty(usuarioActual.Roll))
                        {
                            var lpdep = context.PERSONAS
                                .Include(p => p.IDDEPARTAMENTONavigation)
                                .Where(x => x.IDDEPARTAMENTO != null && x.FECHABAJA == null)
                                .ToList();

                            if (usuarioActual.Roll == "SUPERVISOR" || usuarioActual.Roll == "DELEGADO")
                            {
                                lpdep = lpdep.Where(x => x.IDDEPARTAMENTO == persona.IDDEPARTAMENTO).ToList();
                            }

                            foreach (var perDep in lpdep.OrderBy(x => x.IDDEPARTAMENTO))
                            {
                                if (perDep.NIF.Trim().ToUpper() != nif.Trim().ToUpper() &&
                                    (
                                        (!perDep.SUPERVISORDEPARTAMENTO && (usuarioActual.Roll == "SUPERVISOR" || usuarioActual.Roll == "DELEGADO"))
                                        || (usuarioActual.Roll == "SUPERVISORDETODO")
                                    )
                                   )
                                {
                                    var subordinate = new Personal
                                    {
                                        Nombre = perDep.APELLIDOS + ", " + perDep.NOMBRE,
                                        Dni = perDep.NIF,
                                        idPersona = perDep.IDPERSONA,
                                        Departamento = perDep.IDDEPARTAMENTONavigation?.DESCRIPCION,
                                        Roll = string.Empty
                                    };
                                    if (perDep.DELEGADO)
                                        subordinate.Roll = "DELEGADO";
                                    if (string.IsNullOrEmpty(subordinate.Roll) && perDep.SUPERVISORDEPARTAMENTO)
                                        subordinate.Roll = "SUPERVISOR";
                                    subordinate.NumeroInciPorAceptar = asisYestados.Where(x => x.IDPERSONA == perDep.IDPERSONA).Count();
                                    subordinate.NumeroInciBorrador = asisBorrador.Where(x => x.IDPERSONA == perDep.IDPERSONA).Count();

                                    personas.Add(subordinate);
                                }
                            }

                            // Calcular fechas globales a partir de todos los perfiles (incluyendo el usuario consultante)
                            DateTime fechaNula = new DateTime(1, 1, 1);
                            if (personas.Any(x => x.FeIniInciPorAceptar > fechaNula))
                            {
                                resultadoIdentificacion.FeIniInciPorAceptar = personas
                                    .Where(x => x.FeIniInciPorAceptar > fechaNula)
                                    .OrderBy(x => x.FeIniInciPorAceptar)
                                    .First().FeIniInciPorAceptar;
                            }
                            if (personas.Any(x => x.FeFinInciPorAceptar > fechaNula))
                            {
                                resultadoIdentificacion.FeFinInciPorAceptar = personas
                                    .Where(x => x.FeFinInciPorAceptar > fechaNula)
                                    .OrderBy(x => x.FeFinInciPorAceptar)
                                    .Last().FeFinInciPorAceptar;
                            }
                        }
                    }
                    else // Caso "RPT"
                    {
                        if (origen == "RPT" && !persona.ADMINISTRARPTYREGISTRO)
                        {
                            resultadoIdentificacion.resultado = 1;
                            resultadoIdentificacion.errores = "Identificación correcta pero no es Administrador de Rpt y de Registro de Personal";
                            return Ok(resultadoIdentificacion);
                        }
                    }

                    resultadoIdentificacion.resultado = 0;
                    resultadoIdentificacion.errores = string.Empty;
                    return Ok(resultadoIdentificacion);
                }
            }
            catch (Exception ex)
            {
                resultadoIdentificacion.resultado = 3;
                resultadoIdentificacion.errores = ex.ToString();
                return Ok(resultadoIdentificacion);
            }
        }
    }
}
