package com.dacrt.SBIABackend.security.controler;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.Random;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpRequest;
import org.apache.http.client.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.data.jpa.repository.Query;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.dacrt.SBIABackend.security.dto.AccesoDto;
import com.dacrt.SBIABackend.security.dto.SessionDto;
import com.dacrt.SBIABackend.security.dto.ShortcutsDto;
import com.dacrt.SBIABackend.security.dto.UsersListDto;
import com.dacrt.SBIABackend.security.dto.UsersUnitDto;
import com.dacrt.SBIABackend.security.dto.AuditDtoMod;
import com.dacrt.SBIABackend.security.dto.ComprobadorAcceso;
//import com.dacrt.SBIABackend.security.dto.DetalleUsuarioRequestDto;
//import com.dacrt.SBIABackend.security.dto.DetalleUsuarioResponseDto;
import com.dacrt.SBIABackend.security.dto.JwtDto;
import com.dacrt.SBIABackend.security.dto.HashPwdDto;
import com.dacrt.SBIABackend.security.dto.LoginUsuario;
//import com.dacrt.SBIABackend.security.dto.MenuDto;
//import com.dacrt.SBIABackend.security.dto.UsuarioSesionRequestDto;
import com.dacrt.SBIABackend.security.dto.RolAccesoDto;
import com.dacrt.SBIABackend.security.entity.Roles;
import com.dacrt.SBIABackend.security.entity.Users;
import com.dacrt.SBIABackend.security.enums.RolNombre;
import com.dacrt.SBIABackend.security.jwt.JwtProvider;
//import com.dacrt.SBIABackend.security.repository.UsuarioRepository;
//import com.dacrt.SBIABackend.security.service.UsuarioService;
import com.dacrt.SBIABackend.security.service.UsersService;
import com.dacrt.SBIABackend.security.service.MenuService;
import com.dacrt.SBIABackend.security.service.SecurityService;
import com.dacrt.SBIABackend.utils.HttpReqRespUtils;
import com.dacrt.SBIABackend.dto.JsonoauthDto;
//import com.dacrt.SBIABackend.controler.ProcesoControler;
import com.dacrt.SBIABackend.dto.Mensaje;
import com.dacrt.SBIABackend.dto.SuppliersDtoStatus;
import com.dacrt.SBIABackend.dto.UnitsDto;
import com.dacrt.SBIABackend.dto.UnitsUsersDto;
import com.dacrt.SBIABackend.dto.oAuth2LoginDto;
import com.dacrt.SBIABackend.entity.Units;
import com.dacrt.SBIABackend.entity.Userunits;
import com.dacrt.SBIABackend.repository.UnitsRepository;
import com.dacrt.SBIABackend.repository.UserunitsRepository;
import com.dacrt.SBIABackend.security.dto.RespuestaDto;
import com.dacrt.SBIABackend.security.dto.RespuestaMsgDto;
import com.dacrt.SBIABackend.security.dto.RespuestaParamsDto;
import com.dacrt.SBIABackend.security.dto.RespuestaValidThruDto;
import com.dacrt.SBIABackend.security.dto.RespuestaValueDto;
import com.dacrt.SBIABackend.security.dto.AuditRequestDto;
import com.dacrt.SBIABackend.security.dto.MenuResponseDto;
import com.dacrt.SBIABackend.security.dto.ParamsDto;
import com.dacrt.SBIABackend.security.dto.ParamsResponseDto;
import com.dacrt.SBIABackend.security.dto.PrivilegesDto;
import com.dacrt.SBIABackend.security.dto.PwdcomplexityDto;
import com.dacrt.SBIABackend.security.dto.PwdoldnewDto;
import com.dacrt.SBIABackend.security.dto.AuditDto;
import com.dacrt.SBIABackend.security.dto.AuditResponseDto;
import com.dacrt.SBIABackend.security.dto.AuditModResponseDto;
import com.dacrt.SBIABackend.security.dto.AuditAllResponseDto;
import com.dacrt.SBIABackend.security.dto.AuditAllDto;
import com.dacrt.SBIABackend.security.entity.Access;
import com.dacrt.SBIABackend.security.entity.Audit;
import com.dacrt.SBIABackend.security.entity.Params;
import com.dacrt.SBIABackend.security.entity.Menu;
//import com.dacrt.SBIABackend.repository.ParametrosRepository;
import com.dacrt.SBIABackend.security.repository.UsersRepository;
import com.dacrt.SBIABackend.security.repository.ParamsRepository;
import com.dacrt.SBIABackend.security.repository.AuditRepository;
import com.dacrt.SBIABackend.security.repository.MenuRepository;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;


@RestController
@RequestMapping("/security")
//@CrossOrigin(origins = "http://vpskromasys2.hostnetcom.com:8081")
@CrossOrigin(origins = "*")
//@CrossOrigin(origins = "https://vpskromasys2.hostnetcom.com/~daconsult/dev")
//@CrossOrigin(origins = "*")


public class SecurityController {
	@Autowired
	PasswordEncoder passworEncoder;
	
	@Autowired
	AuthenticationManager autheticationManager;
	
	
	@Autowired
	UsersService usersService;
	
	@Autowired
	MenuService menuService;
	
	@Autowired
	SecurityService securityService;
	
	@Autowired
	AuditRepository auditRepository;
	
	@Autowired
	UsersRepository usersRepository;
	
	@Autowired
	ParamsRepository paramsRepository;
	
	@Autowired
	MenuRepository menuRepository;
	
	@Autowired
	UserunitsRepository userunitsRepository;
	
	@Autowired
	UnitsRepository unitsRepository;
	
	@PersistenceContext
    private EntityManager entityManager;
	
		
	@Autowired
	JwtProvider jwtProvider;
	
	@Autowired
    private JdbcTemplate jdbcTemplate;
	
	@Autowired
    private RestTemplate restTemplate;
	
	//@Value("$(var.ambiente)")
	@Value("${var.ambiente}")
	private String urlAmbiente;
	
	@Value("${spring.security.oauth2.client.registration.okta.client-id}")
	private String clientId;
	
	@Value("${spring.security.oauth2.client.registration.okta.redirect-uri}")
	private String redirect_uri;
	
	@Value("${app.oauth.scopes}")
	private String scope;
	
	@Value("${spring.security.oauth2.client.provider.okta.issuer-uri}")
	private String issuerUri;
	
	@Value("${app.oauth.v1.token}")
	private String vtoken;
	
	@Value("${spring.security.oauth2.client.registration.okta.client-secret}")
	private String clienteSec;
	
	@Value("${spring.security.oauth2.client.registration.okta.authorization-endpoint}")
	private String vauth;
	
	@Value("${app.oauth2.v1.userinfo}")
	private String vuserinfo;
	
	@Value("${direccionlocal}")
	private String dirlocal;
	
	
	Logger logger = LoggerFactory.getLogger(SecurityController.class);
	
	java.util.Date fechaActual = new java.util.Date();
	
	
	@GetMapping("/oAuth2/login")
	public String btenerUnoApplications(HttpServletRequest request,HttpServletResponse response) throws ParseException, IOException {
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		// HttpSession sessionuserid = request.getSession();
		 
		
         String var ="";
         String state = UUID.randomUUID().toString();
         HttpSession session = request.getSession();
         HttpSession sessionLogin = request.getSession();
         session.setAttribute("state", state);
         
      //   String sessionid = (String) session.getAttribute("sessionid");
         String sessionid2 = (String) sessionLogin.getAttribute("sessionidGl");
       //  String entrypoint = (String) session.getAttribute("entrypoint");
         String entrypoint2 = (String) sessionLogin.getAttribute("entrypointGl");
         //String validthru = (String) session.getAttribute("validthru");
         String validthru2 = (String) sessionLogin.getAttribute("validthruGl");
         String fullname2 = (String) sessionLogin.getAttribute("fullnameGl");
         Date validthruDate = (Date) sessionLogin.getAttribute("validtrhuDateGl");
        // sessionLogin.setAttribute("sessionidGl", sessionid);
         //sessionLogin.setAttribute("validthruGl", validthru);0
         //sessionLogin.setAttribute("entrypointGl", entrypoint);
         String redirectUrl;
         //String redirect_uri2 = "http://vpskromasys2.hostnetcom.com:8081/security/oAuth2/callback";
         
         
         if (session.getAttribute("iduser")!=null) {
        	
        	 // hacer una redireccion al acces con las variables de session del entry point session id y validthru
 			
 			String externalUrl = urlAmbiente + "content/access.php";
			  
 			if (sessionid2==null) {
 			     	redirectUrl = externalUrl +
 		                    "?sessionid=" + sessionid2 + 
 		                    "&entrypoint=" + entrypoint2 + 
 		                    "&fullname=" + fullname2 +
 		                    "&validthruDate=" + validthruDate +
 		                    "&validthru=" + validthru2;
 			} else {
 				      redirectUrl = externalUrl +
		                    "?sessionid=" + URLEncoder.encode(sessionid2, StandardCharsets.UTF_8.toString()) + 
		                    "&entrypoint=" + URLEncoder.encode(entrypoint2, StandardCharsets.UTF_8.toString()) + 
		                    "&fullname=" + URLEncoder.encode(fullname2, StandardCharsets.UTF_8.toString()) + 
		                    "&validthruDate=" + validthruDate +
		                    "&validthru=" + validthru2;    
 			}
			     // Usamos las variables que deben haber sido guardadas en la sesión en el callback
			  
        	
        	
        	System.out.print(redirectUrl);
        	// Usamos response.sendRedirect para evitar cambiar la firma del método
        	response.sendRedirect(redirectUrl);
 		} else {
 	         String url = issuerUri + vauth + "?response_type=code&client_id=" + clientId + "&redirect_uri=" + redirect_uri + "&state=" + state + "&scope=" + scope;
 	         String encoding2 = StandardCharsets.UTF_8.toString();
 			 String caracteresCodificados2 = URLEncoder.encode(url, encoding2);
 	         response.sendRedirect(url);
 		}
         
     

         return var; 	
   }
	
	//@GetMapping("/oAuth2/callback/{code}")
	@GetMapping("/oAuth2/callback")
	public ResponseEntity<String> btenercallback(HttpServletRequest request,@RequestParam("code") final String code,@RequestParam("state") final String state) throws Exception {
		//HttpStatus estatus = HttpStatus.FORBIDDEN;   
		
		 JsonoauthDto valorhttp; 
         String var = "Hola Mundo callback2";
         HttpSession session = request.getSession();
         HttpSession sessionLogin = request.getSession();
         String code2 = code;
         String stateRec = state;
         String error;     
         String state2 = session.getAttribute("state").toString();
         if (code==null) {
        	 error = "No se recibio el codigo de autorizacion ";
           	 
         }
         
        if (session.getAttribute("state").toString().compareTo(stateRec)==0) {
        	error = "estado valido";
        
        	// granttype
        	
        	String url = issuerUri + vtoken;
        	String urlinfo = issuerUri + vuserinfo;
        	String encoding2 = StandardCharsets.UTF_8.toString();
        	
           String params = "grant_type=" + "authorization_code&client_id=" + clientId + "&client_secret=" + clienteSec + "&redirect_uri=" + URLEncoder.encode(redirect_uri, encoding2) + "&code=" + code;
         //   String params =  "{\"grant_type\":" + "\"authorization_code\",\"client_id\":\"" + clientId + "\",\"client_secret\":\"" + clienteSec + "\",\"redirect_uri\":\"" + redirect_uri + "\",\"code\":\"" + code + "\"}";

            
   	    	 
        // Llamada al endpoint de okta token
        	String response = sendPostRequest(url, params);
        	error = response;
        	
        	ObjectMapper objectMapper = new ObjectMapper();
        	JsonNode rootNode = objectMapper.readTree(response);
            String accessToken = rootNode.path("access_token").asText();
            String id_token = rootNode.path("id_token").asText();
        
            // Llamada al endpoint de okta userinfo
            String responseInfo = sendRequest(urlinfo,accessToken);
            JsonNode rootNodeinfo = objectMapper.readTree(responseInfo);
            String iduser = rootNodeinfo.path("sub").asText();
            String nameuser= rootNodeinfo.path("name").asText();
            String emailuser = rootNodeinfo.path("email").asText();
            Optional<Users> optionalUsuario;
            boolean existeuser;
            existeuser = usersRepository.existsByEmail(emailuser);
            final String baseurl= dirlocal;
            if (existeuser) {
            	optionalUsuario = usersService.getByEmail(emailuser);
            	String pwd = "no";
            	// aqui deberia llamar el metodo actual de Login pasandole el Usernickname o correo y la clave
            	LoginUsuario loginUsuario = new LoginUsuario();
            	loginUsuario.setUsr(optionalUsuario.get().getUsr());
            	loginUsuario.setPwd(pwd);
            	loginUsuario.setTipo("oauth2");
            	
            	HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
                HttpEntity<LoginUsuario> requestEntity = new HttpEntity<>(loginUsuario, headers);
                String sessionid="";
                String validthru="";
                String entrypoint="";
                String fullname="";
                String fechabien="";
                Date validtrhuString;
                try {
                	// aqui invoco el metodo login con el request body de login usuario
                    ResponseEntity<JwtDto> loginResponse = restTemplate.exchange(
                    		baseurl + "/login",
                        HttpMethod.POST,
                        requestEntity,
                        JwtDto.class 
                    );
                    
                   
                    // tomando al respuesta del login
                    if (loginResponse.getStatusCode() == HttpStatus.OK) {
                        JwtDto jwtDto = loginResponse.getBody();
                         sessionid = jwtDto.getSessionid();
                         validthru = jwtDto.getValidthru().toString();
                         entrypoint= jwtDto.getEntrypoint();
                         fullname = jwtDto.getFullname();
                         Instant instant = jwtDto.getValidthru().toInstant();
                         ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
                         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
                         fechabien = zonedDateTime.format(formatter);
                         validtrhuString = jwtDto.getValidthru();
                         
                         sessionLogin.setAttribute("sessionidGl", sessionid);
                         sessionLogin.setAttribute("validthruGl", fechabien);
                         sessionLogin.setAttribute("entrypointGl", entrypoint);
                         sessionLogin.setAttribute("fullnameGl", fullname);
                         sessionLogin.setAttribute("validtrhuDateGl", validtrhuString);
                         
                        String externalUrl = urlAmbiente + "content/access.php";
                        String redirectUrl = externalUrl + 
                                "?sessionid=" + URLEncoder.encode(sessionid, StandardCharsets.UTF_8.toString()) + 
                                "&entrypoint=" + URLEncoder.encode(entrypoint, StandardCharsets.UTF_8.toString()) +
                                "&fullname=" + URLEncoder.encode(fullname, StandardCharsets.UTF_8.toString()) + 
                                "&validthru=" + fechabien ;
                    	session.setAttribute("iduser", iduser);
                    	session.setAttribute("nameuser", nameuser);
                    	session.setAttribute("emailuser", emailuser);
                    	session.setAttribute("accessToken", accessToken);
                    	// aqui debo retornar lo que indique Javier  llamo a nuevo endpoint access.php con Recibe estos 3 parámetros: "sessionid","entrypoint","validthru"
                    	System.out.print(redirectUrl);
                    	//return "redirect:" + redirectUrl;
                    	HttpHeaders headersResult = new HttpHeaders();
                        headers.add("Location", redirectUrl.substring("redirect:".length()));
                        return new ResponseEntity<>(headersResult, HttpStatus.FOUND); // HttpStatus.FOUND es 302
                    
                    } else {
                        // espero aqui indicacion de Ander  aqui debo devolver un error 400
                    	//String externalUrl = "http://vpskromasys2.hostnetcom.com/~daconsult/dev/content/access.php";
                       // String redirectUrl = externalUrl + "?sessionid=" + URLEncoder.encode(sessionid, StandardCharsets.UTF_8.toString()) + "&entrypoint=" + URLEncoder.encode("internal_fail", StandardCharsets.UTF_8.toString()) + "&validthru=" + URLEncoder.encode(validthru, StandardCharsets.UTF_8.toString());
                        
                        String externalUrl = urlAmbiente + "content/access.php";
                        String redirectUrl = externalUrl + 
                            // ... (Construcción de la URL de redirección) ...
                            "?sessionid=" + URLEncoder.encode(sessionid, StandardCharsets.UTF_8.toString()) + 
                            "&entrypoint=" + URLEncoder.encode("LOGIN_FAILED", StandardCharsets.UTF_8.toString()) + 
                            "&fullname=" + URLEncoder.encode(fullname, StandardCharsets.UTF_8.toString()) +
                           // "&validthruDate=" + validtrhuDate +
                            "&validthru=" + fechabien;
                        
                        // --- RETORNO DE ERROR DE LOGIN (302/redirect) ---
                        HttpHeaders headerserrorlogin = new HttpHeaders();
                        headers.add("Location", redirectUrl);
                        return new ResponseEntity<>(headerserrorlogin, HttpStatus.FOUND);
                    }

                } catch (Exception e) {
                	/*String externalUrl = "http://vpskromasys2.hostnetcom.com/~daconsult/dev/content/access.php";
                    String redirectUrl = externalUrl + "?sessionid=" + URLEncoder.encode(sessionid, StandardCharsets.UTF_8.toString()) + "&entrypoint=" + URLEncoder.encode("internal_fail", StandardCharsets.UTF_8.toString()) + "&validthru=" + URLEncoder.encode(validthru, StandardCharsets.UTF_8.toString());
                    
                    System.out.print(e);
                    return "redirect:" + redirectUrl;*/
                    System.out.println("Error en la llamada interna al /login: " + e.getMessage());
                    
                    return new ResponseEntity<>("Error de comunicación interna con el servicio de login. Acceso denegado.", HttpStatus.FORBIDDEN);
                }
                // esto solo lo seteamos si el login fue exitoso
            
            	
            	
            	// si el login no fue exitoso regreso un error 401
            	
            	
            } else {
            	   System.out.print(var);
            }
            
            // definimos las variables de session
    	
        	
        	
        } else
        {
        	error = "estado invalido";
        	
        	//reenviar al index
        }
         
     

        return new ResponseEntity<>("Enrrutado a Access exitosamente.", HttpStatus.OK);
   }
	
	
	public static String sendPostRequest(String urlString, String jsonBody ) throws Exception {
        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
       
        // 1. Configurar la conexión para POST
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        
       
        
        conn.setRequestProperty("Accept", "application/json");
        conn.setDoOutput(true); // Indica que vamos a enviar un cuerpo
        //byte[] input = jsonBody.getBytes("utf-8");
        //conn.setRequestProperty("Content-Length", String.valueOf(input.length));
        // 2. Enviar el cuerpo de la solicitud (los datos)
        try (OutputStream os = conn.getOutputStream()) {
            // Convertimos el JSON a bytes usando la codificación UTF-8
            byte[] input = jsonBody.getBytes("utf-8");
            os.write(input, 0, input.length);
            //os.write(input);
        }

        // 3. Leer la respuesta del servidor
        
        int responseCode = conn.getResponseCode();
        System.out.print(responseCode);
        System.out.print(urlString);
        System.out.print(jsonBody);
        if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED) {
            // Lectura si la respuesta es exitosa
            try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))) {
                StringBuilder response = new StringBuilder();
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                return response.toString();
            }
        } else {
            // Manejo de errores (puedes leer conn.getErrorStream() para más detalles)
            throw new RuntimeException("Fallo la petición POST. Código de estado: " + responseCode);
        }
    }
	
	public static String sendRequest(String urlString,String access_token ) throws Exception {
        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
       
        // 1. Configurar la conexión para POST
       // conn.setRequestMethod("POST");
        conn.setRequestProperty("Accept", "application/json");
        conn.setRequestProperty("Authorization", "Bearer " + access_token);
        
  
        
        conn.setDoOutput(true); // Indica que vamos a enviar un cuerpo
    
        
        int responseCode = conn.getResponseCode();
       
        if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED) {
            // Lectura si la respuesta es exitosa
            try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))) {
                StringBuilder response = new StringBuilder();
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                return response.toString();
            }
        } else {
            // Manejo de errores (puedes leer conn.getErrorStream() para más detalles)
            throw new RuntimeException("Fallo la petición POST. Código de estado: " + responseCode);
        }
    }
	
	
	@PostMapping("/login")
	public ResponseEntity<JwtDto> login(@Valid @RequestBody LoginUsuario loginUsuario,BindingResult bindingResult) throws ParseException {
		boolean sesionActiva=false;
		Date fecha = new Date();
		
		
		Optional<Users> optionalUsuario;
		String userLogin;
		if (bindingResult.hasErrors())
			return new ResponseEntity(new Mensaje("Campos mal puestos o Email inválido"),HttpStatus.BAD_REQUEST);
		//Optional<Users> optionalUsuario = usersService.getByUsr(loginUsuario.getUsuario());
		   optionalUsuario = usersService.getByUsr(loginUsuario.getUsr());
	       
		if (optionalUsuario.isPresent()) {
			sesionActiva=usersService.consultarSesionEstatus(optionalUsuario.get().getId()); 
			userLogin = optionalUsuario.get().getUsr();
			int activo = optionalUsuario.get().getStatus();
			
			///Validacion por eststus de usuario
			if (activo != 1 && activo != 3) {
				   String var = "Usuario Inactivo";
			         boolean bloked = true;
				     RespuestaDto respuestaDto=new RespuestaDto(var, bloked);
			         respuestaDto.setBlocked(bloked);
			         respuestaDto.setMsg(var);
				//throw new RuntimeException("Su usuario se encuentra inactivo");
			         return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			  } 
				
			
			
		} else {
			
			 optionalUsuario = usersService.getByEmail(loginUsuario.getUsr());
			
			 if (optionalUsuario.isPresent()) {
				 userLogin = optionalUsuario.get().getUsr();
					sesionActiva=usersService.consultarSesionEstatus(optionalUsuario.get().getId()); 
					
					int activo = optionalUsuario.get().getStatus();
					
					///Validacion por eststus de usuario
					if (activo != 1 && activo != 3) {
						   String var = "Usuario Inactivo";
					         boolean bloked = true;
						     RespuestaDto respuestaDto=new RespuestaDto(var, bloked);
					         respuestaDto.setBlocked(bloked);
					         respuestaDto.setMsg(var);
					         return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
					  } 
						
					
					
				} else {
			     String var = "Usuario/Clave Inválidos";
		         boolean bloked = false;
			     RespuestaDto respuestaDto=new RespuestaDto(var, bloked);
		         respuestaDto.setBlocked(bloked);
		         respuestaDto.setMsg(var);
		       
		         return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
				}
		}
	
		
		  try {
		//Authentication authentication=
			//	autheticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginUsuario.getUsuario(),loginUsuario.getPassword()));
		String jwt;
		UserDetails userDetails;
		UserDetails userDetails2;
		//authentication
		//Valido al Session Activa
	     
		 Date fecha2 = new Date();
		 Optional<Params> dePwdDuration=paramsRepository.findByParamname("PWD_DURATION");
		   String PasswordDuration=dePwdDuration.get().getValue();
		 
		   Optional<Params> deSessDuration=paramsRepository.findByParamname("SESSION_DURATION");
		   String SessionDuration=deSessDuration.get().getValue();
		   
		   
		   int duracionPass = Integer.parseInt(PasswordDuration);
		   int duracionSession = Integer.parseInt(SessionDuration);
		   //String var =  URLDecoder.decode(loginUsuario.getUsr(), StandardCharsets.UTF_8.toString());
			//  String encode = var;
		   //comentario de prueba
		          
		        if (loginUsuario.getTipo()==null) {
		    	    Authentication authentication=
			     	autheticationManager.authenticate(new UsernamePasswordAuthenticationToken(userLogin,loginUsuario.getPwd()));
		    	    
	              	SecurityContextHolder.getContext().setAuthentication(authentication);
		            jwt = jwtProvider.generateToken(authentication);
		            userDetails = (UserDetails)authentication.getPrincipal();
		        }  else {
		        	 jwt = jwtProvider.generateTokenoaauth(userLogin);
		        	 String tipologin = "login por el okta";
		        	 System.out.print(tipologin);
		        }      
		            
		           
		            
		            Calendar calendar = Calendar.getInstance();
		            calendar.setTime(fecha2); //tuFechaBase es un Date;
		            calendar.add(Calendar.MINUTE,   duracionSession); //horasASumar es int.
		            Date ValidThrufechaSalida = calendar.getTime(); //Y ya tienes la fecha sumada.
		            
		            
		            	  
		         
		
		///**********************Aqui valido la vigencia del password********************************************************///
		//Date fecha2 = new Date();
	    SimpleDateFormat  fechactual = new SimpleDateFormat("yyyy-MM-dd");
        String dataFormatfechactual = fechactual.format(fecha2);
  
        SimpleDateFormat Lastpwdchange = new SimpleDateFormat("yyyy-MM-dd");
        String dataFormatLastpwdchange = Lastpwdchange.format(optionalUsuario.get().getLastpwdchange());
        
        DateTimeFormatter formatternuevo = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        LocalDate fechaactual = LocalDate.parse(dataFormatfechactual, formatternuevo);
        LocalDate fechavalida = LocalDate.parse(dataFormatLastpwdchange, formatternuevo);
       
        long startTime = fecha2.getTime();
        long endTime = optionalUsuario.get().getLastpwdchange().getTime();
        long diasDesde = (long) Math.floor(startTime / (1000*60*60*24)); // convertimos a dias, para que no afecten cambios de hora 
        long diasHasta = (long) Math.floor(endTime / (1000*60*60*24)); // convertimos a dias, para que no afecten cambios de hora
        long dias = diasDesde - diasHasta;
        
        if (dias<0) {
        	
        	   boolean bloked = false;
        	   
			   Optional<Params> deMinLength=paramsRepository.findByParamname("PWD_MINLENGTH");
			   String minlongitud=deMinLength.get().getValue();
			   Optional<Params> deSimbolos=paramsRepository.findByParamname("PWD_SYMBOLS");
			   String cantSimbolos=deSimbolos.get().getValue();
			   Optional<Params> deCantMayus=paramsRepository.findByParamname("PWD_UPPERCASE");
			   String cantMayusculas=deCantMayus.get().getValue();
			   Optional<Params> deCantMinus=paramsRepository.findByParamname("PWD_LOWERCASE");
			   String cantMinusculas=deCantMinus.get().getValue();
			   Optional<Params> desimbolosPer=paramsRepository.findByParamname("PWD_ALLOWEDSYM");
			   String simbolospermi=desimbolosPer.get().getValue();
			   String encoding = StandardCharsets.UTF_8.toString();
			   String caracteresCodificados = URLEncoder.encode(simbolospermi, encoding);
			   //String ref = "www.duranyasociados.com";
			   String tokenurl = "=";
			   String token2url = "&";
			   String token3url = "|";
			   
			   // Authentication
			   //String ref="https://vpskromasys2.hostnetcom.com/~daconsult/dev/?sid='" + jwt + "'";
			  // String tokenurl = "&";
				String sid = "changepwd";
				String palabrahash = "hash";
				String palabraemail = "email";
				String conditions = "conditions";
				String hash = jwt;
				String idcampo = "?sid=";
				String ConcatAmbiente = urlAmbiente.concat(idcampo);
				String https = ConcatAmbiente;
				//String https="http://vpskromasys2.hostnetcom.com/~daconsult/dev/?sid=";
				
				
			    String url = https + sid + token2url + "hash" + tokenurl + jwt + token2url + palabraemail + tokenurl + optionalUsuario.get().getEmail() + token2url + conditions + tokenurl +
			    		deMinLength.get().getParamname() + minlongitud + "|" + deSimbolos.get().getParamname() + cantSimbolos + 
                "|" + deCantMayus.get().getParamname() + cantMayusculas + "|" + deCantMinus.get().getParamname() + cantMinusculas + "|" + desimbolosPer.get().getParamname() + caracteresCodificados;

			   
			  // String url = ref.concat(tokenurl).concat(jwt).concat(tokenurl).concat("LongitudMinina=").concat(minlongitud).concat(tokenurl).concat("CantidadSimbolos=").concat(cantSimbolos).concat(tokenurl).concat("CantidadMayusculas=").concat(cantMayusculas).concat(tokenurl).concat("CantidadMinusculas=").concat(cantMinusculas).concat(tokenurl).concat("SimbolosPermitidos=").concat(simbolospermi);
			   RespuestaDto respuestaDto=new RespuestaDto(url, bloked);
			   respuestaDto.setBlocked(bloked);
	           respuestaDto.setMsg(url);
	           int id= optionalUsuario.get().getId();
	           int idestatus= optionalUsuario.get().getStatus();
	           int fail=optionalUsuario.get().getFails();
	           usersService.asociarSessionidUsers(id,jwt,optionalUsuario.get().getLastsession(),fail,idestatus);
	           String module = "Seguridad";
	           String Descmodule = "Login exitoso Password no Vigente" ;
	           
	           AuditRequestDto  auditDto=new AuditRequestDto();
	           auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
	           SimpleDateFormat  formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	           String dataFormattata = formatter.format(fecha);
	           Date fechaDate = formatter.parse(dataFormattata);
	           
	           String singo1 = "(";
	           String singo2 = ")";
	           String usryemail = loginUsuario.getUsr().concat(" ").concat(singo1).concat(optionalUsuario.get().getEmail().concat(singo2));
	           auditDto.setUserref(usryemail);
	           auditDto.setModule(module);
	           auditDto.setDesc(Descmodule);
	           auditDto.setCreatedat(fechaDate);
	   		usersService.registrarAuditSesion(auditDto); 
			   
          return new ResponseEntity(respuestaDto, HttpStatus.OK);
        	
        }
        
        if (dias>duracionPass) {
            boolean bloked = false;
	         
			   Optional<Params> deMinLength=paramsRepository.findByParamname("PWD_MINLENGTH");
			   String minlongitud=deMinLength.get().getValue();
			   Optional<Params> deSimbolos=paramsRepository.findByParamname("PWD_SYMBOLS");
			   String cantSimbolos=deSimbolos.get().getValue();
			   Optional<Params> deCantMayus=paramsRepository.findByParamname("PWD_UPPERCASE");
			   String cantMayusculas=deCantMayus.get().getValue();
			   Optional<Params> deCantMinus=paramsRepository.findByParamname("PWD_LOWERCASE");
			   String cantMinusculas=deCantMinus.get().getValue();
			   Optional<Params> desimbolosPer=paramsRepository.findByParamname("PWD_ALLOWEDSYM");
			   String simbolospermi=desimbolosPer.get().getValue();
			   String encoding = StandardCharsets.UTF_8.toString();
				String caracteresCodificados = URLEncoder.encode(simbolospermi, encoding);
			   //String ref = "www.duranyasociados.com";
			   String tokenurl = "=";
			   String token2url = "&";
			   String token3url = "|";
			   
			   // Authentication
			   //String ref="https://vpskromasys2.hostnetcom.com/~daconsult/dev/?sid='" + jwt + "'";
			  // String tokenurl = "&";
				String sid = "changepwd";
				String palabrahash = "hash";
				String palabraemail = "email";
				String conditions = "conditions";
				String hash = jwt;
				String idcampo = "?sid=";
				String ConcatAmbiente = urlAmbiente.concat(idcampo);
				String https = ConcatAmbiente;
				//String https="http://vpskromasys2.hostnetcom.com/~daconsult/dev/?sid=";
				   String module = "Seguridad";
		           String Descmodule = "Login exitoso Password no Vigente" ;
		           
		           AuditRequestDto  auditDto=new AuditRequestDto();
		           auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
		           SimpleDateFormat  formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		           String dataFormattata = formatter.format(fecha);
		           Date fechaDate = formatter.parse(dataFormattata);
		           
		           String singo1 = "(";
		           String singo2 = ")";
		           String usryemail = loginUsuario.getUsr().concat(" ").concat(singo1).concat(optionalUsuario.get().getEmail().concat(singo2));
		           auditDto.setUserref(usryemail);
		           auditDto.setModule(module);
		           auditDto.setDesc(Descmodule);
		           auditDto.setCreatedat(fechaDate);
		   		usersService.registrarAuditSesion(auditDto); 
		   		
			    String url = https+ sid + token2url + palabrahash + tokenurl + jwt + token2url + palabraemail + tokenurl + optionalUsuario.get().getEmail() + token2url + conditions +
			    		tokenurl + deMinLength.get().getParamname() + ":%20" + minlongitud + "|" + deSimbolos.get().getParamname() + ":%20" + cantSimbolos + "|" + 
			    		deCantMayus.get().getParamname() + ":%20" + cantMayusculas + "|" + deCantMinus.get().getParamname() + ":%20" + cantMinusculas +
			    		"|" + desimbolosPer.get().getParamname() + ":%20" + caracteresCodificados;
 
			   
			  // String url = ref.concat(tokenurl).concat(jwt).concat(tokenurl).concat("LongitudMinina=").concat(minlongitud).concat(tokenurl).concat("CantidadSimbolos=").concat(cantSimbolos).concat(tokenurl).concat("CantidadMayusculas=").concat(cantMayusculas).concat(tokenurl).concat("CantidadMinusculas=").concat(cantMinusculas).concat(tokenurl).concat("SimbolosPermitidos=").concat(simbolospermi);
			   RespuestaDto respuestaDto=new RespuestaDto(url, bloked);
			   respuestaDto.setBlocked(bloked);
	           respuestaDto.setMsg(url);
	           int id= optionalUsuario.get().getId();
	           int idestatus= optionalUsuario.get().getStatus();
	           int fail=optionalUsuario.get().getFails();
	           usersService.asociarSessionidUsers(id,jwt,optionalUsuario.get().getLastsession(),fail,idestatus);
			   
          return new ResponseEntity(respuestaDto, HttpStatus.OK);
        }

        		
	    
        
         int fail = 0;
		 String entryDesc = optionalUsuario.get().getRolid().getEntrypoint();
		 
		 
	     JwtDto jwtDto = new JwtDto(jwt , optionalUsuario.get().getName(),ValidThrufechaSalida,entryDesc,ValidThrufechaSalida.toString());

        SimpleDateFormat  formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat  formatter2 = new SimpleDateFormat("HH:mm:ss");
        String dataFormattata = formatter.format(fecha);
        String dataFormattata2 = formatter2.format(fecha);
        Date fechaDate = formatter.parse(dataFormattata);
        Date horaI = formatter2.parse(dataFormattata2);
        int sesionActiva2=0;
        int id= optionalUsuario.get().getId();
        int idestatus= optionalUsuario.get().getStatus();
        usersService.asociarSessionidUsersValid(id,jwt,fechaDate,fail,idestatus,ValidThrufechaSalida);
     
        String module = "Seguridad";
        String Descmodule = "Login exitoso" ;
        
        AuditRequestDto  auditDto=new AuditRequestDto();
        auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
    
        
        String singo1 = "(";
        String singo2 = ")";
        String usryemail = loginUsuario.getUsr().concat(" ").concat(singo1).concat(optionalUsuario.get().getEmail().concat(singo2));
        auditDto.setUserref(usryemail);
        auditDto.setModule(module);
        auditDto.setDesc(Descmodule);
        auditDto.setCreatedat(fechaDate);
		usersService.registrarAuditSesion(auditDto); 
  		return new ResponseEntity(jwtDto, HttpStatus.OK);	
        
     
		 } catch (Exception e) {
		        // logger.error(null, e);
			 int maxIntentosMaster;
			 int IntentosFallidos = 0;
			  IntentosFallidos = optionalUsuario.get().getFails() + 1;
			   Optional<Params> deMaxIntentos=paramsRepository.findByParamname("PWD_MAXFAILS");
			   maxIntentosMaster=Integer.parseInt(deMaxIntentos.get().getValue());
			   
		        
			// Date fecha = new Date();
			 SimpleDateFormat  formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			 String dataFormattata = formatter.format(fecha);
			 Date fechaDate = formatter.parse(dataFormattata);
			  String module = "Seguridad";
		        //String Descmodule = "Modulo de Autorizacion de Acceso al Sistema -Login Error Usuario : ".concat(loginUsuario.getUsr()) ;
			    String Descmodule = "Login fallido";
		        String jwt = "";
		        int id= optionalUsuario.get().getId();
		        int fail = 0;
		        boolean bloked;
		        int idestatus;
		        if (IntentosFallidos>=maxIntentosMaster) {
		              	 idestatus= 0;
		              	// fechaDate=null;
		              	 bloked = true;
					   
				   } else {
					     idestatus= optionalUsuario.get().getStatus();
					      bloked = false;
					   
				   }
		        
		        
		        usersService.asociarSessionidUsers(id,jwt,optionalUsuario.get().getLastsession(),IntentosFallidos,idestatus);
		        
		        AuditRequestDto  auditDto=new AuditRequestDto();
		        auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
		    

		        auditDto.setUserref(loginUsuario.getUsr());
		        auditDto.setModule(module);
		        auditDto.setDesc(Descmodule);
		        auditDto.setCreatedat(fechaDate);
				usersService.registrarAuditSesion(auditDto); 
		         String var = e.getMessage();
		         
		         RespuestaDto respuestaDto=new RespuestaDto(var, bloked);
		         respuestaDto.setBlocked(bloked);
		         respuestaDto.setMsg("Usuario/Clave Inválidos");
		      
		         return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
        }
				
		
	
	}
	


    @PostMapping("/forgot")
	//public ResponseEntity<RespuestaDto> forgotemail(@PathVariable("email") String email) throws ParseException, IOException {
    public ResponseEntity<RespuestaDto> forgotemail(@RequestBody final Users email) throws ParseException, UnsupportedEncodingException {
		/* Verificar si el id del canal existe */
		if (!usersService.existsByEmail(email.getEmail())) {
			//usersService.getByUsr(loginUsuario.getUsr());
			logger.warn("No existe el id de la campaña solicitado: "+email);
			return new ResponseEntity(new Mensaje("No existe ningún usuario registrado con ese email: " + email.getEmail()), HttpStatus.UNAUTHORIZED);
		}
		
		
		//List<RespuestaDto> datosCampana= campanaService.datosCampana(idCampana);	
		Optional<Users> encontreSessionUsuario = usersRepository.findByEmail(email.getEmail());
		  Optional<Params> deMinLength=paramsRepository.findByParamname("PWD_MINLENGTH");
		   String minlongitud=deMinLength.get().getValue();
		   Optional<Params> deSimbolos=paramsRepository.findByParamname("PWD_SYMBOLS");
		   String cantSimbolos=deSimbolos.get().getValue();
		   Optional<Params> deCantMayus=paramsRepository.findByParamname("PWD_UPPERCASE");
		   String cantMayusculas=deCantMayus.get().getValue();
		   Optional<Params> deCantMinus=paramsRepository.findByParamname("PWD_LOWERCASE");
		   String cantMinusculas=deCantMinus.get().getValue();
		   Optional<Params> desimbolosPer=paramsRepository.findByParamname("PWD_ALLOWEDSYM");
		   String simbolospermi=desimbolosPer.get().getValue();
		  // String ref = "www.duranyasociados.com";
			RespuestaParamsDto respuesta= new RespuestaParamsDto("");
			
			HttpStatus estatus = HttpStatus.FORBIDDEN;
		   String tokenurl = "=";
		   String token2url = "&";
		   String token3url = "|";
		   
			String jwt = UUID.randomUUID().toString();
	     
			String sid = "changepwd";
			String palabrahash = "hash";
			String palabraemail = "email";
			String conditions = "conditions";
			String hash = jwt;
			String idcampo = "?sid=";
			String ConcatAmbiente = urlAmbiente.concat(idcampo);
			String https = ConcatAmbiente;
			String encoding = StandardCharsets.UTF_8.toString();
			String caracteresCodificados = URLEncoder.encode(simbolospermi, encoding);

			//String https="http://vpskromasys2.hostnetcom.com/~daconsult/dev/?sid=";
			
			
		 //   String url = https.concat(sid).concat(token2url).concat(palabrahash).concat(tokenurl).concat(jwt).concat(token2url).concat(palabraemail).concat(tokenurl).concat(email.getEmail()).concat(token2url).concat(conditions).concat(tokenurl).concat("Longitud%20Mínima:%20").concat(minlongitud).concat("|").concat("Cantidad%20Símbolos:%20").concat(cantSimbolos).concat("|").concat("Cantidad%20Mayúsculas:%20").concat(cantMayusculas).concat("|").concat("Cantidad%20Mínúsculas:%20").concat(cantMinusculas).concat("|").concat("Símbolos%20Permitidos:%20").concat(simbolospermi);
		    String url = https + sid + "&" + "hash" + "=" + jwt + "&" + "email" + "=" + email.getEmail() + "&" + "conditions" + "="
              + deMinLength.get().getParamname() + ":%20" + minlongitud +"|" + deSimbolos.get().getParamname() + ":%20" + cantSimbolos + "|" + deCantMayus.get().getParamname() + ":%20" + cantMayusculas + "|" +
                 deCantMinus.get().getParamname() + ":%20" + cantMinusculas + "|" + desimbolosPer.get().getParamname() + ":%20" + caracteresCodificados;

			
		    Date fecha = new Date();
		    SimpleDateFormat  formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	        SimpleDateFormat  formatter2 = new SimpleDateFormat("HH:mm:ss");
	        String dataFormattata = formatter.format(fecha);
	        String dataFormattata2 = formatter2.format(fecha);
	        Date fechaDate = formatter.parse(dataFormattata);
	        Date horaI = formatter2.parse(dataFormattata2);
		    //String ruta = "https://i.postimg.cc/Gt1rWjyY/imgemail.jpg";
	     
	        String idcampoLogo = "img/logo.png";
			String ConcatAmbienteLogo = urlAmbiente + (idcampoLogo);
			String ruta = ConcatAmbienteLogo;
			
	        //String ruta= "http://vpskromasys2.hostnetcom.com/~daconsult/dev/img/logo.png";
	       // 
	        ///String rutatotal = directorioImages.toFile().getAbsolutePath();
	         String saludo = " Para recuperar su clave por favor diríjase a la dirección indicada a continuación:";
	         String accion = "Recuperar";
	        // String htmlContent = "<html><body><img src='data:image/png;base64," + base64Image + "'></body></html>";
		    //////////////////////////
	         //String contenidocompleto = String.format(""+
	         String contenido  = usersService.ArmarBodySendMailUser(ruta,encontreSessionUsuario.get().getName(),saludo,url,accion,minlongitud,cantMayusculas,cantMinusculas,cantSimbolos,simbolospermi);
	     try {                                               	
		    int fail = 0;
		    String module = "Seguridad";
		    String Descmodule = "Envio de correo exitoso" ;
		     estatus = HttpStatus.FORBIDDEN;
		   
	      //  auditDto.setIdUsuario(optionalUsuario.get().getId());
	       // auditDto.setActivo(1);
	        String singo1 = "(";
	        String singo2 = ")";
	        String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1).concat(encontreSessionUsuario.get().getEmail().concat(singo2));
	       
			
			usersService.sendEmail(email.getEmail(), contenido , "Recuperación de Contraseña");
			usersService.asociarSessionidUsers(encontreSessionUsuario.get().getId(),jwt,encontreSessionUsuario.get().getLastsession(),fail,encontreSessionUsuario.get().getStatus());
			 AuditRequestDto  auditDto=new AuditRequestDto();
		        auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
			 auditDto.setUserref(usryemail);
		        auditDto.setModule(module);
		        auditDto.setDesc(Descmodule);
		        auditDto.setCreatedat(fechaDate);
			usersService.registrarAuditSesion(auditDto); 
			respuesta= new RespuestaParamsDto(contenido);
			estatus=HttpStatus.OK;
			
        } catch (Exception e) {
        	
        	System.out.println(e);
        
        }
			   
        return new ResponseEntity(respuesta,estatus);
		
		//return new ResponseEntity<>(datosCampana, HttpStatus.OK);
	}
	
		
	@PostMapping("/logout")
	public ResponseEntity<?> cerrarSesion(HttpServletRequest request,@RequestBody final SessionDto sessionid) throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		
		
		try {
						
			HttpSession session = request.getSession();
			if (session.getAttribute("iduser")!=null) {
				session.invalidate(); 
                HttpHeaders headers = new HttpHeaders();
                headers.add("Location", "/oAuth2/login");
                return new ResponseEntity<>(headers, HttpStatus.FOUND); // Código 302 Found
				
			}else {
		Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid.getSessionid());

			if (encontreSessionUsuario.isPresent()) {
				//Eliminar la sesión del usuario
				usersRepository.asociarSessionid(encontreSessionUsuario.get().getId(), "",null);
				SecurityContextHolder.clearContext();
				respuesta= new RespuestaDto("Sesión cerrada correctamente", false);
				estatus=HttpStatus.OK;
			}else {
				respuesta= new RespuestaDto("Sesión inválida", false);
				estatus=HttpStatus.UNAUTHORIZED;
			}
			}
						
		  
		}catch (Exception e) {
            // Manejo de excepciones
			respuesta= new RespuestaDto("Error interno del servidor", false);
			estatus=HttpStatus.INTERNAL_SERVER_ERROR;            
        }
		
		return new ResponseEntity(respuesta, estatus);
	}
	
	@PostMapping("/pwdchange")
	public ResponseEntity<RespuestaParamsDto> passwordChange(HttpServletRequest request,@RequestBody final PwdoldnewDto passoldnew) throws ParseException {
		//RespuestaDto respuesta = new RespuestaDto("", false);
		RespuestaParamsDto respuesta= new RespuestaParamsDto("");
		
		Set<Params> complexity = new HashSet<>();
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		String oldpasswd=""; //Almacena toda las contraseñas
		boolean existe=false; //permite conocer si existe la contraseña
		
		// String sessionid = request.getHeader("Authorization");
		// String sessionid = hashpwd.getHash();
		
		 String sessionid = request.getHeader("Authorization");
		 sessionid = sessionid.substring(7);
			if (sessionid==null) {
				respuesta= new RespuestaParamsDto("Session id es Null");
				estatus=HttpStatus.UNAUTHORIZED;
				return new ResponseEntity(respuesta, estatus);
				
			}
			
			Optional<Users> encontreSessionUsuariovalid = usersRepository.getBySessionid(sessionid);

			if (encontreSessionUsuariovalid.isPresent()) {
				//Eliminar la sesión del usuario
			   String r = "Session correcta";
			}else {
				respuesta= new RespuestaParamsDto("Sesión inválida");
				estatus=HttpStatus.UNAUTHORIZED;
				return new ResponseEntity(respuesta, estatus);
				
		   	}
	    
		
				
		try {
			
			//String passwodConvertidoOld=passworEncoder.encode(passoldnew.getOldpwd());
			
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			try {
				  Authentication authentication=
					     	autheticationManager.authenticate(new UsernamePasswordAuthenticationToken(encontreSessionUsuario.get().getUsr(),passoldnew.getOldpwd()));
			
			/*   RespuestaDto respuestaDto=new RespuestaDto(var, bloked);
		         respuestaDto.setBlocked(bloked);
		         respuestaDto.setMsg("Usuario/Clave Inválidos");
		      
		         return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			*/
		
			}  catch (Exception e) {
				respuesta= new RespuestaParamsDto("Usuario/Clave Inválidos");
				existe=true;
				estatus=HttpStatus.UNAUTHORIZED;
			
		         return new ResponseEntity(respuesta,estatus);   
	        }
				
				
						
			//extraer todos los parametros de validación de la contraseña
			//extraer todos los parametros de validación de la contraseña
		  	  Optional<Params> Minupper=paramsRepository.findByParamname("PWD_UPPERCASE");
		 		  String minupper=Minupper.get().getValue();
		 		  int longitudMayuscula = Integer.parseInt(Minupper.get().getValue());
		 		  Optional<Params> Minsymbols=paramsRepository.findByParamname("PWD_SYMBOLS");
		 		  String minsymbols=Minsymbols.get().getValue();
		 		 int longitudSimbolos = Integer.parseInt(Minsymbols.get().getValue());
		 		  Optional<Params> Minlower=paramsRepository.findByParamname("PWD_LOWERCASE");
		 		  String minlower=Minlower.get().getValue();
		 		 int longitudMinuscula = Integer.parseInt(Minlower.get().getValue());
		 		  Optional<Params> Minlengthn=paramsRepository.findByParamname("PWD_MINLENGTH");
		 		  String minlengthn=Minlengthn.get().getValue();
		 		  int longitudMinima = Integer.parseInt(Minlengthn.get().getValue());
		 		  Optional<Params> Allowedsimbols=paramsRepository.findByParamname("PWD_ALLOWEDSYM");
		 		  String allowedsimbols=Allowedsimbols.get().getValue();
			
			/*Params params = minima.get();
			complexity.add(params);
			
			params = mayuscula.get();
			complexity.add(params);
			
			params = minuscula.get();
			complexity.add(params);
			
			params = simbolos.get();
			complexity.add(params);*/
		 		  
		 			PwdcomplexityDto pwdcomplexityDto = new PwdcomplexityDto();
					RespuestaParamsDto respuesta2 = null;
				 		pwdcomplexityDto.setMinlength(minlengthn);
				 		
				 		pwdcomplexityDto.setMinupper(minupper);
				 		pwdcomplexityDto.setMinlower(minlower);
				 		pwdcomplexityDto.setMinsymbols(minsymbols);
				 		pwdcomplexityDto.setAllowedsimbols(allowedsimbols);
			
			
			//Verificar que la contraseña cumpla con los requerimientos/
			//Si es menor a la longitud minima
			String pwd= passoldnew.getNewpwd();
			//Contar mayusculas/
			int contadorMayusculas = 0;
	        for (char caracter : pwd.toCharArray()) {
	            if (Character.isUpperCase(caracter)) {
	            	contadorMayusculas++;
	            }
	        }
	        
	       //Contar mayusculas/
			int contadorMinusculas = 0;
	        for (char caracter : pwd.toCharArray()) {
	            if (Character.isLowerCase(caracter)) {
	            	contadorMinusculas++;
	            }
	        }
	        
	        //Contar simbolos/
	        int contadorSimbolos = 0;
	        ArrayList<Character> misCaracteres = new ArrayList<>();
	        for (char caracter : pwd.toCharArray()) {
	            if (!Character.isLetterOrDigit(caracter)) {
	            	misCaracteres.add(caracter);
	                contadorSimbolos++;
	            }
	        }
	        
	        boolean encontreSimboloErroneo= false;
	        for (char simbolo : misCaracteres) {
	        	if (!Character.isLetterOrDigit(simbolo)) {
	        		if (allowedsimbols.indexOf(simbolo)==-1) {
	        			encontreSimboloErroneo=true;
	        			break;
	        		}
	            }
	        }
        
	        //Validar contraseña
			if (passoldnew.getNewpwd().length()<longitudMinima 
				|| encontreSimboloErroneo 
				|| contadorSimbolos<longitudSimbolos 
				|| contadorMinusculas<longitudMinuscula
				|| contadorMayusculas<longitudMayuscula) {
				respuesta= new RespuestaParamsDto("Complejidad de la clave incorrecta");	
				//respuesta.setComplexity(complexity);
				respuesta.setComplexity(pwdcomplexityDto);
				estatus=HttpStatus.BAD_REQUEST;
			}else {
			
			//Obtengo la contraseña reconvertida
			String passwodConvertido=passworEncoder.encode(passoldnew.getNewpwd());
			
		
			

			String[] contrasenas = new String[5];
			boolean isMatch=false;
			int contadorLleno=0;
				if (encontreSessionUsuario.isPresent()) { // verifico si obtengo el session id
					if (encontreSessionUsuario.get().getOldpwds()==null){ //verifico si el campo que almacena las contraseñas tiene toda la información.
						oldpasswd=passwodConvertido; //coloco el nuevo password
					}else{
						//Obtengo un array completo de Contraseñas
						if (encontreSessionUsuario.get().getOldpwds().indexOf("||")!=-1) {
							contrasenas =encontreSessionUsuario.get().getOldpwds().split("\\|\\|");
						}else {
							contrasenas[0]=encontreSessionUsuario.get().getOldpwds();
						}
							
						//Verifico si la contraseña es igual a las últimas introducidas por el usuario
						for (String contra: contrasenas) {
							isMatch = passworEncoder.matches(pwd, contra);
							if (contra!=null && isMatch) {
								respuesta= new RespuestaParamsDto("La contraseña no puede ser igual a las registradas anteriormente");
								existe=true;
								estatus=HttpStatus.BAD_REQUEST;
								break;
							}
						}
							
						if (!existe) {	
							//verifica si esta lleno el arreglo
							for (String cont : contrasenas) {
					            if (cont != null && !cont.isEmpty()) {
					                contadorLleno++;
					            }
					        }
							
							//si el campo oldpasswd no esta vacio, verifico la cantidad de contraseñas que obtengo
							if (contadorLleno==5) {//si es igual a 5 entonces coloco el nuevo password
								oldpasswd=passwodConvertido;
							}else {
								oldpasswd=encontreSessionUsuario.get().getOldpwds()+"||"+passwodConvertido;
							}
						}
						
					}
					if (!existe) {
						AuditRequestDto auditDto = new AuditRequestDto();
						Date fecha = new Date();
						usersRepository.cambiarContrasenaSinSession(encontreSessionUsuario.get().getId(), passwodConvertido,oldpasswd,fecha);
						SecurityContextHolder.clearContext();
						auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
						String singo1 = "(";
				        String singo2 = ")";
				        String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1).concat(encontreSessionUsuario.get().getEmail().concat(singo2));
				        //auditDto.setUserref(usryemail);
						//Guardar en la tabla de auditoria
						Audit audit = new Audit(fecha,"Seguridad","Cambio de contraseña exitoso",auditDto.getIpaddr(),usryemail);
						auditRepository.save(audit);
						respuesta= new RespuestaParamsDto("Contraseña cambiada satisfactoriamente");
						estatus=HttpStatus.OK;
					}
					
				}else {
					AuditRequestDto auditDto = new AuditRequestDto();
					Date fecha = new Date();
					//usersRepository.cambiarContrasenaSinSession(encontreSessionUsuario.get().getId(), passwodConvertido,oldpasswd,fecha);
					SecurityContextHolder.clearContext();
					auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
					String singo1 = "(";
			        String singo2 = ")";
			        String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1).concat(encontreSessionUsuario.get().getEmail().concat(singo2));
			        //auditDto.setUserref(usryemail);
					//Guardar en la tabla de auditoria
					Audit audit = new Audit(fecha,"Seguridad","Cambio de contraseña fallido",auditDto.getIpaddr(),usryemail);
					auditRepository.save(audit);
					respuesta= new RespuestaParamsDto("Hash incorrecto");
					estatus=HttpStatus.UNAUTHORIZED;
				}
			}
		}catch (Exception e) {
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			AuditRequestDto auditDto = new AuditRequestDto();
			Date fecha = new Date();
			//usersRepository.cambiarContrasenaSinSession(encontreSessionUsuario.get().getId(), passwodConvertido,oldpasswd,fecha);
			SecurityContextHolder.clearContext();
			auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
			String singo1 = "(";
	        String singo2 = ")";
	        String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1).concat(encontreSessionUsuario.get().getEmail().concat(singo2));
	        //auditDto.setUserref(usryemail);
			//Guardar en la tabla de auditoria
			Audit audit = new Audit(fecha,"Seguridad","Cambio de contraseña fallido",auditDto.getIpaddr(),usryemail);
			auditRepository.save(audit);
            // Manejo de excepciones
			respuesta= new RespuestaParamsDto("Error interno del servidor");
			estatus=HttpStatus.INTERNAL_SERVER_ERROR;            
        }
		
		return new ResponseEntity(respuesta, estatus);
	}
	
	
	@PostMapping("/recover")
	public ResponseEntity<RespuestaParamsDto> cambiarContrasena(@RequestBody final HashPwdDto hashpwd) throws ParseException {
		//RespuestaDto respuesta = new RespuestaDto("", false);
		RespuestaParamsDto respuesta= new RespuestaParamsDto("");
		Set<Params> complexity = new HashSet<>();
		//Set<Params> complexity = new HashSet<>();
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		String oldpasswd=""; //Almacena toda las contraseñas
		boolean existe=false; //permite conocer si existe la contraseña
		
		// String sessionid = request.getHeader("Authorization");
		 String sessionid = hashpwd.getHash();
			if (sessionid==null) {
				respuesta= new RespuestaParamsDto("Session id es Null");
				estatus=HttpStatus.UNAUTHORIZED;
				return new ResponseEntity(respuesta, estatus);
				
			}
			
			Optional<Users> encontreSessionUsuariovalid = usersRepository.getBySessionid(sessionid);

			if (encontreSessionUsuariovalid.isPresent()) {
				//Eliminar la sesión del usuario
			   String r = "Session correcta";
			}else {
				respuesta= new RespuestaParamsDto("Sesión inválida");
				estatus=HttpStatus.UNAUTHORIZED;
				return new ResponseEntity(respuesta, estatus);
		   	}
	    
		
				
		try {
			
		
						
			//extraer todos los parametros de validación de la contraseña
		  	  Optional<Params> Minupper=paramsRepository.findByParamname("PWD_UPPERCASE");
		 		  String minupper=Minupper.get().getValue();
		 		  int longitudMayuscula = Integer.parseInt(Minupper.get().getValue());
		 		  Optional<Params> Minsymbols=paramsRepository.findByParamname("PWD_SYMBOLS");
		 		  String minsymbols=Minsymbols.get().getValue();
		 		 int longitudSimbolos = Integer.parseInt(Minsymbols.get().getValue());
		 		  Optional<Params> Minlower=paramsRepository.findByParamname("PWD_LOWERCASE");
		 		  String minlower=Minlower.get().getValue();
		 		 int longitudMinuscula = Integer.parseInt(Minlower.get().getValue());
		 		  Optional<Params> Minlengthn=paramsRepository.findByParamname("PWD_MINLENGTH");
		 		  String minlengthn=Minlengthn.get().getValue();
		 		  int longitudMinima = Integer.parseInt(Minlengthn.get().getValue());
		 		  Optional<Params> Allowedsimbols=paramsRepository.findByParamname("PWD_ALLOWEDSYM");
		 		  String allowedsimbols=Allowedsimbols.get().getValue();
		 	//	 String simbolosPermitidos = simbolos_permitidos.get().getValue();
			
	
			
			PwdcomplexityDto pwdcomplexityDto = new PwdcomplexityDto();
			RespuestaParamsDto respuesta2 = null;
		 		pwdcomplexityDto.setMinlength(minlengthn);
		 		
		 		pwdcomplexityDto.setMinupper(minupper);
		 		pwdcomplexityDto.setMinlower(minlower);
		 		pwdcomplexityDto.setMinsymbols(minsymbols);
		 		pwdcomplexityDto.setAllowedsimbols(allowedsimbols);
		 		
			
			
			//Verificar que la contraseña cumpla con los requerimientos/
			//Si es menor a la longitud minima
			String pwd= hashpwd.getPwd();
			//Contar mayusculas/
			int contadorMayusculas = 0;
	        for (char caracter : pwd.toCharArray()) {
	            if (Character.isUpperCase(caracter)) {
	            	contadorMayusculas++;
	            }
	        }
	        
	       //Contar mayusculas/
			int contadorMinusculas = 0;
	        for (char caracter : pwd.toCharArray()) {
	            if (Character.isLowerCase(caracter)) {
	            	contadorMinusculas++;
	            }
	        }
	        
	        //Contar simbolos/
	        int contadorSimbolos = 0;
	        ArrayList<Character> misCaracteres = new ArrayList<>();
	        for (char caracter : pwd.toCharArray()) {
	            if (!Character.isLetterOrDigit(caracter)) {
	            	misCaracteres.add(caracter);
	                contadorSimbolos++;
	            }
	        }
	        
	        boolean encontreSimboloErroneo= false;
	        for (char simbolo : misCaracteres) {
	        	if (!Character.isLetterOrDigit(simbolo)) {
	        		
	        		//if (simbolosPermitidos.indexOf(simbolo)==-1) {
	        		if (allowedsimbols.indexOf(simbolo)==-1) {
	        			encontreSimboloErroneo=true;
	        			break;
	        		}
	            }
	        }
        
	        //Validar contraseña
			if (hashpwd.getPwd().length()<longitudMinima 
				|| encontreSimboloErroneo 
				|| contadorSimbolos<longitudSimbolos 
				|| contadorMinusculas<longitudMinuscula
				|| contadorMayusculas<longitudMayuscula) {
				respuesta= new RespuestaParamsDto("Complejidad de la clave incorrecta");	
				//respuesta.setComplexity(complexity);
				respuesta.setComplexity(pwdcomplexityDto);
				estatus=HttpStatus.BAD_REQUEST;
			}else {
			
			//Obtengo la contraseña reconvertida
			String passwodConvertido=passworEncoder.encode(hashpwd.getPwd());
			
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(hashpwd.getHash());
			String[] contrasenas = new String[5];
			boolean isMatch=false;
			int contadorLleno=0;
				if (encontreSessionUsuario.isPresent()) { // verifico si obtengo el session id
					if (encontreSessionUsuario.get().getOldpwds()==null){ //verifico si el campo que almacena las contraseñas tiene toda la información.
						oldpasswd=passwodConvertido; //coloco el nuevo password
					}else{
						//Obtengo un array completo de Contraseñas
						if (encontreSessionUsuario.get().getOldpwds().indexOf("||")!=-1) {
							contrasenas =encontreSessionUsuario.get().getOldpwds().split("\\|\\|");
						}else {
							contrasenas[0]=encontreSessionUsuario.get().getOldpwds();
						}
							
						//Verifico si la contraseña es igual a las últimas introducidas por el usuario
						for (String contra: contrasenas) {
							isMatch = passworEncoder.matches(pwd, contra);
							if (contra!=null && isMatch) {
								respuesta= new RespuestaParamsDto("La contraseña no puede ser igual a las registradas anteriormente");
								existe=true;
								estatus=HttpStatus.BAD_REQUEST;
								break;
							}
						}
							
						if (!existe) {	
							//verifica si esta lleno el arreglo
							for (String cont : contrasenas) {
					            if (cont != null && !cont.isEmpty()) {
					                contadorLleno++;
					            }
					        }
							
							//si el campo oldpasswd no esta vacio, verifico la cantidad de contraseñas que obtengo
							if (contadorLleno==5) {//si es igual a 5 entonces coloco el nuevo password
								oldpasswd=passwodConvertido;
							}else {
								oldpasswd=encontreSessionUsuario.get().getOldpwds()+"||"+passwodConvertido;
							}
						}
						
					}
					if (!existe) {
						AuditRequestDto auditDto = new AuditRequestDto();
						Date fecha = new Date();
						usersRepository.cambiarContrasena(encontreSessionUsuario.get().getId(), passwodConvertido,oldpasswd,fecha);
						SecurityContextHolder.clearContext();
						auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
						String singo1 = "(";
				        String singo2 = ")";
				        String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1).concat(encontreSessionUsuario.get().getEmail().concat(singo2));
				        //auditDto.setUserref(usryemail);
						//Guardar en la tabla de auditoria
						Audit audit = new Audit(fecha,"Seguridad","Cambio de contraseña exitoso",auditDto.getIpaddr(),usryemail);
						auditRepository.save(audit);
						respuesta= new RespuestaParamsDto("Contraseña cambiada satisfactoriamente");
						estatus=HttpStatus.OK;
					}
					
				}else {
					
					AuditRequestDto auditDto = new AuditRequestDto();
					Date fecha = new Date();
					//usersRepository.cambiarContrasena(encontreSessionUsuario.get().getId(), passwodConvertido,oldpasswd,fecha);
					SecurityContextHolder.clearContext();
					auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
					String singo1 = "(";
			        String singo2 = ")";
			        String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1).concat(encontreSessionUsuario.get().getEmail().concat(singo2));
			        //auditDto.setUserref(usryemail);
					//Guardar en la tabla de auditoria
					Audit audit = new Audit(fecha,"Seguridad","Cambio de contraseña fallido",auditDto.getIpaddr(),usryemail);
					auditRepository.save(audit);
					respuesta= new RespuestaParamsDto("Hash incorrecto");
					estatus=HttpStatus.UNAUTHORIZED;
				}
			}
		}catch (Exception e) {
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(hashpwd.getHash());
			AuditRequestDto auditDto = new AuditRequestDto();
			Date fecha = new Date();
			//usersRepository.cambiarContrasena(encontreSessionUsuario.get().getId(), passwodConvertido,oldpasswd,fecha);
			SecurityContextHolder.clearContext();
			auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
			String singo1 = "(";
	        String singo2 = ")";
	        String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1).concat(encontreSessionUsuario.get().getEmail().concat(singo2));
	        //auditDto.setUserref(usryemail);
			//Guardar en la tabla de auditoria
			Audit audit = new Audit(fecha,"Seguridad","Cambio de contraseña fallido",auditDto.getIpaddr(),usryemail);
			auditRepository.save(audit);
            // Manejo de excepciones
			respuesta= new RespuestaParamsDto("Error interno del servidor");
			estatus=HttpStatus.INTERNAL_SERVER_ERROR;            
        }
		
		return new ResponseEntity(respuesta, estatus);
	}
	
	
	@PostMapping("/audit/users")
	public ResponseEntity<AuditResponseDto> usersaudit(HttpServletRequest request,@RequestBody UsersListDto tiposfiltros) throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		AuditResponseDto auditoriaDto = new AuditResponseDto();
		 AuditDto detalleAudit;
	     List<AuditDto> listasAudit = new ArrayList<>();
	     
		 String sessionid = request.getHeader("Authorization");
		  Date fecha = new Date();
		    SimpleDateFormat  formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		    Long cuantosregistro = (long) 0;
	        String dataFormattata = formatter.format(fecha);
	        Date fechaDate = formatter.parse(dataFormattata);
	        AuditRequestDto  auditDto=new AuditRequestDto();
	   	 String searchIn = "";
	   	 String contentIn = "";
		 int orderIn = 0;
		 int offsetIn = 0;
		 int numofrecordsIn = 0;
		 String fechaComoCadena;
		 Optional<Params> deSessDuration=paramsRepository.findByParamname("SESSION_DURATION");
		 String SessionDuration=deSessDuration.get().getValue();
		 int duracionSession = Integer.parseInt(SessionDuration);
		 Date fecha2 = new Date();
		   Calendar calendar = Calendar.getInstance();
         calendar.setTime(fecha2); //tuFechaBase es un Date;
         //calendar.add(Calendar.MINUTE, minutosASumar); minutosASumar es int.
         
        calendar.add(Calendar.MINUTE,duracionSession); //horasASumar es int.
          //lo que más quieras sumar
         Date ValidThrufechaSalida = calendar.getTime();// Y ya tienes la fecha sumada.
         SimpleDateFormat salida = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //2024-12-23 23:00
        // String fechaComoCadena = salida.format(ValidThrufechaSalida);
        // System.out.println(fechaComoCadena);
	
		 
			if (sessionid==null) {
				String var = "";
				boolean bloked = false;
				RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
				respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Sesión expirada o inválida");
				//Error 400
				return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
			} else   {
				 
				   sessionid = sessionid.substring(7);
				   Optional<Users> encontreSessionUsuario =usersRepository.getBySessionid(sessionid);
				 
				   if (encontreSessionUsuario.isPresent()) {
					   
					   Date FechaReg = encontreSessionUsuario.get().getValidthru(); 
					   //Llamada a la funcion que validad el tiempo de Session, retorna la fecha sumandole el tiempo de session activa, y vacio si no esta activa
					   
					    fechaComoCadena  = securityService.consultarSessionActiva(FechaReg,fecha2,encontreSessionUsuario.get().getId());
					   
					    if (fechaComoCadena=="") {
						   
						   
						   
						   String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("Sesión expirada o inválida"); 
							return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
						   
					    }
					   //Este servicio obtiene una lista de los usuarios registrados en la auditoría en el campo "userref". (priv 600)

					   Roles roles = encontreSessionUsuario.get().getRolid();
					   int idrol = roles.getId();
					   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 600);
					   
					   if (rolisvalid==0) {
						   
						   String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("No tiene los Privilegios"); 
							return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
							
					   }
						  //searchIn = tiposfiltros.getFilters().getSearch();
						  searchIn = tiposfiltros.getFilters().getSearch();
						  
						    String Salida = usersService.verificarCaracteresValidosConRegex(searchIn);
							  
							  if (Salida=="NOOK") {
								  String var = "";
									boolean bloked = false;
									RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
									//respuestaDto.setBlocked(bloked);
									respuestaDto.setMsg("Caracteres no permitidos en la busqueda"); 
									return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
							  }
							  
						  searchIn = usersService.eliminarAcentosService(tiposfiltros.getFilters().getSearch());   
						  orderIn = tiposfiltros.getOrder();
						  offsetIn = tiposfiltros.getOffset();
						  numofrecordsIn = tiposfiltros.getNumofrecords();
						  
						  contentIn = tiposfiltros.getContent();
						  if (contentIn !=null) {
						  menuService.iscontentdiffnull(contentIn, encontreSessionUsuario.get().getId());
						  }
					   					
					
				 } else {
						String var = "";
						boolean bloked = false;
						RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
						respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Sesión expirada o inválida");
						//Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
				 }
			}
		 
		
		try {
			
			
			
			//Se setean algunas palabras claves del Manejador de BD
			/*comienzo del comentario*/  
		
			String SentenciaBase = "SELECT DISTINCT new com.dacrt.SBIABackend.security.dto.AuditDto  (u.userref) FROM Audit u";		

			String QueryTotal = "";
			String useref = "u.userref";
			String group = "u.userref,u.id";
			String LowerSearch = searchIn.toLowerCase();
			String loweruseref = " main.sinacentos(LOWER(u.userref))";
			//String lowerdsc = "main.sinacentos(LOWER(ed.dsc))";
		
			 switch (searchIn) { 
			    case "":  // viene sin busqueda por el like
			    	QueryTotal = SentenciaBase + " GROUP BY " + group;
			     break;
			  
			    default:	// viene con el parametro para buscar por el like		   			    				    	
			    	QueryTotal = SentenciaBase  + " WHERE " + loweruseref +" LIKE " + "'%" + LowerSearch + "%'";
			    	
	         }
			 
			 TypedQuery<AuditDto> paramsCount= entityManager.createQuery(QueryTotal, AuditDto.class);
			 cuantosregistro = (long) paramsCount.getResultList().size();
		
			 
			 switch (orderIn) { 
			    case 1:  //ordena por group y name ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + useref + " ASC";
			     break;
			    case -1://ordena por group y name descendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + useref + " DESC";
			     break;
			    default:
			    	String var2 = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
					respuestaDto= new RespuestaMsgDto("Error interno del servidor");
					estatus=HttpStatus.INTERNAL_SERVER_ERROR;   
					return new ResponseEntity(respuestaDto, estatus);
			     // Default secuencia de sentencias.
			   }
			 
			 //Se mapea la entidad se le pasa el query y lo bota como un tipo de objeto AuditDto-Buscar en los DTO 
			     TypedQuery<AuditDto> params= entityManager.createQuery(QueryTotal, AuditDto.class);
			      params.setFirstResult(offsetIn);
			      params.setMaxResults(numofrecordsIn);
			      List<AuditDto> listacompleta = params.getResultList();
			
		    	
		    	  	//Se le pasa el listado al DTO RESPONSE que contiene la estructura de Salida solicitada
		    	  	auditoriaDto.setNumofrecords(cuantosregistro);
		    	  	auditoriaDto.setSessionvalidthru(fechaComoCadena);		           
		    	  	auditoriaDto.setRecords(listacompleta);
																				
				    return ResponseEntity.ok(auditoriaDto);																					
       
		} catch (Exception e) {
            // Manejo de excepciones
			respuesta= new RespuestaDto("Error interno del servidor", false);
			estatus=HttpStatus.INTERNAL_SERVER_ERROR;            
        }finally {
	        if (entityManager != null && entityManager.isOpen()) {
	            entityManager.close();
	        }
        }
		
		return new ResponseEntity(respuesta, estatus);
	
	}
	
	
	@PostMapping("/audit/modules")
	public ResponseEntity<AuditModResponseDto> modulesaudit(HttpServletRequest request,@RequestBody UsersListDto tiposfiltros) throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		AuditModResponseDto auditoriaModDto = new AuditModResponseDto();
		AuditDtoMod detalleAudit;
	     List<AuditDtoMod> listasAudit = new ArrayList<>();
		 
		 String sessionid = request.getHeader("Authorization");
		  Date fecha = new Date();
		  Long cuantosregistro = (long) 0;
		  
		    SimpleDateFormat  formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	        String dataFormattata = formatter.format(fecha);
	        Date fechaDate = formatter.parse(dataFormattata);
	        AuditRequestDto  auditDto=new AuditRequestDto()
	        		;
	   	 String searchIn = "";
	   	 String contentIn = "";
		 int orderIn = 0;
		 int offsetIn = 0;
		 int numofrecordsIn = 0;
		 
		 //Se calcula el validtrhu de la session trayendo de la BD el parametro session duration
		 Optional<Params> deSessDuration=paramsRepository.findByParamname("SESSION_DURATION");
		 String SessionDuration=deSessDuration.get().getValue();
		 int duracionSession = Integer.parseInt(SessionDuration);
		 Date fecha2 = new Date();
		   Calendar calendar = Calendar.getInstance();
         calendar.setTime(fecha2); //tuFechaBase es un Date;
         String fechaComoCadena;
     
	
		 //Valida la nulidad de la session
			if (sessionid==null) {
				String var = "";
				boolean bloked = false;
				RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
				respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Sesión expirada o inválida");
				//Error 400
				return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
			} else   {
				 
				   sessionid = sessionid.substring(7);
				   Optional<Users> encontreSessionUsuario =usersRepository.getBySessionid(sessionid);
				//   String usuarioIN = encontreSessionUsuario.get().getUsr();
				 //  int position = usuarioIN.indexOf('('); 
				   // Validacion de la existencia del usuario que hizo la peticion del servicio Jackson Rivero
				   if (encontreSessionUsuario.isPresent()) {
					   Date FechaReg = encontreSessionUsuario.get().getValidthru(); 
					   //Llamada a la funcion que validad el tiempo de Session, retorna la fecha sumandole el tiempo de session activa, y vacio si no esta activa
					   
					    //fechaComoCadena  = securityService.consultarSessionActiva(FechaReg,fecha2);
					    fechaComoCadena  = securityService.consultarSessionActiva(FechaReg,fecha2,encontreSessionUsuario.get().getId());
					   
					    if (fechaComoCadena=="") {
						   
						   
						   
						   String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("Sesión expirada o inválida"); 
							return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
						   
					    }
                     // Este servicio obtiene una lista de los módulos registrados en la auditoría. (priv 600)

					   Roles roles = encontreSessionUsuario.get().getRolid();
					   int idrol = roles.getId();
					   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 600);
					   
					   if (rolisvalid==0) {
						   
						   String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("No tiene los Privilegios"); 
							return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
							
					   }
						 // searchIn = tiposfiltros.getFilters().getSearch();
						  
						  
						  searchIn = tiposfiltros.getFilters().getSearch();
						  
						    String Salida = usersService.verificarCaracteresValidosConRegex(searchIn);
							  
							  if (Salida=="NOOK") {
								  String var = "";
									boolean bloked = false;
									RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
									//respuestaDto.setBlocked(bloked);
									respuestaDto.setMsg("Caracteres no permitidos en la busqueda"); 
									return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
							  }
							  
					      searchIn = usersService.eliminarAcentosService(tiposfiltros.getFilters().getSearch());  
						  orderIn = tiposfiltros.getOrder();
						  offsetIn = tiposfiltros.getOffset();
						  numofrecordsIn = tiposfiltros.getNumofrecords();
						  
						  contentIn = tiposfiltros.getContent();
						  if (contentIn !=null) {
						  menuService.iscontentdiffnull(contentIn, encontreSessionUsuario.get().getId());
						  }						 						
										
				 } else {
						String var = "";
						boolean bloked = false;
						RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
						respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Sesión expirada o inválida");
						//Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
				 }
			}
		 
		
		try {
			
		

			String SentenciaBase = "SELECT DISTINCT new com.dacrt.SBIABackend.security.dto.AuditDtoMod (u.module) FROM Audit u";		

			String QueryTotal = "";
			String module = "u.module";
			String group = "u.module,u.id";
			String lowermodule= " main.sinacentos(LOWER(u.module))";
			String LowerSearch = searchIn.toLowerCase();
		
			 switch (searchIn) { 
			    case "":  // viene sin busqueda por el like
			    	QueryTotal = SentenciaBase + " GROUP BY " + group;
			     break;
			  
			    default:	// viene con el parametro para buscar por el like		   			    				    	
			    	QueryTotal = SentenciaBase  + " WHERE " + lowermodule + " LIKE " + "'%" + LowerSearch + "%'";
			    	
	         }
			 
			 TypedQuery<AuditDtoMod> paramsCount= entityManager.createQuery(QueryTotal, AuditDtoMod.class);
			 cuantosregistro = (long) paramsCount.getResultList().size();
		
			 
			 switch (orderIn) { 
			    case 1:  //ordena por group y name ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + module + " ASC";
			     break;
			    case -1://ordena por group y name descendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + module + " DESC";
			     break;
			    default:
			    	String var2 = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
					respuestaDto= new RespuestaMsgDto("Error interno del servidor");
					estatus=HttpStatus.INTERNAL_SERVER_ERROR;   
					return new ResponseEntity(respuestaDto, estatus);
			     // Default secuencia de sentencias.
			   }
			 
			 //Se mapea la entidad se le pasa el query y lo bota como un tipo de objeto AuditDto-Buscar en los DTO 
			     TypedQuery<AuditDtoMod> params= entityManager.createQuery(QueryTotal, AuditDtoMod.class);
			      params.setFirstResult(offsetIn);
			      params.setMaxResults(numofrecordsIn);
			      List<AuditDtoMod> listacompleta = params.getResultList();
			
		    	
		    	  	//Se le pasa el listado al DTO RESPONSE que contiene la estructura de Salida solicitada
			      auditoriaModDto.setNumofrecords(cuantosregistro);
			      auditoriaModDto.setSessionvalidthru(fechaComoCadena);		           
			      auditoriaModDto.setRecords(listacompleta);
											
			      return ResponseEntity.ok(auditoriaModDto);		     
						
       
		}catch (Exception e) {
            // Manejo de excepciones
			respuesta= new RespuestaDto("Error interno del servidor", false);
			estatus=HttpStatus.INTERNAL_SERVER_ERROR;            
        }finally {
	        if (entityManager != null && entityManager.isOpen()) {
	            entityManager.close();
	        }
        }
		
		return new ResponseEntity(respuesta, estatus);
	
	}
	
	
	@PostMapping("/audit")
	public ResponseEntity<AuditAllResponseDto> audit(HttpServletRequest request,@RequestBody UsersListDto tiposfiltros) throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		AuditAllResponseDto auditoriaModDto = new AuditAllResponseDto();
		AuditAllDto detalleAudit;
	    List<AuditAllDto> listasAudit = new ArrayList<>();
	    Long cuantosregistro = (long) 0;
		 
		 String sessionid = request.getHeader("Authorization");
		  Date fecha = new Date();
		    SimpleDateFormat  formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	        String dataFormattata = formatter.format(fecha);
	        Date fechaDate = formatter.parse(dataFormattata);
	        AuditRequestDto  auditDto=new AuditRequestDto();
	        String searchStringfrom = tiposfiltros.getFilters().getDatefrom();
	        String searchStringto = tiposfiltros.getFilters().getDateto();
	       
	        String sinfecha="NO";
	        String sinfechaFrom="NO";
	        String sinfechaTo="NO";
	    
	        
	        
	   	  String searchIn = "";
	      String searchModule = "";
		  String searchUsr = "";
		  String contentIn = "";
		  //Date searchDatefrom;
		 // Date searchDateto;
		  String fechaComoCadena;
		 int orderIn = 0;
		 int offsetIn = 0;
		 int numofrecordsIn = 0;
		 Optional<Params> deSessDuration=paramsRepository.findByParamname("SESSION_DURATION");
		 String SessionDuration=deSessDuration.get().getValue();
		 int duracionSession = Integer.parseInt(SessionDuration);
		 Date fecha2 = new Date();
		 
		 
			if (sessionid==null) {
				String var = "";
				boolean bloked = false;
				RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
				respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Sesión expirada o inválida");
				//Error 400
				return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
			} else   {
				 
				   sessionid = sessionid.substring(7);
				   Optional<Users> encontreSessionUsuario =usersRepository.getBySessionid(sessionid);
				
				   
				   if (encontreSessionUsuario.isPresent()) {
					   Date FechaReg = encontreSessionUsuario.get().getValidthru(); 
					   //Llamada a la funcion que validad el tiempo de Session, retorna la fecha sumandole el tiempo de session activa, y vacio si no esta activa
					   
					    fechaComoCadena  = securityService.consultarSessionActiva(FechaReg,fecha2,encontreSessionUsuario.get().getId());
					   
					    if (fechaComoCadena=="") {
						   						   						   
						   String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("Sesión expirada o inválida"); 
							return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
						   
					    }
					   
					   // Este servicio obtiene una lista de los módulos registrados en la auditoría. (priv 600)

					   Roles roles = encontreSessionUsuario.get().getRolid();
					   int idrol = roles.getId();
					   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 600);
					   
					   if (rolisvalid==0) {
						   
						   String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("No tiene los Privilegios"); 
							return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
							
					   }
						 
						  
						  searchIn = tiposfiltros.getFilters().getSearch();
						  
						    String Salida = usersService.verificarCaracteresValidosConRegex(searchIn);
							  
							  if (Salida=="NOOK") {
								  String var = "";
									boolean bloked = false;
									RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
									//respuestaDto.setBlocked(bloked);
									respuestaDto.setMsg("Caracteres no permitidos en la busqueda"); 
									return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
							  }
							  
						  searchIn = usersService.eliminarAcentosService(tiposfiltros.getFilters().getSearch());  
						  searchModule = usersService.eliminarAcentosService(tiposfiltros.getFilters().getModule());
						  searchUsr = usersService.eliminarAcentosService(tiposfiltros.getFilters().getUser());
					
						  orderIn = tiposfiltros.getOrder();
						  offsetIn = tiposfiltros.getOffset();
						  numofrecordsIn = tiposfiltros.getNumofrecords();
						  
						  contentIn = tiposfiltros.getContent();
						  if (contentIn !=null) {
						  menuService.iscontentdiffnull(contentIn, encontreSessionUsuario.get().getId());
						  }
						  						
					
				 } else {
						String var = "";
						boolean bloked = false;
						RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
						respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Sesión expirada o inválida");
						//Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
				 }
			}
			
			
		
		try {
			
			
        //  SELECT * FROM main.audit a WHERE a.userref ILIKE ?4 AND a.module ILIKE ?3 AND a.createdat < ?5 ORDER BY a.createdat ASC LIMIT ?1 OFFSET ?2

			String SentenciaBase = "SELECT new com.dacrt.SBIABackend.security.dto.AuditAllDto (u.module,TO_CHAR(u.createdat, 'yyyy-mm-dd HH24:MI'),u.dsc,u.userref,u.ipaddr) FROM Audit u";
			
			String QueryTotal = "";
			String userref = "u.userref";
			String module = "u.module";
			String dsc = "u.dsc";
			String createdat = "u.createdat";
			String group = "u.module,u.id";
			String lowermodule= " main.sinacentos(LOWER(u.module))";
			String loweruserref= " main.sinacentos(LOWER(u.userref))";
			String lowerdsc= " main.sinacentos(LOWER(u.dsc))";
			String LowerSearch = searchIn.toLowerCase();
			
			 
			 switch (searchIn) { 
			    case "":  // viene sin busqueda por el like
			    	//QueryTotal = SentenciaBase  + " WHERE " + lowerdsc + " LIKE " + "'%" + "" + "%'";
			    	QueryTotal = SentenciaBase  + " WHERE " + "TRUE = TRUE ";
			     break;
			  
			    default:	// viene con el parametro para buscar por el like		   			    				    	
			    	QueryTotal = SentenciaBase  + " WHERE " + lowerdsc + " LIKE " + "'%" + LowerSearch + "%'" + " OR u.ipaddr LIKE " + "'%" + LowerSearch + "%'";
			    	
	         }
			 
			 switch (searchModule) { 
			    case "":  // viene sin busqueda por el like
			    	QueryTotal = QueryTotal;
			     break;
			  
			    default:	// viene con el parametro para buscar por el like		   			    				    	
			    	QueryTotal = QueryTotal  + " AND " + lowermodule + " LIKE " + "'%" + searchModule.toLowerCase() + "%'";
			    	
	         }
			 
			 switch (searchUsr) { 
			    case "":  // viene sin busqueda por el like
			    	QueryTotal = QueryTotal;
			     break;
			  
			    default:	// viene con el parametro para buscar por el like		   			    				    	
			    	QueryTotal = QueryTotal  + " AND " + loweruserref + " LIKE " + "'%" + searchUsr.toLowerCase() + "%'";
			    	
	         }
			 
			 Date searchDatefrom = new Date();
			 Date searchDateto= new Date();
			    
		        if (searchStringfrom==""  || searchStringto=="") {
		        	 if (searchStringfrom=="") {
		        		 
		        		 QueryTotal = QueryTotal;
		        	 } else {
		        		 QueryTotal = QueryTotal  + " AND " + "u.createdat > " + "'" + searchStringfrom + "'" ;
		        		 
		        	 }
		        		 
	                 if (searchStringto=="") {
	                	 QueryTotal = QueryTotal;
		        	 } else {
		        		 QueryTotal = QueryTotal  + " AND " + "u.createdat < " + "'" + searchStringto + "'" ;
		        	 }
		        	 
		        	 
		        } else {
		        	// AND a.module ILIKE ?3 AND a.createdat BETWEEN ?5 AND ?6 
		        	QueryTotal = QueryTotal  + " AND " + "u.createdat BETWEEN " + "'" +searchStringfrom + "'" + " AND " + "'" + searchStringto + "'";
		        	 searchDatefrom = formatter.parse(searchStringfrom);
			         searchDateto = formatter.parse(searchStringto);
			         
		        }
			 
			 TypedQuery<AuditAllDto> auditCount= entityManager.createQuery(QueryTotal, AuditAllDto.class);
			 cuantosregistro = (long) auditCount.getResultList().size();
			 
			  String ordena="";
			  if (orderIn == 1 || orderIn == 2 || orderIn == 3) {
				  ordena = " ASC";
			 }  else if (orderIn == -1 || orderIn == -2 || orderIn == -3) {
				  ordena = " DESC";
			 } else {
				 	String var2 = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
					respuestaDto= new RespuestaMsgDto("Error interno del servidor");
					estatus=HttpStatus.INTERNAL_SERVER_ERROR;   
					return new ResponseEntity(respuestaDto, estatus);
			 }
		
			 int absolutoOrden = Math.abs(orderIn);
			 
			 switch (absolutoOrden) { 
			    case 1:  //ordena por FECHA DE CREACION ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + "u.createdat" + ordena;
			     break;
                case 2:  //ordena por MODULO ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + "u.module" + ordena;
			     break;
                case 3:  //ordena por USUARIO ascendente
 	
 	                QueryTotal = QueryTotal + " ORDER BY " + "u.userref" + ordena;
                 break;
		  }
			 
			   TypedQuery<AuditAllDto> audito= entityManager.createQuery(QueryTotal, AuditAllDto.class);
			       audito.setFirstResult(offsetIn);
			       audito.setMaxResults(numofrecordsIn);
			      List<AuditAllDto> listacompleta = audito.getResultList();
			      
			      auditoriaModDto.setNumofrecords(cuantosregistro);
			       auditoriaModDto.setSessionvalidthru(fechaComoCadena);
			       auditoriaModDto.setRecords(listacompleta);
			       return ResponseEntity.ok(auditoriaModDto);
       
		}catch (Exception e) {
            // Manejo de excepciones
			respuesta= new RespuestaDto("Error interno del servidor", false);
			estatus=HttpStatus.INTERNAL_SERVER_ERROR;            
        }finally {
	        if (entityManager != null && entityManager.isOpen()) {
	            entityManager.close();
	        }
        }
		
		return new ResponseEntity(respuesta, estatus);
	
	}
	
	//@GetMapping("/menus)
		//public ResponseEntity<MenuResponseDto> menu(@PathVariable final String sessionid) throws ParseException {
	    @GetMapping("/extendsession")
		public ResponseEntity<ParamsResponseDto> extendSession(HttpServletRequest request) throws ParseException {
			RespuestaValidThruDto respuestaValidThruDto;
			RespuestaMsgDto respuestaMsgDto;
			RespuestaDto respuesta = new RespuestaDto("", false);
			HttpStatus estatus = HttpStatus.FORBIDDEN;
			ParamsResponseDto paramsResponseDto = new ParamsResponseDto();
			ParamsDto detalleParams;
			PrivilegesDto detallePrivilege;
			String fechaComoCadena;
			String sessionid = request.getHeader("Authorization");
			Long cuantosregistro = (long) 0;
		     List<ParamsDto> listasParams = new ArrayList<>();
		     List<PrivilegesDto> listasPrivelege = new ArrayList <>();

		     
		     try {
				if (sessionid==null) {
					String var = "";
					boolean bloked = false;
					RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
					respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("Sesión expirada o inválida");
					//Error 400
					return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				} else   {
					 
					   sessionid = sessionid.substring(7);
					   Optional<Users> encontreSessionUsuario =usersRepository.getBySessionid(sessionid);
					   
					   if (encontreSessionUsuario.isPresent()) {
						   
						   
						
						   //Este proceso permite obtener un listado de los parámetros (tabla "params") (Priv 610)
						   Roles roles = encontreSessionUsuario.get().getRolid();
						   int idrol = roles.getId();
						   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 610);
						   rolisvalid = 1;
						   if (rolisvalid==0) {
							   
							   String var = "";
								boolean bloked = false;
								RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
								//respuestaDto.setBlocked(bloked);
								respuestaDto.setMsg("No tiene los Privilegios"); 
								return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
								
						      }	else {
						    	  
						    	
						    	  
						    	  Optional<Params> deSessDuration=paramsRepository.findByParamname("SESSION_DURATION");
						 		  String SessionDuration=deSessDuration.get().getValue();
						 	      int duracionSession = Integer.parseInt(SessionDuration);
						 	      Calendar calendar = Calendar.getInstance();
						 		  calendar.add(Calendar.MINUTE,duracionSession); //horasASumar es int.
					        	  Date ValidThrufechaSalida = calendar.getTime(); //Y ya tienes la fecha sumada.
					              SimpleDateFormat salida = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //2024-12-23 23:00
					              String resp = salida.format(ValidThrufechaSalida);
					              
					               usersRepository.asociarcambioValidthru(encontreSessionUsuario.get().getId(),ValidThrufechaSalida);
									
					               //respuestaMsgDto= new RespuestaMsgDto(resp);
					               respuestaValidThruDto= new RespuestaValidThruDto(resp);
									estatus=HttpStatus.OK;
									return new ResponseEntity(respuestaValidThruDto, estatus);
						    
						    	  
						      }			
				
					
						
				   	 } else {
							String var = "";
							boolean bloked = false;
							RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
							respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("Sesión expirada o inválida");
							//Error 400
							return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
					 }
				}
				
				
	    } catch (Exception e) {
	            // Manejo de excepciones
				 respuesta = new RespuestaDto("Error interno del servidor", false);
				estatus=HttpStatus.INTERNAL_SERVER_ERROR;            
	        }
		 return new ResponseEntity(respuesta, estatus);
				
		}
	    
	  //@GetMapping("/menus)
	  		//public ResponseEntity<MenuResponseDto> menu(@PathVariable final String sessionid) throws ParseException {
	  	    @GetMapping("/pwdcomplexity")
	  		public ResponseEntity<Object> pwdcomplexity(HttpServletRequest request) throws ParseException {
	  			RespuestaValidThruDto respuestaValidThruDto;
	  			RespuestaMsgDto respuestaMsgDto;
	  			RespuestaDto respuesta = new RespuestaDto("", false);
	  			HttpStatus estatus = HttpStatus.FORBIDDEN;
	  			ParamsResponseDto paramsResponseDto = new ParamsResponseDto();
	  			ParamsDto detalleParams;
	  			PrivilegesDto detallePrivilege;
	  			String fechaComoCadena;
	  			String sessionid = request.getHeader("Authorization");
	  			Long cuantosregistro = (long) 0;
	  			 Date fecha2 = new Date();
	  		     List<ParamsDto> listasParams = new ArrayList<>();
	  		     List<PrivilegesDto> listasPrivelege = new ArrayList <>();

	  		   try {
	  		     
	  				if (sessionid==null) {
	  					String var = "";
	  					boolean bloked = false;
	  					RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
	  					respuestaDto.setBlocked(bloked);
	  					respuestaDto.setMsg("Sesión expirada o inválida");
	  					//Error 400
	  					return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
	  				} else   {
	  					 
	  					   sessionid = sessionid.substring(7);
	  					   Optional<Users> encontreSessionUsuario =usersRepository.getBySessionid(sessionid);
	  					   
	  					   if (encontreSessionUsuario.isPresent()) {	  						   	  
	  						   
	  						 Date FechaReg = encontreSessionUsuario.get().getValidthru(); 
	  					   //Llamada a la funcion que validad el tiempo de Session, retorna la fecha sumandole el tiempo de session activa, y vacio si no esta activa
	  					   
	  					   // fechaComoCadena  = securityService.consultarSessionActiva(FechaReg,fecha2);
	  					  fechaComoCadena  = securityService.consultarSessionActiva(FechaReg,fecha2,encontreSessionUsuario.get().getId());
	  					   
	  					    if (fechaComoCadena=="") {
	  						   
	  						   
	  						   
	  						   String var = "";
	  							boolean bloked = false;
	  							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
	  							//respuestaDto.setBlocked(bloked);
	  							respuestaDto.setMsg("Sesión expirada o inválida"); 
	  							return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
	  						   
	  					    }
	  					   
	  						   
	  						
	  						   //Este proceso permite obtener un listado de los parámetros (tabla "params") (Priv 610)
	  						   Roles roles = encontreSessionUsuario.get().getRolid();
	  						   int idrol = roles.getId();
	  						   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 610);
	  						   rolisvalid = 1;
	  						   
	  						   if (rolisvalid==0) {
	  							   
	  							   String var = "";
	  								boolean bloked = false;
	  								RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
	  								//respuestaDto.setBlocked(bloked);
	  								respuestaDto.setMsg("No tiene los Privilegios"); 
	  								return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
	  								
	  						      }	else {
	  						    	  
	  						    /*	String SentenciaBase = "SELECT u.paramname,u.value  FROM  main.params  u where u.paramname like '%PWD%'";
	  						    	List<Map<String, Object>> lista = jdbcTemplate.queryForList(SentenciaBase);
	  						    	
	  				    			
	  				    			 for (Map<String, Object> mapa : lista) {
	  				    				 String name = (String) mapa.get("paramname"); 
	  				    				 String value = (String) mapa.get("value");
	  				    				 
	  				    				 String valie2 = value;
	  				    			 }*/
	  				    			 
	  				    			
	  				    			/* //TypedQuery<Object> params= entityManager.createQuery(SentenciaBase, Object.class);
	  				    			List<Object> resultados;
	  				    			Object salida;
	  				    			resultados = params.getResultList();
	  				    			 * for (Object obj : resultados) {
	  				    				if (obj instanceof Params) {
	  				    					Params param = (Params) obj;
	  				    					String paramname = param.getParamname();
	  				    					String valor = param.getValue();
	  				    					salida = new Object(paramname,valor);
	  				    				}
	  				    			}*/
	  				    			
	  				    			
	  				    			
	  				    			
	  						    	  
	  						    	  Optional<Params> Minupper=paramsRepository.findByParamname("PWD_UPPERCASE");
	  						 		  String minupper=Minupper.get().getValue();
	  						 		  Optional<Params> Minsymbols=paramsRepository.findByParamname("PWD_SYMBOLS");
	  						 		  String minsymbols=Minsymbols.get().getValue();
	  						 		  Optional<Params> Minlower=paramsRepository.findByParamname("PWD_LOWERCASE");
	  						 		  String minlower=Minlower.get().getValue();
	  						 		  Optional<Params> Minlengthn=paramsRepository.findByParamname("PWD_MINLENGTH");
	  						 		  String minlengthn=Minlengthn.get().getValue();
	  						 		  Optional<Params> Allowedsimbols=paramsRepository.findByParamname("PWD_ALLOWEDSYM");
	  						 		  String allowedsimbols=Allowedsimbols.get().getValue();
	  						 		  
	  						 		PwdcomplexityDto pwdcomplexityDto = new PwdcomplexityDto();
	  						 	
	  						 		pwdcomplexityDto.setMinlength(minlengthn);
	  						 		
	  						 		pwdcomplexityDto.setMinupper(minupper);
	  						 		pwdcomplexityDto.setMinlower(minlower);
	  						 		pwdcomplexityDto.setMinsymbols(minsymbols);
	  						 		pwdcomplexityDto.setAllowedsimbols(allowedsimbols);
	  						 	     
	  									
	  					               //respuestaMsgDto= new RespuestaMsgDto(resp);
	  					              /// respuestaValidThruDto= new RespuestaValidThruDto(resp);
	  								//	estatus=HttpStatus.OK;
	  									return new ResponseEntity(pwdcomplexityDto, HttpStatus.OK);
	  						    
	  						    	  
	  						      }			
	  				
	  					
	  						
	  				   	 } else {
	  							String var = "";
	  							boolean bloked = false;
	  							RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
	  							respuestaDto.setBlocked(bloked);
	  							respuestaDto.setMsg("Sesión expirada o inválida");
	  							//Error 400
	  							return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
	  					 }
	  				}
	  			} catch (Exception e) {
	  	            // Manejo de excepciones
	  				 respuesta = new RespuestaDto("Error interno del servidor", false);
	  				estatus=HttpStatus.INTERNAL_SERVER_ERROR;            
	  	        }
	  		 return new ResponseEntity(respuesta, estatus);
	  		}
		
}