package com.dacrt.SBIABackend.security.controler;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.ArrayList;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.servlet.http.HttpServletRequest;

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.http.HttpStatus;
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.crypto.password.PasswordEncoder;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RestController;

import com.dacrt.SBIABackend.dto.Mensaje;
import com.dacrt.SBIABackend.dto.StatusDto;
import com.dacrt.SBIABackend.dto.SuppliersDtoStatus;
import com.dacrt.SBIABackend.dto.UnitsDto;
import com.dacrt.SBIABackend.dto.UnitsUsersDto;
import com.dacrt.SBIABackend.dto.WorkersDto;
import com.dacrt.SBIABackend.dto.responseDto.UnitsResponseDto;
import com.dacrt.SBIABackend.entity.Suppliers;
import com.dacrt.SBIABackend.entity.Units;
import com.dacrt.SBIABackend.entity.Userunits;
import com.dacrt.SBIABackend.entity.Workers;
import com.dacrt.SBIABackend.repository.SuppliersRepository;
import com.dacrt.SBIABackend.repository.UnitsRepository;
import com.dacrt.SBIABackend.repository.UserunitsRepository;
import com.dacrt.SBIABackend.repository.WorkersRepository;
import com.dacrt.SBIABackend.security.dto.AuditAllDto;
import com.dacrt.SBIABackend.security.dto.AuditRequestDto;
import com.dacrt.SBIABackend.security.dto.EntryDto;
import com.dacrt.SBIABackend.security.dto.HashPwdDto;
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.PrivilegesAllDto;
import com.dacrt.SBIABackend.security.dto.PrivilegesDto;
import com.dacrt.SBIABackend.security.dto.RespuestaDto;
import com.dacrt.SBIABackend.security.dto.RespuestaMsgDto;
import com.dacrt.SBIABackend.security.dto.RespuestaValueDto;
import com.dacrt.SBIABackend.security.dto.RoleDto;
import com.dacrt.SBIABackend.security.dto.RolesResponseDto;
import com.dacrt.SBIABackend.security.dto.RolesUserDto;
import com.dacrt.SBIABackend.security.dto.SuppliersUsersDto;
import com.dacrt.SBIABackend.security.dto.UserDetailsResponseDto;
import com.dacrt.SBIABackend.security.dto.UserListDto;
import com.dacrt.SBIABackend.security.dto.UserRequestNewDto;
import com.dacrt.SBIABackend.security.dto.UsersListDto;
import com.dacrt.SBIABackend.security.dto.UsersListResponseDto;
import com.dacrt.SBIABackend.security.dto.UsersRolesPriWorStaDto;
import com.dacrt.SBIABackend.security.dto.UsersUnitDto;
import com.dacrt.SBIABackend.security.dto.WorkersUsersDto;
import com.dacrt.SBIABackend.security.entity.Params;
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.repository.AuditRepository;
import com.dacrt.SBIABackend.security.repository.ParamsRepository;
import com.dacrt.SBIABackend.security.repository.RolesPrivilegesRepository;
import com.dacrt.SBIABackend.security.repository.RolesRepository;
import com.dacrt.SBIABackend.security.repository.UsersRepository;
import com.dacrt.SBIABackend.security.service.RolesService;
import com.dacrt.SBIABackend.security.service.SecurityService;
import com.dacrt.SBIABackend.security.service.MenuService;
import com.dacrt.SBIABackend.security.service.UsersService;
import com.dacrt.SBIABackend.service.SuppliersService;
import com.dacrt.SBIABackend.service.WorkersService;
import com.dacrt.SBIABackend.utils.HttpReqRespUtils;

@RestController
//@RequestMapping("/users")
//@CrossOrigin(origins = "http://vpskromasys2.hostnetcom.com/~daconsult/dev")
@CrossOrigin(origins = "*")
public class UsersController {
	
	@Autowired
	AuthenticationManager autheticationManager;
	
	@Autowired
	PasswordEncoder passworEncoder;
	
	@Autowired
	UsersService usersService;
	
	@Autowired
	MenuService menuService;
	
	@Autowired
	RolesService rolesService;
	
	@Autowired
	UsersRepository usersRepository;
	
	@Autowired
	ParamsRepository paramsRepository;
	
	@Autowired
	AuditRepository auditRepository;
	
	@Autowired
	UserunitsRepository userunitsRepository;
	
	@Autowired
	UnitsRepository unitsRepository;
	
	@Autowired
	WorkersRepository workersRepository;
	
	@Autowired
	SuppliersRepository suppliersRepository;
	
	@Autowired
	RolesPrivilegesRepository rolesPrivilegesRepository;
	
	@PersistenceContext
    private EntityManager entityManager;
	
	@Autowired
	WorkersService workersService;
	
	@Autowired
	SecurityService securityService;
	
	@Autowired
	RolesRepository rolesRepository;
	
	@Autowired
	SuppliersService suppliersService;
	
	@Autowired
    private JdbcTemplate jdbcTemplate;
	
	@Value("${var.ambiente}")
	private String urlAmbiente;
	
	@Value("${spring.datasource.url}")
	private String conexion;
	
	@Value("${spring.datasource.username}")
	private String userbd;
	
	@Value("${spring.datasource.password}")
	private String passbd;
	
	
	Logger logger = LoggerFactory.getLogger(UsersController.class);
	
	java.util.Date fechaActual = new java.util.Date();

	
	//@GetMapping("/menus)
	//public ResponseEntity<MenuResponseDto> menu(@PathVariable final String sessionid) throws ParseException {
	@PostMapping("/users")
	public ResponseEntity<UsersListResponseDto> userlist(HttpServletRequest request,@RequestBody UsersListDto tiposfiltros) throws ParseException {
		 
		 String sessionid = request.getHeader("Authorization");
		 UsersListResponseDto usersResponseDto = new UsersListResponseDto();
		 RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		 HttpStatus estatus = HttpStatus.FORBIDDEN;
		 int statusIn = tiposfiltros.getFilters().getStatus();
		 int roleIn = tiposfiltros.getFilters().getRole();
		 String searchIn = tiposfiltros.getFilters().getSearch();
		 int orderIn = tiposfiltros.getOrder();
		 int offsetIn = tiposfiltros.getOffset();
		 int numofrecordsIn = tiposfiltros.getNumofrecords();
		 PrivilegesAllDto detallePrivilege;
		// List<UsersRolesPriWorStaDto> listaUserRolWorStaSup = new ArrayList<>();
		 List<UsersRolesPriWorStaDto> listasUsersRolesPriWorStaDto = new ArrayList<>();
		 UsersRolesPriWorStaDto detalleUsers;
		 StatusDto detalleStatus;
		 WorkersUsersDto detalleworker;
		 SuppliersUsersDto detallesupplier;
		 RolesUserDto detalleroles;
		 
    	   detalleStatus = new StatusDto();
    	   String fechaComoCadena;
		  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();
		 Long cuantosregistro = (long) 0;
		 //Optional<Users> encontreUSERS = tiposfiltros.getFilter().get(0);
		 Optional<Params> deSessDuration=paramsRepository.findByParamname("SESSION_DURATION");
		 String SessionDuration=deSessDuration.get().getValue();
		 int duracionSession = Integer.parseInt(SessionDuration);
		 Date fecha2 = new Date();
		 int idrol;
		  
		try {
			
			  //String searchIn = "";
		      String searchModule = "";
			  String searchUsr = "";
			  String contentIn = "";
			  int searchStatus = 0;
			  int searchRoles= 0;
			 
			
			if (sessionid==null) {
				String var = "";
				boolean bloked = false;
				RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
				//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('('); 
				   
				   if (encontreSessionUsuario.isPresent()) {
					   Date FechaReg = encontreSessionUsuario.get().getValidthru(); 
					  // 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 usuarios. (Priv 630)
					   Roles roles = encontreSessionUsuario.get().getRolid();
					   idrol = roles.getId();
					   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 630);
					   
					   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());
						  
						  searchModule = tiposfiltros.getFilters().getModule();
						  searchUsr = tiposfiltros.getFilters().getUser();
						//  searchDatefrom = tiposfiltros.getFilters().getDatefrom();
						//  searchDateto = tiposfiltros.getFilters().getDateto();
						  searchStatus = tiposfiltros.getFilters().getStatus();
						  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;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						//respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Sesión expirada o inválida");
						//Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
				 }
			}
									
			
			String SentenciaBase = "SELECT u.id,u.usr,u.name,u.email,u.rolid,u.workerid,u.supplierid,u.status FROM main.users u";					
			String QueryTotal = "";
			//String name = "u.dsc";
		//	String status = "u.status";				
			String lowername = "LOWER(u.dsc)";
			String LowerSearch = searchIn.toLowerCase();
			///String lowerdsc = "main.sinacentos(LOWER(ed.dsc))";
			//searchIn.toUpperCase()
			 switch (searchIn) { 
			    case "":  // viene sin busqueda por el like
			    	QueryTotal = SentenciaBase + " WHERE " + "TRUE = TRUE";
			     break;
			  
			    default:	// viene con el parametro para buscar por el like		   			    				    	
			    	QueryTotal = SentenciaBase + " WHERE " + " main.sinacentos(LOWER(u.usr))" + " LIKE  " + "'%" + LowerSearch + "%'" + " OR " + " main.sinacentos(LOWER(u.name)) " + " LIKE  " + "'%" + LowerSearch + "%'" + " OR " + " main.sinacentos(LOWER(u.email))" + " LIKE  " + "'%" + LowerSearch + "%'" ;
			    	
	         }
			 
			 switch (roleIn) { 
			    case 0:  // viene con el rolid 0, entonces se deben traer por todos los rolid
			    	//QueryTotal = SentenciaBase;
			    	QueryTotal = QueryTotal;
			     break;
			  
			    default:	// viene con el rolid <>0, entonces se debe buscar el rol exacto que llego por parametro
			    	
			    	QueryTotal = QueryTotal + " AND " + "u.rolid = " + roleIn;
			    	
	         }
			 
			 switch (searchStatus) { 
			    case 0:  // Busca por cualquier estatus
			    	QueryTotal = QueryTotal;
			     break;
			    case 1:  // Busca por estatus activo
			    	
			    	QueryTotal = QueryTotal  + " AND " + "u.status" + " = " + searchStatus;
			     break;
			    case 2:  // Busca por estatus Inactivo
			    	
			    	//QueryTotal = QueryTotal  + " AND " + "u.status" + " = " + searchStatus;
			    	QueryTotal = QueryTotal  + " AND " + "u.status" + " = " + 0;
			     break;
			  
			    default:	// maneja el error enviando el mensaje, ocurre cuando el valor de estatus no es 0,1 ó 2		   			    				    	
			    	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);
			    	
	         }
			
			  cuantosregistro = (long) jdbcTemplate.queryForList(QueryTotal).size(); // primer toque para saber la cantidad de registros sin Order	
			  String ordena="";
			  if (orderIn == 1 || orderIn == 2 || orderIn == 3 || orderIn == 4 || orderIn == 5 || orderIn == 6) {
				  ordena = " ASC";
			 }  else if (orderIn == -1 || orderIn == -2 || orderIn == -3 || orderIn == -4 || orderIn == -5 || orderIn == -6) {
				  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) {  /// se forma la sentencia order
			    case 1:  //ordena por createdat ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + "u.createdat" + ordena;
			     break;
			    case 2:   //ordena por name ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + "u.name" + ordena;
			     break;	
                case 3:  //ordena por user ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + "u.usr" + ordena;
			     break;
			    case 4:   //ordena por email ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + "u.email" + ordena;
			     break;		
                case 5:  //ordena por rolid ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + "u.rolid" + ordena;
			     break;
			    case 6:   //ordena por status ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + "u.status" + ordena;
			     break;		
                
			   }
			 
			 QueryTotal = QueryTotal + " LIMIT " + numofrecordsIn + " OFFSET " + offsetIn; //se pasa el limit y el offset distinto a otros metodos, esto por problemas con el typed
			 //para manejar los campos nullos que son FK, los registros resultantes son pasados a un HashMap
			 List<Map<String, Object>> lista = jdbcTemplate.queryForList(QueryTotal);
				
			      
			      
			       detalleworker = new WorkersUsersDto();
		    	   detallesupplier = new SuppliersUsersDto();
		    	   detalleroles = new RolesUserDto();
		    	   detalleStatus = new StatusDto();
		    	   
		    		  
		    	  	detallePrivilege = new PrivilegesAllDto();
		    	  	
		    	       boolean tieneView = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,630);
					   boolean tieneUpdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,631);
					   boolean tieneAdd = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,632);
					   boolean tieneDelete = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,633);
					   //existsByRolidAndPrivilegeid
					   
	      	    	 	detallePrivilege.setView(tieneView);
			    	  	detallePrivilege.setUpdate(tieneUpdate);		    	  
			    	  	detallePrivilege.setAdd(tieneAdd);
			    	  	detallePrivilege.setDelete(tieneDelete);
		    	  /*	detallePrivilege.setUpdate(true);
		    	  	detallePrivilege.setView(true);
		    	  	detallePrivilege.setAdd(true);
		    	  	detallePrivilege.setDelete(true);	*/	    	   			    	   
		    		  
		    		  // for(Users users : UsersMov) {
		    			   //for(UserListDto usuarios : listacompleta) {
		    				 for (Map<String, Object> mapa : lista) 
		    				 {
					    	  List<StatusDto> listasStatus = new ArrayList<>();
					    	  
					    	  
					    	  List<WorkersUsersDto> listasWorkersUsersDto = new ArrayList<>();
					    	  List<SuppliersUsersDto> listasSuppliersUsersDto = new ArrayList<>();
					    	  List<RolesUserDto> listasRolesUsersDto = new ArrayList<>();
					    	  
					    	   detalleUsers = new UsersRolesPriWorStaDto();
					    	   detalleStatus = new StatusDto();
					    	   detalleworker = new WorkersUsersDto();
					    	   detallesupplier = new SuppliersUsersDto();
					    	   detalleroles = new RolesUserDto();
					    	   
					    	   
								  int id = (int) mapa.get("id");
								  String usr = (String) mapa.get("usr");
								  String name = (String) mapa.get("name"); 
								  String email = (String) mapa.get("email"); 
								  int rolid = (int) mapa.get("rolid"); 								  								 
								  int status = (int) mapa.get("status");
								 
					  		 
					    	   detalleUsers.setId(id);
					    	   detalleUsers.setUsr(usr);
					    	   detalleUsers.setName(name);
					    	   detalleUsers.setEmail(email);
					    	   
					    	   try {
					    		      int workerid = (int) mapa.get("workerid");
					    		      Optional<Workers> worker = workersRepository.findById(workerid);
				                   	  detalleworker.setId(worker.get().getId());
				                   	  detalleworker.setName(worker.get().getName());

  						    	       
						    	   } catch(Exception e) {
						    		   detalleworker.setId(0);
						    		   detalleworker.setName("");
						    	   }
                                 listasWorkersUsersDto.add(detalleworker);
                                 
                                 try {
                                	      int supplierid = (int) mapa.get("supplierid");
                                		  Optional<Suppliers> supply = suppliersRepository.findById(supplierid);
                                		  detallesupplier.setId(supply.get().getId());
                                		  detallesupplier.setName(supply.get().getName());
                                	 
						    	  // detallesupplier.setId(usuarios.getSupplierid().getId());
						    	  // detallesupplier.setName(usuarios.getSupplierid().getName());
                                 }  catch(Exception e) {
                                  detallesupplier.setId(0);
  						    	   detallesupplier.setName("");
                                 }
						    	   
						    	   listasSuppliersUsersDto.add(detallesupplier);
					    	   
					    	   detalleStatus.setId(status);
					    	   
					    	   if (status==1) {
					    		   String descestatus = "Activo";
					    		   detalleStatus.setName(descestatus);
					    		   
					    	   } else {
					    		   String descestatus = "Inactivo";	
					    		   detalleStatus.setName(descestatus);
					    	   }
					    	   listasStatus.add(detalleStatus);
					    	   Optional<Roles> rolesOnly = rolesRepository.findById(rolid);
					    	   detalleroles.setId(rolesOnly.get().getId());
					    	   detalleroles.setName(rolesOnly.get().getName()); 
					    	   listasRolesUsersDto.add(detalleroles);
					    	   
					    	   
					    	   detalleUsers.setWorker(detalleworker);
					    	   detalleUsers.setSupplier(detallesupplier);
					    	   detalleUsers.setStatus(detalleStatus);
					    	   detalleUsers.setRole(detalleroles);
					    	   
					    	   
					    	   listasUsersRolesPriWorStaDto.add(detalleUsers);				    	   													             
					             
					        }
		
		    	
		    	  	usersResponseDto.setNumofrecords(cuantosregistro);
		           //paramsResponseDto.setValidthru(ValidThrufechaSalida);
		    	  	usersResponseDto.setSessionvalidthru(fechaComoCadena);		           
		    	  	usersResponseDto.setRecords(listasUsersRolesPriWorStaDto);
		    	  	usersResponseDto.setPrivileges(detallePrivilege);		      		   			
		  						           
                     return ResponseEntity.ok(usersResponseDto);
			
		}catch(Exception e) {
			String var = e.getMessage();
			boolean bloked = false;
			RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
			//respuestaDto.setBlocked(bloked);
			respuestaDto.setMsg("Error interno del servidor");
			respuestaDto.setMsg(var);

			return new ResponseEntity(respuestaDto, HttpStatus.INTERNAL_SERVER_ERROR);
		}finally {
	        if (entityManager != null && entityManager.isOpen()) {
	            entityManager.close();
	        }
		}
		
	

	}	
	
	@PostMapping("/users/{userid}")
	public ResponseEntity<ParamsResponseDto> usersUpdate(HttpServletRequest request,@RequestBody UserRequestNewDto datosUsuario,@PathVariable("userid") final Integer userid) throws ParseException, UnsupportedEncodingException {
		
		
		RespuestaValueDto respuestaValueDto;
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		ParamsResponseDto paramsResponseDto = new ParamsResponseDto();
		ParamsDto detalleParams;
		PrivilegesDto detallePrivilege;
	     List<ParamsDto> listasParams = new ArrayList<>();
	     List<PrivilegesDto> listasPrivelege = new ArrayList<>();
	     
		 int idparametro = userid;
		 Optional<Users> encontreSessionUsuario;
		 int valor = idparametro;
		 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();
	       	        	     	       	       	  		
		   Date fecha2 = new Date();
		   Calendar calendar = Calendar.getInstance();
		   
		   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);
			/////aqui validamos los caracteres permitidos para la creacion del nickname//////////////
			 Optional<Params> deCarateresPer=paramsRepository.findByParamname("NICK_ALLOWEDSYM");
			   String caracterespermi=deCarateresPer.get().getValue();
			   String encoding2 = StandardCharsets.UTF_8.toString();
				String caracteresCodificados2 = URLEncoder.encode(caracterespermi, encoding2);
		    ////////////////////////////////////////////////////////////////////////////////////////
			if (sessionid==null) {
				String var = "";
				boolean bloked = false;
				RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
				//respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Llamada al servicio malformado");
				//Error 400
				return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
			} else   {
				 
				   sessionid = sessionid.substring(7);
				   encontreSessionUsuario =usersRepository.getBySessionid(sessionid);
			String fechaComoCadena;
				   
				   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);
  						   
  					    }
  					   
					 //Actualiza o Incluye un registro de un usuario. (Si el userid es 0 se incluye). (priv 631 MOD Y 632 INC)
					   if (idparametro==0) {
						   //el permiso es el 632
						   Roles roles = encontreSessionUsuario.get().getRolid();
						   int idrol = roles.getId();
						   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 632);
						   
						   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 {
					   
					   Roles roles = encontreSessionUsuario.get().getRolid();
					   int idrol = roles.getId();
					   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 631);
					   
					   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);
						   
					     }
					   } 
					   
					   
					    String SalidaName= usersService.verificarCaracteresValidosConRegex(datosUsuario.getName());
					    String SalidaUsu = usersService.verificarCaracteresValidosConRegex(datosUsuario.getUsr());
					    String Salidaemail = usersService.verificarCaracteresValidosConRegex(datosUsuario.getEmail());
					    
					    if (SalidaName=="NOOK" || SalidaUsu=="NOOK" || Salidaemail=="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);
						  }
						
					   
					   if (idparametro==0) {
						   
                       if  (datosUsuario.getWorkerid()!= 0 ) {
							   
							   int existeEmpleadoUser = usersRepository.consultarUsuWorkers(datosUsuario.getWorkerid());
							    if (existeEmpleadoUser>0) {
							    	String var = "";
							    	RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
									//respuestaDto.setBlocked(bloked);
									respuestaDto.setMsg("Registro Duplicado");
									//Error 400
									return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
							    }
						   }
					                     						   
					
						  // if (usersRepository.existsByEmail(encontreSessionUsuario.get().getEmail())) {
							   
							   
						  // }
						    //////////////////////////INSERCION BLOQUE DE AUDITORIA///////////////////
						 /*    String module = "Usuarios";
						     //String Descmodule = "Actualización de parametro del Sistema con id: " + parmid  ;
						     String Descmodule = "Se agregó a: " + datosUsuario.getEmail();
						    
					         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);
					         auditDto.setModule(module);
					         auditDto.setDesc(Descmodule);
					         auditDto.setCreatedat(fechaDate);
					 		   usersService.registrarAuditSesion(auditDto); */
						   
					   } else {
						   boolean existeUser =  usersRepository.existsById(idparametro);
						   if (!existeUser) {
					    	    String var = "";
								boolean bloked = false;
								RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
								//respuestaDto.setBlocked(bloked);
								respuestaDto.setMsg("Registro no encontrado"); 
								return new ResponseEntity(respuestaDto, HttpStatus.NOT_FOUND);
					    	  
					      }
					    	  
					    	  
					    /*  {
					    	  
					      
								   				
					      }*/
						   
					   }
						
					   
					   for (int i = 0; i < datosUsuario.getUsr().length(); i++) {
						   
						   char currentChar = datosUsuario.getUsr().charAt(i);
				            // Verificar si el carácter no está en el conjunto de permitidos
						   if (caracterespermi.indexOf(currentChar) == -1) {
				                
				                // Si indexOf devuelve -1, el carácter no está permitido.
				             //   String errorMsg = String.format(
				               //     "Error: El carácter '%c' en la posición %d no está permitido.",
				                 //   currentChar, i
				               // );
				                String var = "";
								boolean bloked = false;
								RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
								//respuestaDto.setBlocked(bloked);
								respuestaDto.setMsg("Caracteres no permitidos en el Nombre del Usuario"); 
								return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				            }
				        }
					       
			
				   
				 } else {
						String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						//respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Sesión expirada o inválida");
						//Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
				 }
			}
			
			
		
		try {
			
			Users tipoUsers2=null;
			Users tipoUsers=null;
			Users tipoUsersNew2=null;
			Optional<Users> nuevoinsertado = null;
			
			Userunits tipoUsersUnits = new Userunits();	
			if (idparametro==0) {
				Users tipoUsersNew = new Users();
				tipoUsersNew.setStatus(datosUsuario.getStatus());
				
				tipoUsersNew.setName(datosUsuario.getName());
				boolean validaemail = usersRepository.existsByEmail(datosUsuario.getEmail());
				boolean validaUser = usersRepository.existsByUsr(datosUsuario.getUsr());
                if (validaUser) {
					
					String var = "";
					//boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					//respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("Registro Duplicado");
					//Error 400
					return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
					
				} else {
					tipoUsersNew.setUsr(datosUsuario.getUsr());
				}
				if (validaemail) {
					
					String var = "";
					//boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					//respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("Registro Duplicado");
					//Error mensaje conflicto
					return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
					
				} else {
					tipoUsersNew.setEmail(datosUsuario.getEmail());
				}
				
				tipoUsersNew.setModifiedat(fechaDate);
				tipoUsersNew.setCreatedat(fechaDate);  //tipoUsers.setLastpwdchange(fechaDate);
				tipoUsersNew.setLastpwdchange(fechaDate);
				tipoUsersNew.setFails(0);
				tipoUsersNew.setLastsession(fechaDate);
				
		        if (datosUsuario.getRoleid()!=0) {
					Roles tipoRol = rolesService.getRolesByid(datosUsuario.getRoleid());
					tipoUsersNew.setRolid(tipoRol);
				} else
				{
					Roles tipoRol = rolesService.getRolesByid(datosUsuario.getRoleid());
					tipoUsersNew.setRolid(tipoRol);
				}
	            
	            if (datosUsuario.getWorkerid()!=0) {
	            	Workers tipoWorkers = workersService.getWorkersByid(datosUsuario.getWorkerid());
	            	tipoUsersNew.setWorkerid(tipoWorkers);
				}
	            
	            if (datosUsuario.getSupplierid()!=0) {
	            	Suppliers tipoSuppliers = suppliersService.getSuppliersByid(datosUsuario.getSupplierid());
	            	tipoUsersNew.setSupplierid(tipoSuppliers);
				}
	            String jwt = UUID.randomUUID().toString();
	            tipoUsersNew.setSessionid(jwt);
				
	            tipoUsersNew2=usersService.addIdUsers(tipoUsersNew);
	            tipoUsers2 = tipoUsersNew2;
	            
	            String saludo = " Por favor ingresa en el siguiente enlace para definir  tu clave y completar tu registro en el sistema:";
	            String accion = "Registrar";
	        	String idcampo = "?sid=";
				String ConcatAmbiente = urlAmbiente + (idcampo);
				

		        String idcampoLogo = "img/logo.png";
				String ConcatAmbienteLogo = urlAmbiente + (idcampoLogo);
				String ruta = ConcatAmbienteLogo;
				
				   String module = "Usuarios";
				     //String Descmodule = "Actualización de parametro del Sistema con id: " + parmid  ;
				     String Descmodule = "Se agregó a: " + datosUsuario.getEmail();
				    
			         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);
			         auditDto.setModule(module);
			         auditDto.setDesc(Descmodule);
			         auditDto.setCreatedat(fechaDate);
			 		   usersService.registrarAuditSesion(auditDto); 
				
		
				
	            String url = ConcatAmbiente + "changepwd" + "&" + "hash" + "=" + jwt + "&" + "email" + "=" + datosUsuario.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;
	            
		         String contenido  = usersService.ArmarBodySendMailUser(ConcatAmbienteLogo,datosUsuario.getName(),saludo,url,accion,minlongitud,cantMayusculas,cantMinusculas,cantSimbolos,simbolospermi);
		         usersService.sendEmail(datosUsuario.getEmail(), contenido , "Bienvenido al sistema GCN");

			} else {
				 tipoUsers = usersService.getUsersByid(idparametro);
				 
					tipoUsers.setStatus(datosUsuario.getStatus());
					//tipoUsers.setUsr(datosUsuario.getUsr());

					String user1 = tipoUsers.getUsr();
					String user2 = datosUsuario.getUsr();
					if (user1.equals(user2)){
						String Validausers = "El user es el mismo";
				    	
					} else {
					boolean validaUser = usersRepository.existsByUsr(datosUsuario.getUsr());
	                if (validaUser) {
						
						String var = "";
						//boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						//respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Registro Duplicado");
						//Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
						
					} else {
						tipoUsers.setUsr(datosUsuario.getUsr());
					}
				}	
					
					tipoUsers.setName(datosUsuario.getName());
					
//					String Work1 =  tipoUsers.getWorkerid().getId();
					int workers1 = 0;
					try {
					 workers1 = tipoUsers.getWorkerid().getId();
					
					} catch (Exception e) {
						
						workers1 = 0;
					}
					int workers2 = datosUsuario.getWorkerid();
				//	int suppliers1 = tipoUsers.getSupplierid().getId();
				//	int suppliers2 = datosUsuario.getSupplierid();
					
					if (workers2 != 0) {
						
						if (workers1==workers2) {
							String ValidaWorkers = "El id workers es el mismo";
							
						} else {
							
							  int existeEmpleadoUser = usersRepository.consultarUsuWorkers(datosUsuario.getWorkerid());
							    if (existeEmpleadoUser>0) {
							    	String var = "";
							    	RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
									//respuestaDto.setBlocked(bloked);
									respuestaDto.setMsg("Registro Duplicado");
									//Error 400
									return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
							    }
							
						}
						
						
					}
					
                   
					
					String correo1 = tipoUsers.getEmail();
					String correo2 = datosUsuario.getEmail();
					if (correo1.equals(correo2)){
						String Validacorreo = "El email es el mismo";
				    	
					} else {
						boolean validaemail = usersRepository.existsByEmail(datosUsuario.getEmail());
					   	if (validaemail) {
							
							
							String var = "";
							//boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("Registro Duplicado");
							//Error 400
							return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
							
						  } else {
							 tipoUsers.setEmail(datosUsuario.getEmail());
					     }
						
					}
					//if (tipoUsers.getEmail()==datosUsuario.getEmail()) {}
					//tipoUsers.setEmail(datosUsuario.getEmail());
					tipoUsers.setModifiedat(fechaDate);
					
					//tipoUsers.setCreatedat(fecha2);
					tipoUsers.setFails(0);
					
					
			        if (datosUsuario.getRoleid()!=0) {
						Roles tipoRol = rolesService.getRolesByid(datosUsuario.getRoleid());
						tipoUsers.setRolid(tipoRol);
					} else {
						Roles tipoRol = rolesService.getRolesByid(datosUsuario.getRoleid());
						tipoUsers.setRolid(tipoRol);
					}
		            
		            if (datosUsuario.getWorkerid()!=0) {
		            	Workers tipoWorkers = workersService.getWorkersByid(datosUsuario.getWorkerid());
						tipoUsers.setWorkerid(tipoWorkers);
					} else {
						
						usersRepository.updateWorkeridbyId(idparametro);
						//Workers tipoWorkers = workersService.getWorkersByid(datosUsuario.getWorkerid());
						//tipoUsers.setWorkerid(tipoWorkers);
						
					}
		            
		            
		            if (datosUsuario.getSupplierid()!=0) {
		            	Suppliers tipoSuppliers = suppliersService.getSuppliersByid(datosUsuario.getSupplierid());
						tipoUsers.setSupplierid(tipoSuppliers);
					} else {
						//Suppliers tipoSuppliers = suppliersService.getSuppliersByid(datosUsuario.getSupplierid());
						//tipoUsers.setSupplierid(tipoSuppliers);
						usersRepository.updateSuppliersidbyId(idparametro);
						//usersRepository.updateSuppliersidbyId(idparametro);
					}
		            
		            tipoUsers2=usersService.addIdUsers(tipoUsers);
		            
		            
				    //////////////////////////INSERCION BLOQUE DE AUDITORIA///////////////////
				     String module = "Usuarios";
				     //String Descmodule = "Actualización de parametro del Sistema con id: " + parmid  ;
				     String Descmodule = "Se actualizó a: "+ datosUsuario.getEmail();
				    
			         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);
			         auditDto.setModule(module);
			         auditDto.setDesc(Descmodule);
			         auditDto.setCreatedat(fechaDate);
			 		   usersService.registrarAuditSesion(auditDto); 
			 		  //////////////////////////INSERCION BLOQUE DE AUDITORIA///////////////////				
		            
		            if (datosUsuario.getWorkerid()==0) {
		            	usersRepository.updateWorkeridbyId(idparametro);
		            }
		            if (datosUsuario.getSupplierid()==0) {
		            	usersRepository.updateSuppliersidbyId(idparametro);
		            }
			      }
		int idmensaje=0;																	           
		if (idparametro!=0) {
            try {   
            	
                userunitsRepository.borrarUsersUnits(tipoUsers.getId());
                idmensaje = userid;
                Connection conexion2 = DriverManager.getConnection(conexion,userbd, passbd);
    			//(PreparedStatement sentenciaPreparada = conexion2.prepareStatement(sql))
    			Statement sentenciaPreparada = null;
    			sentenciaPreparada = conexion2.createStatement();

         
    			int cuantasuni = datosUsuario.getUnits().size();
    			
    			if (cuantasuni > 0 ) {
                    String unidades = arrayAParentesis(datosUsuario.getUnits());
    			
    	            String sql = "INSERT INTO main.userunits (unitid,userid) SELECT id," + userid + " FROM main.units  WHERE id IN " + unidades;
    	            sentenciaPreparada.execute(sql);
    			}
                
            } catch (Exception e) {
            	  // Manejo de excepciones
    			respuesta= new RespuestaMsgDto("Error borrando la relacion Unidades Usuarios");
    			estatus=HttpStatus.CONFLICT;     
            	
            }
		} else {
			
			nuevoinsertado = usersRepository.findByEmail(datosUsuario.getEmail());
			int idInsertado =  nuevoinsertado.get().getId();
			idmensaje = idInsertado;
			//Connection conexion = null;
			Connection conexion2 = DriverManager.getConnection(conexion,userbd, passbd);
			//(PreparedStatement sentenciaPreparada = conexion2.prepareStatement(sql))
			Statement sentenciaPreparada = null;
			sentenciaPreparada = conexion2.createStatement();
	        
	      
			int cuantasuni = datosUsuario.getUnits().size();
			
			if (cuantasuni > 0 ) {
			   String unidades = arrayAParentesis(datosUsuario.getUnits());			
	           String sql = "INSERT INTO main.userunits (unitid,userid) SELECT id," + idInsertado + " FROM main.units  WHERE id IN " + unidades;
	           sentenciaPreparada.execute(sql);
					
	        		
	                   
			}   
		}
		
          
            		
			if (tipoUsers2!=null) { //Comprobar si es distinto de null
				
				String Resp = userid.toString();
				respuestaValueDto= new RespuestaValueDto(idmensaje);
				//int parmid = 2;
				//respuestaValueDto= new RespuestaValueDto(userid);
				estatus=HttpStatus.OK;
				return new ResponseEntity(respuestaValueDto, estatus);
				
			}else {
				respuesta= new RespuestaMsgDto("Fallo la actualizacion");
				estatus=HttpStatus.BAD_REQUEST;
				return new ResponseEntity(respuesta, estatus);
				
			}
			
						
       
		}catch (Exception e) {
            // Manejo de excepciones
			respuesta= new RespuestaMsgDto("Error interno del servidor");
			estatus=HttpStatus.INTERNAL_SERVER_ERROR;            
        } finally {
	        if (entityManager != null && entityManager.isOpen()) {
	            entityManager.close();
	        }
	    }
		
		return new ResponseEntity(respuesta, estatus);
	
	}
	
	public String arrayAParentesis(List<Integer> lista) {
		
	    if (lista == null || lista.isEmpty()) {
	        return "()";
	    }
	    StringBuilder sb = new StringBuilder("(");
	    for (int i = 0; i < lista.size(); i++) {
	        sb.append(lista.get(i));
	        if (i < lista.size() - 1) {
	            sb.append(", ");
	        }
	    }
	    sb.append(")");
	    return sb.toString();
	}
	
	@GetMapping("/users/{userid}")
	public ResponseEntity<?> getOneUsers(HttpServletRequest request, @PathVariable("userid") final Integer userid)
			throws ParseException {
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		// List<UsersRolesPriWorStaDto> listaUserRolWorStaSup = new ArrayList<>();
		 List<UsersRolesPriWorStaDto> listasUsersRolesPriWorStaDto = new ArrayList<>();
		 UsersRolesPriWorStaDto detalleUsers;
		 StatusDto detalleStatus;
		 WorkersUsersDto detalleworker;
		 SuppliersUsersDto detallesupplier;
		 RolesUserDto detalleroles;
		 UnitsDto detalleUnits;
		 UsersUnitDto detalleUserUnits;
		 
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		try {

			RespuestaValueDto respuestaValueDto;
			String var = "";
			boolean bloked = false;
			RespuestaDto respuestaDto = new RespuestaDto(var, bloked);

			RolesResponseDto rolesResponseDto = new RolesResponseDto();
			RoleDto detalleRoles;
			PrivilegesAllDto detallePrivilege;
			Long cuantosregistro = (long) 0;
			List<RoleDto> listasRoles = new ArrayList<>();
			List<PrivilegesAllDto> listasPrivelege = new ArrayList<>();

			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();

			

			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) {
				respuesta.setMsg("Llamada al servicio malformado");
				return new ResponseEntity(respuesta, 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 var2 = "";
  							boolean bloked2 = false;
  							RespuestaMsgDto respuestaDto2 = new RespuestaMsgDto(var2);
  							//respuestaDto.setBlocked(bloked);
  							respuestaDto2.setMsg("Sesión expirada o inválida"); 
  							return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
  						   
  					    }
  					   
					// Obtiene la información de un usuario en particular. (priv 630)
					  Roles roles = encontreSessionUsuario.get().getRolid();
					   int idrol = roles.getId();
					   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 630);
					   
					   if (rolisvalid==0) {
						  
						   
							//boolean bloked = false;
							RespuestaMsgDto respuestaPrivDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaPrivDto.setMsg("No tiene los Privilegios"); 
							return new ResponseEntity(respuestaPrivDto, HttpStatus.FORBIDDEN);
							
					   }
					   
					boolean existeUsers = usersRepository.existsById(userid);
					if (!existeUsers) {
						respuesta.setMsg("Registro no encontrado");
						return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
					} else {
						//int rolisvalid = 0;
						List<Userunits> listaUserUnits = new ArrayList<>();
						Optional<Users> UsersElegido = usersRepository.findById(userid);
						 
				    	   
						 listaUserUnits=userunitsRepository.findByUserid(userid);
						 List<UnitsUsersDto> listasUnidadesDto = new ArrayList<>();
						 List<UsersUnitDto> ListunitsAsociadas= new ArrayList<>();
						 
						 detalleUnits = new UnitsDto();
						 
						for(Userunits units : listaUserUnits) {
							detalleUserUnits = new UsersUnitDto();
							int unitid = units.getUnitid();
							
							
							Optional<Units> unidadselecc = unitsRepository.findById(unitid);
							detalleUserUnits.setId(unidadselecc.get().getId());
							detalleUserUnits.setName(unidadselecc.get().getDsc());
							ListunitsAsociadas.add(detalleUserUnits);
							
						}
						
						  List<StatusDto> listasStatus = new ArrayList<>();						    	  						    	  
				    	  List<WorkersUsersDto> listasWorkersUsersDto = new ArrayList<>();
				    	  List<SuppliersUsersDto> listasSuppliersUsersDto = new ArrayList<>();
				    	  List<RolesUserDto> listasRolesUsersDto = new ArrayList<>();				    	  				    	  				    	  
				    	   detalleUsers = new UsersRolesPriWorStaDto();
				    	   detalleStatus = new StatusDto();
				    	   detalleworker = new WorkersUsersDto();
				    	   detallesupplier = new SuppliersUsersDto();
				    	   detalleroles = new RolesUserDto();
				    	   
				    	      detalleUsers.setId(UsersElegido.get().getId());
							  detalleUsers.setUsr(UsersElegido.get().getUsr());
					    	  detalleUsers.setName(UsersElegido.get().getName());	    	   
					    	  detalleUsers.setEmail(UsersElegido.get().getEmail());
				    	   
				    	   try {
                         	  detalleworker.setId(UsersElegido.get().getWorkerid().getId());
                         	  detalleworker.setName(UsersElegido.get().getWorkerid().getName());
					    	       
					    	   } catch(Exception e) {
					    		   detalleworker.setId(0);
					    		   detalleworker.setName("");
					    	   }
                           listasWorkersUsersDto.add(detalleworker);
                           
				    	   
				    	   try {
					    	   detallesupplier.setId(UsersElegido.get().getSupplierid().getId());
					    	   detallesupplier.setName(UsersElegido.get().getSupplierid().getName());
                              }  catch(Exception e) {
                                   detallesupplier.setId(0);
						    	   detallesupplier.setName("");
                              }
				    	   listasSuppliersUsersDto.add(detallesupplier);
				    	   
				    	   detalleStatus.setId(UsersElegido.get().getStatus());
				    	   
				    	   if (UsersElegido.get().getStatus()==1) {
				    		   String descestatus = "Activo";
				    		   detalleStatus.setName(descestatus);
				    		   
				    	   } else {
				    		   String descestatus = "Inactivo";	
				    		   detalleStatus.setName(descestatus);
				    	   }
				    	   listasStatus.add(detalleStatus);
				    	   
				    	   detalleroles.setId(UsersElegido.get().getRolid().getId());
				    	   detalleroles.setName(UsersElegido.get().getRolid().getName());
				    	   listasRolesUsersDto.add(detalleroles);
				    	   
				    	 
				    	   detalleUsers.setWorker(detalleworker);
				    	   detalleUsers.setSupplier(detallesupplier);
				    	   detalleUsers.setStatus(detalleStatus);
				    	   detalleUsers.setRole(detalleroles);
				    	   detalleUsers.setUnits(ListunitsAsociadas);
				    	   
				    	  // listasUsersRolesPriWorStaDto.add(detalleUsers);	
				    	   
				    	   UserDetailsResponseDto entry = new UserDetailsResponseDto();
			    		   //usersResponseDto.setSessionvalidthru(fechaDate);
				        //UserDetailsResponseDto.setSessionvalidthru(fechaComoCadena);
				    	   entry.setEntry(detalleUsers);
						      // unitsResponseDto.setPrivileges(listasPrivelege);
				       // UserDetailsResponseDto.setPrivileges(detallePrivilege);
						      
						           return ResponseEntity.ok(entry);
					}
				} else {
					respuesta.setMsg("Sesión expirada o inválida");
					estatus = HttpStatus.UNAUTHORIZED;
					return new ResponseEntity(respuesta, estatus);
				}
			}
		} catch (Exception e) {// Error Interno
			// Manejo de excepciones
			respuesta.setMsg("Error interno del servidor");
			estatus = HttpStatus.INTERNAL_SERVER_ERROR;
			return new ResponseEntity(respuesta, estatus);
		} finally {
	        if (entityManager != null && entityManager.isOpen()) {
	            entityManager.close();
	        }
	    }

	}
	
	@DeleteMapping("/users/{userid}")
	public ResponseEntity<?> borrarUsers(HttpServletRequest request, @PathVariable("userid") final Integer userid)
			throws ParseException {
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		RoleDto detalleRoles;
		PrivilegesAllDto detallePrivilege;
		
		String var = "";
		boolean bloked = false;
		RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
		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();
		RespuestaValueDto respuestaValueDto;
		String searchIn = "";


		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.

		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus=HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {
			sessionid = sessionid.substring(7);
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);

			if (encontreSessionUsuario.isPresent()) {
				//Eliminar un registro de un usuario. (priv 633)

				String fechaComoCadena;
				   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 var2 = "";
							boolean bloked2 = false;
							RespuestaMsgDto respuestaDto2 = new RespuestaMsgDto(var2);
							//respuestaDto.setBlocked(bloked);
							respuestaDto2.setMsg("Sesión expirada o inválida"); 
							return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
						   
					    }
					    
				  Roles roles = encontreSessionUsuario.get().getRolid();
				   int idrol = roles.getId();
				   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 633);
				   
				   if (rolisvalid==0) {
					  
					   
						//boolean bloked = false;
						RespuestaMsgDto respuestaPrivDto = new RespuestaMsgDto(var);
						//respuestaDto.setBlocked(bloked);
						respuestaPrivDto.setMsg("No tiene los Privilegios"); 
						return new ResponseEntity(respuestaPrivDto, HttpStatus.FORBIDDEN);
						
				   }
				   
				
				try {
					
					if (usersRepository.existsById(userid)) {
						
						  Optional<Users> usuDelete = usersRepository.findById(userid);
						   String module = "Usuarios";
						     String Descmodule = "Se eliminó a : " + usuDelete.get().getEmail() ;
						    
					         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 = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1).concat(encontreSessionUsuario.get().getEmail().concat(singo2));
					         auditDto.setUserref(usryemail);
					         auditDto.setModule(module);
					         auditDto.setDesc(Descmodule);
					         auditDto.setCreatedat(fechaDate);
					 		   usersService.registrarAuditSesion(auditDto); 
						
						// Borro el rol boolean existeUsers = ;
						int valor = 0;
						try {
						//usersRepository.deleteusersbyid(userid,fechaDate,valor);	
						usersRepository.deleteusersbyid(userid);	
						respuestaValueDto= new RespuestaValueDto(userid);
						
						
						estatus=HttpStatus.OK;
						return new ResponseEntity(respuestaValueDto, estatus);
						} catch (Exception e) {// Error Interno
							respuesta.setMsg("Error interno del servidor -conflicto. ");
							estatus=HttpStatus.CONFLICT;
							return new ResponseEntity(respuesta, estatus);
						} 
					} else {// Registro no encontrado
						respuesta.setMsg("Registro no encontrado");
						estatus=HttpStatus.NOT_FOUND;
						return new ResponseEntity(respuesta, estatus);
						
					}

				} catch (Exception e) {// Error Interno
					// Manejo de excepciones
					respuesta.setMsg("Error interno del servidor");
					estatus=HttpStatus.INTERNAL_SERVER_ERROR;
					return new ResponseEntity(respuesta, estatus);
				} finally {
			        if (entityManager != null && entityManager.isOpen()) {
			            entityManager.close();
			        }
			    }
			} else {
				respuesta.setMsg("Sesión expirada o inválida");
				estatus=HttpStatus.UNAUTHORIZED;
				return new ResponseEntity(respuesta, estatus);
				
			}

			
		}
		
	}
	
	
	public boolean isAuthenticationSuccessful(String usuario, String password) {
		try {
			Authentication authentication=
					autheticationManager.authenticate(new UsernamePasswordAuthenticationToken(usuario,password));
			return true;
		} catch (Exception e) {
			return false;
		}
	}
	
	
}
