package com.dacrt.SBIABackend.controler;

import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URI;
import java.sql.Connection;
import java.sql.DriverManager;
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.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import javax.validation.Valid;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
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.DataIntegrityViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
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.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.dacrt.SBIABackend.dto.AppTypeDto;
import com.dacrt.SBIABackend.dto.CampaignFormat2Dto;
import com.dacrt.SBIABackend.dto.ChannelsRecordDto;
import com.dacrt.SBIABackend.dto.EnddateDto;
import com.dacrt.SBIABackend.dto.EntryRiskEvaluationsDto;
import com.dacrt.SBIABackend.dto.EntryRiskEvaluationsDto2;
import com.dacrt.SBIABackend.dto.InitialdateDto;
import com.dacrt.SBIABackend.dto.PrivilegesRiskDto;
import com.dacrt.SBIABackend.dto.RecordCatalogoResponseDto;
import com.dacrt.SBIABackend.dto.RiskFactorsElementDto;
import com.dacrt.SBIABackend.dto.RiskFactorsEntryRecordDto2;
import com.dacrt.SBIABackend.dto.RiskFactorsRecordDto;
import com.dacrt.SBIABackend.dto.RiskRecordDto;
import com.dacrt.SBIABackend.dto.ScalesDto;
import com.dacrt.SBIABackend.dto.SceneryDto2;
import com.dacrt.SBIABackend.dto.ServiceOffersDescDto;
import com.dacrt.SBIABackend.dto.StatusDto;
import com.dacrt.SBIABackend.dto.StatusDto2;
import com.dacrt.SBIABackend.dto.TypesUnitDto;
import com.dacrt.SBIABackend.dto.scalesDtoAll;
import com.dacrt.SBIABackend.dto.requestDto.ElementDto;
import com.dacrt.SBIABackend.dto.requestDto.EvalProcessesAppRequestDto;
import com.dacrt.SBIABackend.dto.requestDto.FactorDto;
import com.dacrt.SBIABackend.dto.requestDto.RiskRequestDto;
import com.dacrt.SBIABackend.dto.requestDto.SupplierRequestDto;
import com.dacrt.SBIABackend.dto.responseDto.EvalRiskResponseDto;
import com.dacrt.SBIABackend.dto.responseDto.RiskFactorsResponseDto;
import com.dacrt.SBIABackend.entity.Applications;
import com.dacrt.SBIABackend.entity.Evalprocapps;
import com.dacrt.SBIABackend.entity.Evalprocesses;
import com.dacrt.SBIABackend.entity.Instrumentriskfactors;
import com.dacrt.SBIABackend.entity.Instruments;
import com.dacrt.SBIABackend.entity.Riskevalfactorelements;
import com.dacrt.SBIABackend.entity.Riskevalfactors;
import com.dacrt.SBIABackend.entity.Riskevaluations;
import com.dacrt.SBIABackend.entity.Riskfactorelements;
import com.dacrt.SBIABackend.entity.Riskfactors;
import com.dacrt.SBIABackend.entity.Suppliers;
import com.dacrt.SBIABackend.entity.Unitprocesses;
import com.dacrt.SBIABackend.entity.Units;
import com.dacrt.SBIABackend.repository.ApplicationsRepository;
import com.dacrt.SBIABackend.repository.CampaignsRepository;
import com.dacrt.SBIABackend.repository.EvalprocappsRepository;
import com.dacrt.SBIABackend.repository.EvalprocessesRepository;
import com.dacrt.SBIABackend.repository.EvalprosuppliersRepository;
import com.dacrt.SBIABackend.repository.InstrumentriskfactorsRepository;
import com.dacrt.SBIABackend.repository.InstrumentsRepository;
import com.dacrt.SBIABackend.repository.RiskevalfactorelementsRepository;
import com.dacrt.SBIABackend.repository.RiskevalfactorsRepository;
import com.dacrt.SBIABackend.repository.RiskevaluationsRepository;
import com.dacrt.SBIABackend.repository.RiskfactorelementsRepository;
import com.dacrt.SBIABackend.repository.RiskfactorsRepository;
import com.dacrt.SBIABackend.security.dto.AuditRequestDto;
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.UsersListDto;
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.repository.AuditRepository;
import com.dacrt.SBIABackend.security.repository.ParamsRepository;
import com.dacrt.SBIABackend.security.repository.RolesPrivilegesRepository;
import com.dacrt.SBIABackend.security.repository.UsersRepository;
import com.dacrt.SBIABackend.security.service.MenuService;
import com.dacrt.SBIABackend.security.service.ParamsService;
import com.dacrt.SBIABackend.security.service.SecurityService;
import com.dacrt.SBIABackend.security.service.UsersService;
import com.dacrt.SBIABackend.utils.HttpReqRespUtils;


@RestController
@CrossOrigin(origins = "*")
public class EvalRiskController {
	
	@Autowired
	private ParamsRepository paramsRepository;
	
	@Autowired
	private UsersRepository usersRepository;
	
	@Autowired
	private AuditRepository auditRepository;
	
	@Autowired
	private EvalprosuppliersRepository evalprosuppliersRepository;
	
	@Autowired
	private RiskevaluationsRepository riskevaluationsRepository2;
	
	@Autowired
	private RolesPrivilegesRepository rolesPrivilegesRepository;
	
	@Autowired
	UsersService usersService;
	
	@Autowired
	ParamsService paramsService;
	
	@Autowired
	SecurityService securityService;
	
	@Autowired
	MenuService menuService;
	
	@Autowired
	CampaignsRepository campaignsRepository;
	
	@Autowired
	ApplicationsRepository applicationsRepository;
	
	@Autowired
	EvalprocappsRepository evalprocappsRepository;
	
	@Autowired
	InstrumentsRepository instrumentsRepository;
	
	@Autowired
	RiskfactorsRepository riskfactorsRepository;
	
	@Autowired
	RiskevaluationsRepository riskevaluationsRepository;
	
	@Autowired
	RiskevalfactorsRepository riskevalfactorsRepository;
	
	@Autowired
	RiskevalfactorelementsRepository riskevalfactorelementsRepository;
	
	@Autowired
	InstrumentriskfactorsRepository instrumentRiskFactorsRepository;
	
	@Autowired
	RiskfactorelementsRepository riskFactorElementsRepository;
	
	
	@Autowired
    private JdbcTemplate jdbcTemplate;
	
	@Value("${var.ambiente}")
	private String urlAmbiente;
	
	
	
	
	@PersistenceContext
    private EntityManager entityManager;
	
	@Autowired
	EvalprocessesRepository evalprocessesRepository;
	
	Logger logger = LoggerFactory.getLogger(EvalRiskController.class);
	
	@Transactional(rollbackOn = Exception.class) // <--- CRITICO: Habilita el rollback
	@PostMapping("/riskevaluations/{riskevaluationid}")
	public ResponseEntity<ParamsResponseDto> evalRiskUpsert(HttpServletRequest request,
			@Valid @RequestBody RiskRequestDto datosvp, @PathVariable("riskevaluationid") final Integer riskevaluationid)
			throws ParseException, SQLException {
		// @GetMapping("/vicepresidencies/{vicepresidencyid}")

		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 = riskevaluationid;

		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();
		Optional<Users> encontreSessionUsuario;
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		Statement sentenciaPreparada2 = null;
		// Connection conexion2 = DriverManager.getConnection(conexion,userbd, passbd);
		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);

				}
				
	                 String SalidaDsc = usersService.verificarCaracteresValidosConRegex(datosvp.getRelatedItemDsc());
					  
					  if (SalidaDsc=="NOOK") {
						  String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("Caracteres no permitidos en la busqueda Desc"); 
							return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
					  }
					  String mensajeestatus;
					  switch (datosvp.getStatus()) { 
					    case 1:  // Busca por cualquier estatus
					    	 mensajeestatus = "ok";
					     break;
					    case 0:  // Busca por estatus activo
					    	
					    	 mensajeestatus = "ok";
					     break;
					    
					  
					    default:	// viene con el parametro para buscar por el like		   			    				    	
					    	String var2 = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
							respuestaDto= new RespuestaMsgDto("Llamada al servicio mal Formado");
							estatus=HttpStatus.BAD_REQUEST;   
							return new ResponseEntity(respuestaDto, estatus);
					    	
			         }
					  
                
		
			if (idparametro == 0) {
				
				Optional<Riskevaluations> existingEval = riskevaluationsRepository2.findDuplicate(
				        datosvp.getInstrument(),
				        datosvp.getRelatedItemId(),
				        datosvp.getRelatedItemDsc(),
				        datosvp.getInitialDate()
				    );
				
				if (existingEval.isPresent()) {
			        RespuestaMsgDto respuestaDto = new RespuestaMsgDto("");
			        respuestaDto.setMsg("Ya existe una evaluación para este instrumento y elemento en la fecha seleccionada.");
			        return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT); // Error 409 es ideal para duplicados
			    }
					// el permiso es el 632
					Roles roles = encontreSessionUsuario.get().getRolid();
					int idrol = roles.getId();
					int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 822);
					// rolisvalid = 3;
					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, 821);
					// rolisvalid = 3;
					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);

					}

					boolean existeSup = riskevaluationsRepository.existsById(idparametro);
					

					if (!existeSup) {

						String var = "";
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						// respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Registro No encontrado");
						// Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);

					}
				}

			} else {
				String var = "";
				boolean bloked = false;
				RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
				respuestaDto.setMsg("Sesión expirada o inválida");
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

			Suppliers tiposupl2 = null;
			Riskevaluations tipoRiskEval = null;
			Riskevalfactors tipoRiskEvalFac = null;
			Riskevalfactorelements tipoEvalFactorEle = null;
			 Integer vScenery; 
			Suppliers tiposupl = null;
			String mensajeAudit="";
			String vDescEscenario = "";
			  String vDescValor;
			Suppliers tiposuplNew2 = null;
			Optional<Suppliers> nuevoinsertado = null;
			
			 if (!instrumentsRepository.existsById(datosvp.getInstrument())) {
          	   String var2 = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
					respuestaDto= new RespuestaMsgDto("Llamada al servicio malformado - el Id del Instrumento no existe");
					estatus=HttpStatus.BAD_REQUEST;   
					return new ResponseEntity(respuestaDto, estatus);
             } else {
            	 
				 Instruments vInstrument = instrumentsRepository.getById(datosvp.getInstrument());				 
				  vScenery = vInstrument.getScenery();
				 String vDescInstrumento = vInstrument.getName();
				 
				String descScenery = " SELECT  "
						+ "    elemento ->> 'dsc' AS descr,  "
						+ "    elemento ->> 'value' AS valor 	  "
						+ "FROM  "
						+ "    main.params p,  "
						+ "    jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
						+ "WHERE  "
						+ "    p.paramname = 'RISK_SCENERIES'  "
						+ "    AND " + vScenery +  "= CAST(elemento ->> 'value' AS integer);";
				
				
				Query query;
			      query = entityManager.createNativeQuery(descScenery);
				   List<Object[]> listacompleta = query.getResultList();
				  
				   for (Object[] reg : listacompleta) {	
					   vDescEscenario = ((String) reg[0]);
					   vDescValor = ((String) reg[1]);
					   
				   }
				   
				    mensajeAudit= " con id de Escenario: " + vScenery + " y descripción: " +  vDescEscenario + ", con id de instrumento: " + datosvp.getInstrument() 
				   + " y descripción: " + vDescInstrumento + ", con id de elemento: " + datosvp.getRelatedItemId()  + " y descripción: " + datosvp.getRelatedItemDsc();
             }
			

			if (idparametro == 0) {

				Suppliers tipoSuplNew = new Suppliers();
				Riskevaluations tipoRiskEvalNew = new Riskevaluations();
				 if (datosvp.getAttenuator().compareTo(BigDecimal.ZERO) < 0) {
					 String var2 = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
						respuestaDto= new RespuestaMsgDto("Llamada al servicio malformado");
						estatus=HttpStatus.BAD_REQUEST;   
						return new ResponseEntity(respuestaDto, estatus);
				 } 
				 
				 if (datosvp.getImpact().compareTo(BigDecimal.ZERO) < 0) {
					 String var2 = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
						respuestaDto= new RespuestaMsgDto("Llamada al servicio malformado");
						estatus=HttpStatus.BAD_REQUEST;   
						return new ResponseEntity(respuestaDto, estatus);
				 } 
				 
				 if (datosvp.getProbability().compareTo(BigDecimal.ZERO) < 0) {
					 String var2 = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
						respuestaDto= new RespuestaMsgDto("Llamada al servicio malformado");
						estatus=HttpStatus.BAD_REQUEST;   
						return new ResponseEntity(respuestaDto, estatus);
				 } 
                                         							
			 
				 tipoRiskEvalNew.setInstrumentid(datosvp.getInstrument());
				 tipoRiskEvalNew.setInitialdate(datosvp.getInitialDate());
				 tipoRiskEvalNew.setRelateditem(datosvp.getRelatedItemId());
				 tipoRiskEvalNew.setRelateditemdsc(datosvp.getRelatedItemDsc());
				 tipoRiskEvalNew.setStatus(datosvp.getStatus()); 
				 tipoRiskEvalNew.setProbability(datosvp.getProbability());
				 tipoRiskEvalNew.setImpact(datosvp.getImpact());
				 tipoRiskEvalNew.setAttenuator(datosvp.getAttenuator());
				 tipoRiskEvalNew.setDsc(datosvp.getDsc());
				 tipoRiskEvalNew.setScenery(vScenery);
				 tipoRiskEvalNew.setScenerydsc(vDescEscenario);
				 tipoRiskEvalNew.setCreatedat(fechaDate); 
				 tipoRiskEvalNew.setModifiedat(fechaDate);
				 if (datosvp.getStatus()==1) {
					 tipoRiskEvalNew.setEnddate(fechaDate);
				    }
								 								 						
				 Riskevaluations savedEval = riskevaluationsRepository2.save(tipoRiskEvalNew);
				 
				// --- INICIO LÓGICA AUTOMÁTICA ---
				 List<FactorDto> factoresAProcesar = datosvp.getFactors();

				 // Si el JSON no trae factores, los buscamos en las tablas maestras por el Instrumento
				 if (factoresAProcesar == null || factoresAProcesar.isEmpty()) {
				     factoresAProcesar = obtenerFactoresDesdeMaestras(datosvp.getInstrument());
				 }
				 // --- FIN LÓGICA AUTOMÁTICA ---

				 // Ahora procesamos la lista (ya sea la del JSON o la que cargamos de la BD)
				 if (factoresAProcesar != null) {
				     for (FactorDto fDto : factoresAProcesar) {
				         Riskevalfactors factor = new Riskevalfactors();
				         factor.setRiskevaluationid(savedEval.getId());
				         factor.setRiskfactorid(fDto.getId()); 
				         factor.setRiskcategory(fDto.getCategory());
				       //  factor.setWeight(fDto.getWeight().intValue());
				         factor.setWeight(fDto.getWeight());
				         factor.setRiskfactornam(fDto.getName());
				         factor.setRiskfactordsc(fDto.getDsc());
				         Riskevalfactors savedFactor = riskevalfactorsRepository.save(factor);

				         if (fDto.getElements() != null) {
				             for (ElementDto eDto : fDto.getElements()) {
				                 Riskevalfactorelements element = new Riskevalfactorelements();
				                 element.setRiskevalfactorid(savedFactor.getId());
				                 element.setRiskfactorelementid(eDto.getId());
				                 element.setRiskfactorelementdsc(eDto.getDsc());
				                 element.setProbability(eDto.getProbability());
				                 element.setImpact(eDto.getImpact());
				                 element.setWeight(eDto.getWeight());
				                 element.setActive(0); // Por defecto activo al ser carga automática
				                 
				                 riskevalfactorelementsRepository.save(element);
				             }
				         }
				     }
				 }

			
				 
			
				//int idInsertado = nuevoinsertado.get().getId();
				int idInsertado= savedEval.getId();
				int idmensaje = idInsertado;

				////////////////////////// INSERCION BLOQUE DE AUDITORIA///////////////////
				String module = "Evaluación de Riesgo";
				// String Descmodule = "Actualización de parametro del Sistema con id: " +
				// parmid ;
				String Descmodule = "Se agregó la Evaluación de Riesgo " +  " con Id:" + idInsertado  + " " + mensajeAudit;

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

				respuestaValueDto = new RespuestaValueDto(idmensaje);
				estatus = HttpStatus.OK;
				return new ResponseEntity(respuestaValueDto, estatus);
			 } else {
				// --- LÓGICA PARA MODIFICAR (UPDATE) ---
				    
				    // 1. Verificar que la evaluación de riesgo exista
				    Optional<Riskevaluations> opRiskEval = riskevaluationsRepository2.findById(idparametro);
				    int idEvalFactorInsertado;
				    if (!opRiskEval.isPresent()) {
				        return new ResponseEntity(new RespuestaMsgDto("La evaluación de riesgo no existe"), HttpStatus.NOT_FOUND);
				    }

				    Riskevaluations evalToUpdate = opRiskEval.get();

				    // 2. Validaciones de negocio (ej. valores negativos)
				    if (datosvp.getAttenuator().compareTo(BigDecimal.ZERO) < 0 || 
				        datosvp.getImpact().compareTo(BigDecimal.ZERO) < 0 || 
				        datosvp.getProbability().compareTo(BigDecimal.ZERO) < 0) {
				        return new ResponseEntity(new RespuestaMsgDto("Llamada al servicio malformado: valores negativos"), HttpStatus.BAD_REQUEST);
				    }

				    // 3. Actualizar campos de la entidad principal
				    evalToUpdate.setInstrumentid(datosvp.getInstrument());
				    evalToUpdate.setInitialdate(datosvp.getInitialDate());
				    evalToUpdate.setRelateditem(datosvp.getRelatedItemId());
				    evalToUpdate.setRelateditemdsc(datosvp.getRelatedItemDsc());
				    evalToUpdate.setStatus(datosvp.getStatus());
				    evalToUpdate.setProbability(datosvp.getProbability());
				    evalToUpdate.setImpact(datosvp.getImpact());
				    evalToUpdate.setAttenuator(datosvp.getAttenuator());
				    evalToUpdate.setScenery(vScenery);
				    evalToUpdate.setScenerydsc(vDescEscenario);
				    evalToUpdate.setDsc(datosvp.getDsc());
				    evalToUpdate.setModifiedat(fechaDate); // Fecha de modificación actual
				    if (datosvp.getStatus()==1) {
				    	evalToUpdate.setEnddate(fechaDate);
				    }
				    
				    riskevaluationsRepository2.save(evalToUpdate);

				    // 4. Gestionar Factores y Elementos
				    // Recomendación: Eliminar los existentes para evitar duplicados o huérfanos
				    // (Asegúrate de tener este método en tus repositorios o manejar la lógica de borrado)
				    
				    // Suponiendo que borramos los factores previos asociados a esta evaluación:
				    // riskevalfactorsRepository.deleteByRiskevaluationid(idparametro);

				    if (datosvp.getFactors() != null) {
				        for (FactorDto fDto : datosvp.getFactors()) {
				            // 1. Obtener o actualizar el Factor
				         //   Riskevalfactors factor = riskevalfactorsRepository.getByRiskevaluationid(idparametro);
				            //Riskevalfactors factor = riskevalfactorsRepository.getByRiskevaluationidAndRiskfactorid(idparametro,fDto.getId());
				            Riskevalfactors factor = riskevalfactorsRepository.getById(fDto.getId());
				            
				            // Si por alguna razón el factor no existe para esa evaluación, lo creamos
				            if (factor == null) {
				                factor = new Riskevalfactors();
				                factor.setRiskevaluationid(idparametro);
				            }
				            
				            factor.setWeight(fDto.getWeight());
				            factor.setRiskcategory(fDto.getCategory());
				            //factor.setWeight(fDto.getWeight().intValue());
				            Riskevalfactors savedFactor = riskevalfactorsRepository.save(factor);

				            // --- AQUÍ EL CAMBIO CRÍTICO PARA ELEMENTOS ---
				            
				            // 2. BORRADO PREVIO: Eliminamos todos los elementos actuales de este factor
				            // Asegúrate de tener este método en tu RiskevalfactorelementsRepository
				            riskevalfactorelementsRepository.deleteByRiskevalfactorid(savedFactor.getId());

				            // 3. INSERCIÓN NUEVA: Si el JSON trae elementos, los insertamos todos de cero
				            if (fDto.getElements() != null) {
				                for (ElementDto eDto : fDto.getElements()) {
				                    // Solo insertamos si vienen como activos (o según tu lógica de negocio)
				                  //  if (eDto.getActive() != 0) { 
				                        Riskevalfactorelements element = new Riskevalfactorelements();
				                        element.setRiskevalfactorid(savedFactor.getId());
				                        element.setRiskfactorelementid(eDto.getId());
				                        element.setRiskfactorelementdsc(eDto.getDsc());
				                        element.setProbability(eDto.getProbability());
				                        element.setImpact(eDto.getImpact());
				                        element.setWeight(eDto.getWeight());
				                        element.setActive(eDto.getActive());

				                        riskevalfactorelementsRepository.save(element);
				                    //}
				                }
				            }
				        }
				    }

				    // 5. Auditoría de Modificación
				    String module = "Evaluación de Riesgo";
				    String Descmodule = "Se modificó la Evaluación de Riesgo con Id: " + idparametro + ", " + mensajeAudit ;

				    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); // Usar la descripción de modificación
				    auditDto.setCreatedat(fechaDate);
				    usersService.registrarAuditSesion(auditDto);

				    return new ResponseEntity(new RespuestaValueDto(idparametro), HttpStatus.OK);
			 }
			

		} catch (DataIntegrityViolationException e) {
		    // ESTO SE DISPARA POR: Duplicados, llaves foráneas inexistentes, etc.
		    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		    
		    RespuestaMsgDto respuestaDto = new RespuestaMsgDto("Error de integridad: El registro ya existe o datos relacionados son inválidos.");
		    return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT); // HTTP 409

		} catch (Exception e) {
		    // ERROR GENÉRICO (500)
		    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		    
		    RespuestaMsgDto respuestaDto = new RespuestaMsgDto("Error interno: " + e.getMessage());
		    return new ResponseEntity(respuestaDto, HttpStatus.INTERNAL_SERVER_ERROR);
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}

		//return new ResponseEntity(respuesta, estatus);

	}

	
	@Transactional(rollbackOn = Exception.class) // <--- CRITICO: Habilita el rollback
	@PostMapping("/riskevaluations/attupdate/{riskevaluationid}")
	public ResponseEntity<ParamsResponseDto> evalRiskUpsertAtt(HttpServletRequest request,
			@Valid @RequestBody RiskRequestDto datosvp, @PathVariable("riskevaluationid") final Integer riskevaluationid)
			throws ParseException, SQLException {
		// @GetMapping("/vicepresidencies/{vicepresidencyid}")

		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 = riskevaluationid;

		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();
		Optional<Users> encontreSessionUsuario;
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		Statement sentenciaPreparada2 = null;
		// Connection conexion2 = DriverManager.getConnection(conexion,userbd, passbd);
		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);

				}
				       

					Roles roles = encontreSessionUsuario.get().getRolid();
					int idrol = roles.getId();
					int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 821);
					int rolisvalid2 = auditRepository.getCantbyRolAndPrivi(idrol, 825);
					int rolisvalid3 = auditRepository.getCantbyRolAndPrivi(idrol, 826);
					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);

					}
					if (rolisvalid2 == 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);

					}
					if (rolisvalid3 == 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);

					}

					boolean existeSup = riskevaluationsRepository.existsById(idparametro);
					

					if (!existeSup) {

						String var = "";
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						// respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Registro No encontrado-No existe la evaluación");
						// Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);

					}
				

			} else {
				String var = "";
				boolean bloked = false;
				RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
				respuestaDto.setMsg("Sesión expirada o inválida");
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

		
			Riskevaluations tipoRiskEval = null;
			Riskevalfactors tipoRiskEvalFac = null;
			Riskevalfactorelements tipoEvalFactorEle = null;
			Integer vScenery; 
			 
			Suppliers tiposuplNew2 = null;
			Optional<Suppliers> nuevoinsertado = null;
			
 {
				// --- LÓGICA PARA MODIFICAR (UPDATE) ---
				    
				    // 1. Verificar que la evaluación de riesgo exista
				    Optional<Riskevaluations> opRiskEval = riskevaluationsRepository2.findById(idparametro);
				    int idEvalFactorInsertado;
				   
				    Riskevaluations evalToUpdate = opRiskEval.get();

				    // 2. Validaciones de negocio (ej. valores negativos)
				  /*  if (datosvp.getAttenuator().compareTo(BigDecimal.ZERO) < 0 || 
				        datosvp.getImpact().compareTo(BigDecimal.ZERO) < 0 || 
				        datosvp.getProbability().compareTo(BigDecimal.ZERO) < 0) {
				        return new ResponseEntity(new RespuestaMsgDto("Llamada al servicio malformado: valores negativos"), HttpStatus.BAD_REQUEST);
				    }*/

				  
				    evalToUpdate.setAttenuator(datosvp.getAttenuator());
				  
				    
				    riskevaluationsRepository2.save(evalToUpdate);

				    // 4. Gestionar Factores y Elementos
				    // Recomendación: Eliminar los existentes para evitar duplicados o huérfanos
				    // (Asegúrate de tener este método en tus repositorios o manejar la lógica de borrado)
				    
				    // Suponiendo que borramos los factores previos asociados a esta evaluación:
				    // riskevalfactorsRepository.deleteByRiskevaluationid(idparametro);


				    // 5. Auditoría de Modificación
				    String module = "Actualización de Atenuación";
				    String Descmodule = "Se modificó la Atenuación a "  + datosvp.getAttenuator() +  " de la Evaluación de Riesgo con Id: " + idparametro;

				    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); // Usar la descripción de modificación
				    auditDto.setCreatedat(fechaDate);
				    usersService.registrarAuditSesion(auditDto);

				    return new ResponseEntity(new RespuestaValueDto(idparametro), HttpStatus.OK);
			 }
			

		} catch (DataIntegrityViolationException e) {
		    // ESTO SE DISPARA POR: Duplicados, llaves foráneas inexistentes, etc.
		    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		    
		    RespuestaMsgDto respuestaDto = new RespuestaMsgDto("Error de integridad: El registro ya existe o datos relacionados son inválidos.");
		    return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT); // HTTP 409

		} catch (Exception e) {
		    // ERROR GENÉRICO (500)
		    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		    
		    RespuestaMsgDto respuestaDto = new RespuestaMsgDto("Error interno: " + e.getMessage());
		    return new ResponseEntity(respuestaDto, HttpStatus.INTERNAL_SERVER_ERROR);
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}


	}

	private List<FactorDto> obtenerFactoresDesdeMaestras(Integer instrumentId) {
	    List<FactorDto> listaFactores = new ArrayList<>();
	    
	    // 1. Buscamos los factores vinculados al instrumento
	    List<Instrumentriskfactors> relaciones = instrumentRiskFactorsRepository.findByInstrumentid(instrumentId);

	    for (Instrumentriskfactors rel : relaciones) {
	        FactorDto fDto = new FactorDto();
	        
	        // --- CAMBIO: Buscamos la entidad maestra del factor para obtener nombre y descripción ---
	        Optional<Riskfactors> opRf = riskfactorsRepository.findById(rel.getRiskfactorid());
	        
	        if (opRf.isPresent()) {
	            Riskfactors rf = opRf.get();
	            
	            fDto.setId(rf.getId());
	            fDto.setName(rf.getName()); // <-- ASIGNAMOS EL NOMBRE
	            fDto.setDsc(rf.getDsc());   // <-- ASIGNAMOS LA DESCRIPCIÓN
	            fDto.setWeight(rel.getWeight()); // El peso se mantiene de la tabla relacional (específico del instrumento)
	            
	            // 2. Buscamos los elementos de ese factor
	            List<ElementDto> listaElementos = new ArrayList<>();
	            List<Riskfactorelements> elementosBase = riskFactorElementsRepository.findByRiskfactorid(rf);
	            
	            for (Riskfactorelements eb : elementosBase) {
	                ElementDto eDto = new ElementDto();
	                eDto.setId(eb.getId());
	                eDto.setDsc(eb.getName()); 
	                eDto.setWeight(eb.getWeight());
	                eDto.setProbability(BigDecimal.ZERO); 
	                eDto.setImpact(BigDecimal.ZERO);
	                eDto.setActive(1);
	                listaElementos.add(eDto);
	            }
	            
	            fDto.setElements(listaElementos);
	            listaFactores.add(fDto);
	        }
	    }
	    
	    return listaFactores;
	}
	
	
	@PostMapping("/riskevaluations")
	public ResponseEntity<?> lisriskevaluations(HttpServletRequest request,HttpServletResponse response,@RequestBody UsersListDto tiposfiltros) throws ParseException, UnsupportedEncodingException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
	//	ParamsDto detalleParams;
		RiskRecordDto detalleRiskRecordDto;
		List<RiskRecordDto> listasRiskRecordDto= new ArrayList<>();
		
		
		RiskFactorsElementDto detalleRiskFactorsElementDto;
		List<RiskFactorsElementDto> listasRiskFactorsElementDto= new ArrayList<>();
		
		PrivilegesRiskDto detallePrivilege;
		RiskFactorsRecordDto detalleRiskFactorsRecordDto;
		List<RiskFactorsRecordDto> listasRiskFactorsRecordDto= new ArrayList<>();
		EvalRiskResponseDto riskFactorsResponseDto = new EvalRiskResponseDto();
		 
		StatusDto2 detalleStatus;
		StatusDto2 detalleType;
		StatusDto2 detalleScenery;
		StatusDto detalleStatus2;
		StatusDto2 detalleElement;
		StatusDto2 detalleInstrument;
		
		StatusDto2 detallecapacityperiod;
		ServiceOffersDescDto detalleserviceoffers;
		RiskFactorsElementDto detalleElements;
		List<TypesUnitDto> listasTypes = new ArrayList<>();
			     
	     Long cuantosregistro = (long) 0;
	     
	     List<PrivilegesRiskDto> listasPrivelege = new ArrayList<>();
	     List<RiskFactorsRecordDto> listasRecordRisk= new ArrayList<>();
	     
	     TypesUnitDto detalleTypes;
	     TypesUnitDto detallePeriodos;
	     List<TypesUnitDto> listasPeriodos = 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();
	       	     
	      int idrol;
	   	  String searchIn = "";
	   	  String contentIn = "";
	     // String searchModule = "";
		  int searchStatus = 0;
		  int typeIn=0;
		  String fechaComoCadena; 
		 int orderIn = 0;
		 int offsetIn = 0;
		 int numofrecordsIn = 0;
		 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(); 

					   fechaComoCadena  = securityService.consultarSessionActiva(FechaReg,fecha2,encontreSessionUsuario.get().getId());
           
					    if (fechaComoCadena=="") {
						   
						   
						   
						   String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							respuestaDto.setMsg("Sesión expirada o inválida"); 
							return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
						   
					    }
					    
					    
					  // Este proceso permite obtener un listado de los proveedores. (Priv 440)
					   Roles roles = encontreSessionUsuario.get().getRolid();
					   idrol = roles.getId();
					   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 820);
					
					  // if (!mostraTodo) {
					        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());
						   searchStatus = tiposfiltros.getFilters().getStatus();
					
						  orderIn = tiposfiltros.getOrder();
						  offsetIn = tiposfiltros.getOffset();
						  numofrecordsIn = tiposfiltros.getNumofrecords();
						  contentIn = tiposfiltros.getContent();
						  
						  
						  try {
							  typeIn= tiposfiltros.getFilters().getSceneryid();
								 if (typeIn==0) {
									  typeIn = 0;
								  }
								  
							  }  catch (Exception e) { 
								  
								  typeIn = 0;
								  
							  }
							
						  
						  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;
		
		
			
			SentenciaBase = " SELECT  re.id, it.id as idisntrumento, it.name,re.scenery, re.scenerydsc AS scenery_name, "
					+ "							 re.status,  CASE WHEN re.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatus, "
					+ "							 re.probability,re.impact,re.attenuator ,re.dsc,re.relateditem,re.relateditemdsc, "
					+ "	(re.probability * re.impact * re.attenuator) AS severidad "
					+ "							 FROM main.riskevaluations re "
					+ "							 LEFT JOIN main.instruments it  on it.id = re.instrumentid ";
			
				Query query;
				 String QueryTotal;
			
			String name = "it.name ";
			String status = "re.status ";				
			String lowernameInst = "main.sinacentos(LOWER(it.name)) ";
			String lowerelemento = "main.sinacentos(LOWER(re.relateditemdsc)) ";
			String lowerdscParams = "main.sinacentos(LOWER(re.scenerydsc)) ";
			String LowerSearch = searchIn.toLowerCase();
			
			 switch (searchIn) { 
			    case "":  
			    	
			    	QueryTotal = SentenciaBase  + " WHERE TRUE = TRUE";
			     break;
			  
			    default:	  
			         	    QueryTotal = SentenciaBase + " WHERE (" + lowernameInst + " LIKE  " + "'%" + LowerSearch + "%'"  + " OR " +  lowerelemento + " LIKE " + "'%" + LowerSearch + "%' " + " OR " + lowerdscParams + " LIKE " + "'%" + LowerSearch + "%')";
			    	
			    	
	         }
			 
			 switch (searchStatus) { 
			    case 0:  // Busca por cualquier estatus
			    	QueryTotal = QueryTotal;
			     break;
			    case 1:  // Busca por estatus activo
			    	
			    	QueryTotal = QueryTotal  + " AND " + status + " = " + searchStatus;
			     break;
			    case 2:  // Busca por estatus Inactivo
			    	
			    	QueryTotal = QueryTotal  + " AND " + status + " <> " + 1;
			     break;
			  
			    default:	// viene con el parametro para buscar por el like		   			    				    	
			    	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);
			    	
	         }
			 
				 
			    switch (typeIn) { 
			    case 0: 
			      	QueryTotal = QueryTotal;
			     break;
			    case 1: 
			    	
			    	QueryTotal = QueryTotal  + " AND " + " re.scenery " + " = " + typeIn;
			     break;
			    case 2: 
			    	
			    	QueryTotal = QueryTotal  + " AND " + " re.scenery " + " = " + typeIn;
			     break;
			     
                 case 3:  
			    	
			    	QueryTotal = QueryTotal  + " AND " +  " re.scenery " + " = " + typeIn;
			     break;
                 case 4:  
 			    	
 			    	QueryTotal = QueryTotal  + " AND " +  " re.scenery " + " = " + typeIn;
 			     break;
                 case 5:  
 			    	
 			    	QueryTotal = QueryTotal  + " AND " +  " re.scenery " + " = " + typeIn;
 			     break;
			    default:	// viene con el parametro para buscar por el like		   			    				    	
			    	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);
			    	
	         }
		     
		
		    //  QueryTotal = QueryTotal + groupby;
		      query = entityManager.createNativeQuery(QueryTotal);	  			            	        
			    	     			 			 			
			 
			 String ordena="";
			  if (orderIn == 1 || orderIn == 2 || orderIn == 3 || orderIn == 4 || orderIn == 5 || orderIn == 6 || orderIn == 7 || orderIn == 8 || orderIn == 99) {
				  ordena = " ASC";
			 }  else if (orderIn == -1 || orderIn == -2 || orderIn == -3 || orderIn == -4 || orderIn == -5 || orderIn == -6 || orderIn == -7 || orderIn == -8 || orderIn == -99) {
				  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 name ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + " re.scenerydsc " + ordena + ", " + name + ordena  ;
			     break;
			    case 2://ordena por status ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + name + ordena;
			     break;	
                case 3:  //ordena por name ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + " re.relateditemdsc " + ordena;
			     break;
                case 4:  //ordena por name ascendente
 	
 	             QueryTotal = QueryTotal + " ORDER BY " + " re.probability " + ordena;
                 break;
                case 5:  //ordena por name ascendente
                 	
    	             QueryTotal = QueryTotal + " ORDER BY "   + " re.impact " + ordena;
                    break;
                case 6:  //ordena por name ascendente
                 	
   	             QueryTotal = QueryTotal + " ORDER BY "   + " severidad" + ordena;
                   break;
                case 7:  //ordena por name ascendente
                 	
   	             QueryTotal = QueryTotal + " ORDER BY "   + " re.attenuator " + ordena;
                   break;
                case 8:  //ordena por name ascendente
                 	
      	             QueryTotal = QueryTotal + " ORDER BY "   + " re.status " + ordena;
                      break;    
                case 99:   //ordena por status ascendente
                	
                    QueryTotal = QueryTotal + " ORDER BY " + " re.id " + ordena;
                break; 
			 
			    
			   }
	  
	
	   
				       query = entityManager.createNativeQuery(QueryTotal);
				       cuantosregistro = (long) query.getResultList().size();	
				       query.setFirstResult(offsetIn);
					   query.setMaxResults(numofrecordsIn);
					   List<Object[]> listacompleta = query.getResultList();
				
			   
		    	   listasRiskRecordDto= new ArrayList<>();
		    		 for (Object[] reg : listacompleta) {	  
		    				//RiskRecordDto detalleRiskRecordDto;
		    				
		    		  detalleRiskRecordDto = new RiskRecordDto(); 			 
		    		   detalleStatus = new StatusDto2();
		    		   detalleScenery = new StatusDto2();
		    		   detalleInstrument= new StatusDto2();
		    		   detalleElement= new StatusDto2();
		    		   
		    		
		    		   ///////////////////////llenando el scenery//////////////////
		    		 //  detalleScenery.setId((int) reg[3]);
		    		   detalleRiskRecordDto.setId((int) reg[0]);
		    		   ///seteando el instrumento/////
		    		   detalleInstrument.setId((int) reg[1]);
		    		   detalleInstrument.setName((String) reg[2]);
		    		   
		    		   detalleRiskRecordDto.setInstrument(detalleInstrument);
		    		   ///seteando el scenery/////
		    		   detalleScenery.setId((int) reg[3]);
		    		   detalleScenery.setName((String) reg[4]);
		    		   detalleRiskRecordDto.setScenery(detalleScenery);
		    		   ///////////////////////////////////////////////////////
		    		   /////seteando el elemento//////////////
		    		   detalleElement.setId((int) reg[11]);
		    		   detalleElement.setName((String) reg[12]);
		    		   detalleRiskRecordDto.setElement(detalleElement);
		    		   ////////////////////////////
		    		   
		    		   /////////////////////llenando el estatus//////////////////////
		    		   detalleStatus.setId((int) reg[5]);
			    	   detalleStatus.setName((String) reg[6]);			    	   			    	   				 
			    	   detalleRiskRecordDto.setStatus(detalleStatus);
		    		 
		    		  ////////////seteando los valores restantes//////////
			    	   
			    	   detalleRiskRecordDto.setProbability((BigDecimal) reg[7]);
			    	   detalleRiskRecordDto.setImpact((BigDecimal) reg[8]);
			    	   detalleRiskRecordDto.setAttenuator((BigDecimal) reg[9]);
			    	   detalleRiskRecordDto.setDsc((String) reg[10]);
			    	   ////////////////////////////////////////////
			    	   
			    	   listasRiskRecordDto.add(detalleRiskRecordDto);
			    		
		    	   }
		    	
		    	   
      	    	 	detallePrivilege = new PrivilegesRiskDto();
      	    	       boolean tieneView = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,820);
					   boolean tieneUpdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,821);
					   boolean tieneAdd = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,822);
					   boolean tieneDelete = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,823);
					   boolean tieneUpdatt = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,825);
					   //existsByRolidAndPrivilegeid
					   
	      	    	 	detallePrivilege.setView(tieneView);
			    	  	detallePrivilege.setUpdate(tieneUpdate);		    	  
			    	  	detallePrivilege.setAdd(tieneAdd);
			    	  	detallePrivilege.setDelete(tieneDelete);
			    	  	detallePrivilege.setUpdatt(tieneUpdatt);
			    	  	
			    	  	 String SetenciaSceneries="";
							
			    	  	SetenciaSceneries= "SELECT  elemento ->> 'dsc' AS descr,elemento ->> 'value' AS valor "
					 		+ " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento WHERE paramname = 'RISK_SCENERIES' ORDER BY valor ASC";
					      
					      Query queryTypes = entityManager.createNativeQuery(SetenciaSceneries);
					       List<Object[]> listasceneries= queryTypes.getResultList();
					       for (Object[] types : listasceneries) {
					    	   detalleTypes = new TypesUnitDto();
					    	  
					    	   detalleTypes.setDsc((String) types[0]);
					    	   detalleTypes.setValue((String) types[1]);
					    	   listasTypes.add(detalleTypes);
					       }
		    	          
					       riskFactorsResponseDto.setNumofrecords(cuantosregistro); 
					       riskFactorsResponseDto.setSessionvalidthru(fechaComoCadena);
					       riskFactorsResponseDto.setRecords(listasRiskRecordDto);
					       riskFactorsResponseDto.setPrivileges(detallePrivilege);
					       riskFactorsResponseDto.setSceneries(listasTypes);
		    	   	    	   			
		  						           
                return ResponseEntity.ok(riskFactorsResponseDto);
		     						
			 
	
	
		} 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("/riskevaluations/{riskevaluationid}")
	public ResponseEntity<?> obtenerunoriskevaluation(HttpServletRequest request,
			@PathVariable("riskevaluationid") final Integer riskevaluationid)
			throws ParseException, UnsupportedEncodingException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;

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

		int idrol;
		String fechaComoCadena;
		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();
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

				if (fechaComoCadena == "") {
					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					respuestaDto.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
				}

				// Este proceso permite obtener un listado de los proveedores. (Priv 440)
				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 820);

				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 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 {

			Optional<Riskevaluations> riskevaluations = riskevaluationsRepository.findById(riskevaluationid);

			// Verifico si encontre la aplicación
			if (!riskevaluations.isPresent()) {
				respuesta.setMsg("Registro no encontrado");
				return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
			}
			
			String SentenciaBase;
		
			SentenciaBase = "SELECT  re.id,         "
					+ "					 		it.id as idisntrumento,       "
					+ "					 		it.name,       "
					+ "					 		re.scenery,     "
					+ "					 		re.scenerydsc,      "
					+ "					 		re.relateditem,       "
					+ "					 		re.dsc,       "
					+ "					 		re.initialdate,       "
					+ "					 		re.enddate,         "
					+ "					 		re.status,         "
					+ "					 		CASE WHEN re.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatus,         "
					+ "					 		cast(re.probability as decimal(19,3)) as prob,         "
					+ "					 		cast(re.impact as decimal(19,3)),      "
					+ "					 		cast(re.attenuator as decimal(19,3)),       "
					+ "					 		re.relateditemdsc,       "
					+ "					 		STRING_AGG(COALESCE(CAST(rf.id AS TEXT), '0'), ',' ORDER BY rf.id) AS factores_id,      "
					+ "					 		STRING_AGG(COALESCE(CAST(rf.riskfactornam AS TEXT), '0'), ',' ORDER BY rf.id) AS factores_nombres,      "
					+ "					 		STRING_AGG(COALESCE(CAST(rf.riskfactordsc AS TEXT), '0'), ',' ORDER BY rf.id) AS factores_dsc,      "
					+ "					 		STRING_AGG(COALESCE(CAST(rf.weight AS TEXT), '0'), ',' ORDER BY rf.id) AS factores_weight,    "
					+ "					 		STRING_AGG(  "
					+ "					         (  "
					+ "					             SELECT STRING_AGG(  "
					+ "					                 rfe.riskfactorelementid || ':' ||   "
					+ "					                 rfe.riskfactorelementdsc || ':' ||   "
					+ "					                 TRIM(TO_CHAR(rfe.probability, '999990.000')) || ':' ||   "
					+ "					                 TRIM(TO_CHAR(rfe.impact, '999990.000')) || ':' ||   "
					+ "					                 rfe.active || ':' ||   "
					+ "					                 rfe.weight,   "
					+ "					                 '|' ORDER BY rfe.riskfactorelementid   "
					+ "					             )  "
					+ "					             FROM main.riskevalfactorelements rfe   "
					+ "					             WHERE rfe.riskevalfactorid = rf.id  "
					+ "					         ),  "
					+ "					         ';' ORDER BY rf.id   "
					+ "					     ) AS elementos_por_factor   "
					+ "					 					 			FROM main.riskevaluations re    	       "
					+ "					 					 			INNER JOIN main.riskevalfactors rf ON rf.riskevaluationid = re.id     "
					+ "					 					 			INNER JOIN main.instruments it  on it.id = re.instrumentid        "
					+ "					 					 			     "
					+ "					 					 					   			       "
					+ "					 					 			WHERE re.id = :riskevaluationid  "
					+ "					 					 			GROUP BY     "
					+ "					 					 		    re.id, it.id, it.name, re.scenery, re.relateditem, re.dsc,     "
					+ "					 					 		    re.scenerydsc, re.initialdate, re.enddate, re.status,     "
					+ "					 					 		    re.probability, re.impact, re.attenuator, re.relateditemdsc " ; 
			
			Query query;
			String QueryTotal;
			EntryRiskEvaluationsDto2 entry = new EntryRiskEvaluationsDto2();
			
			SceneryDto2 sceneri = new SceneryDto2();
			ScalesDto scale = new ScalesDto();
			List<SceneryDto2> sceneries = new ArrayList<>();
			List<ScalesDto> scales = new ArrayList<>();
			List<ScalesDto> scalespro = new ArrayList<>();
			StatusDto2 instrument = new StatusDto2();
			StatusDto2 scenery= new StatusDto2();
			StatusDto2 scenery2= new StatusDto2();
			StatusDto2 element= new StatusDto2();
			InitialdateDto initialdate= new InitialdateDto();
			EnddateDto enddate= new EnddateDto();
			StatusDto2 status = new StatusDto2();
			Integer probability;
			Integer impact;
			Integer attenuator;
			String dsc ="";
			RiskFactorsEntryRecordDto2 riskFactorsEntryRecordDto2 = new RiskFactorsEntryRecordDto2();
			List<RiskFactorsEntryRecordDto2>  riskfactors = new ArrayList<>();
			EntryRiskEvaluationsDto entryRiskEvaluationsDto = new EntryRiskEvaluationsDto();
			
			query = entityManager.createNativeQuery(SentenciaBase);
			query.setParameter("riskevaluationid", riskevaluationid);
			List<Object[]> listacompleta = query.getResultList();

			for (Object[] reg : listacompleta) {
			    EntryRiskEvaluationsDto2 entryLocal = new EntryRiskEvaluationsDto2();
			    StatusDto2 instDto = new StatusDto2();
			    StatusDto2 scenDto = new StatusDto2();
			    StatusDto2 elemDto = new StatusDto2();
			    StatusDto2 statDto = new StatusDto2();

			 
			    entryLocal.setId(((Number) reg[0]).intValue());

			    
			    instDto.setId(((Number) reg[1]).intValue());
			    instDto.setName(String.valueOf(reg[2]));
			    entryLocal.setInstrument(instDto);

		
			    scenDto.setId(((Number) reg[3]).intValue());
			    scenDto.setName(String.valueOf(reg[4]));
			    entryLocal.setScenery(scenDto);

			
			    elemDto.setId(((Number) reg[5]).intValue());
			    elemDto.setName(String.valueOf(reg[6]));
			    entryLocal.setElement(elemDto);

			 // --- PROCESAMIENTO DE FECHAS ---
			    SimpleDateFormat sdfIso = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
			    SimpleDateFormat sdfFormatted = new SimpleDateFormat("dd/MM/yyyy hh:mma", Locale.US);
			    
			   
			    if (reg[7] != null) {
			        Date d1 = (Date) reg[7];
			        InitialdateDto initDto = new InitialdateDto();
			        initDto.setDate(sdfIso.format(d1)); 
			        String formattedDate = sdfFormatted.format(d1)
	                        .toLowerCase()
	                        .replace(".", "")
	                        .replace(" ", "");
			        String finalString = formattedDate.substring(0, 10) + " " + formattedDate.substring(10);
			        initDto.setFormatted(finalString); // 
			        entryLocal.setInitialdate(initDto);
			    }

			
			    if (reg[8] != null) {
			        Date d2 = (Date) reg[8];
			        EnddateDto endDto = new EnddateDto();
			        
			        endDto.setDate(sdfIso.format(d2)); 
			        String formattedDate = sdfFormatted.format(d2)
	                        .toLowerCase()
	                        .replace(".", "")
	                        .replace(" ", "");
			        String finalString = formattedDate.substring(0, 10) + " " + formattedDate.substring(10);
			        endDto.setFormatted(finalString);
			        entryLocal.setEnddate(endDto);
			    }
			    boolean allowopen=true;
			    statDto.setId((Integer)reg[9]);
			    statDto.setName((String)reg[10]);
			    entryLocal.setStatus(statDto);
			    entryLocal.setProbability(reg[11] != null ? new BigDecimal(reg[11].toString()) : BigDecimal.ZERO);
			    entryLocal.setImpact(reg[12] != null ? new BigDecimal(reg[12].toString()) : BigDecimal.ZERO);
			    entryLocal.setAttenuator(reg[13] != null ? new BigDecimal(reg[13].toString()) : BigDecimal.ZERO);
			   
			    ///////trabajando la fecha para el permiso especial de editar la evaluacion luego de cerrada///////
			    if (reg[8] != null) {
			        // 1. Convertimos el Date antiguo a LocalDate de Java 8
			        java.util.Date d1Old = (java.util.Date) reg[8];
			        java.time.LocalDate d1 = d1Old.toInstant()
			                                      .atZone(java.time.ZoneId.systemDefault())
			                                      .toLocalDate();

			        // 2. Obtenemos el límite del repositorio
			        String valorparams = "RISK_EVALOPENLIMIT";
			        Optional<Params> paramDate = paramsRepository.findByParamname(valorparams);
			        
			        if (paramDate.isPresent()) {
			            int limite = Integer.parseInt(paramDate.get().getValue());

			            // 3. Sumamos los días
			            java.time.LocalDate fechaFinal = d1.plusDays(limite);

			            // 4. Obtenemos la fecha de hoy
			            java.time.LocalDate hoy = java.time.LocalDate.now();

			            // Aquí es donde comparamos...
			            //allowopen
			            allowopen  = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,824);
			            if (allowopen) {
			            	allowopen = true;
			            } else {
			            	     if (fechaFinal.isBefore(hoy) || fechaFinal.isEqual(hoy)) {
			            	       allowopen = true;
			            	     } else {
			            	       allowopen = false;
			            	    }
			            }
			        }
			    } else {
			    	 allowopen  = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,824);
			    }
			 
			 
			     
			    boolean allowtotalupdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,826);
			    entryLocal.setAllowopen(allowopen);
			    entryLocal.setAllowtotalupdate(allowtotalupdate);
		
			    entryLocal.setDsc(reg[6] != null ? reg[6].toString() : "");

			 // --- PROCESAMIENTO DE FACTORES (SEGURIDAD AÑADIDA) ---
			    List<RiskFactorsEntryRecordDto2> listaF = new ArrayList<>();

			    try {
			   // if (reg[15] != null && !reg[15].toString().equals("0") && !reg[15].toString().isEmpty()) {
			        
			    	String[] idsF = reg[15].toString().split(",");
			    	String[] nomF = (reg[16] != null) ? reg[16].toString().split(",") : new String[0];
			    	String[] dscF = (reg[17] != null) ? reg[17].toString().split(",") : new String[0];
			    	String[] peso = (reg[18] != null) ? reg[18].toString().split(",") : new String[0];
			    	// El campo elementos_por_factor es el 19
			    	String elementosRaw = (reg[19] != null) ? reg[19].toString() : "SIN_ELEMENTOS";
			        String[] rawE = elementosRaw.split(";");

			        for (int i = 0; i < idsF.length; i++) {
			                if (idsF[i].trim().isEmpty() || idsF[i].trim().equals("0")) continue;

			            RiskFactorsEntryRecordDto2 rf = new RiskFactorsEntryRecordDto2();
			            rf.setId(Integer.parseInt(idsF[i].trim()));
			            rf.setName(nomF.length > i ? nomF[i] : "");
			            rf.setDsc(dscF.length > i ? dscF[i] : "");
			            rf.setWeight(new BigDecimal(peso[i]));
			            StatusDto2 sF = new StatusDto2();

			                // --- ELEMENTOS (CORRECCIÓN CRÍTICA AQUÍ) ---
			            List<RiskFactorsElementDto> listaE = new ArrayList<>();
			                if (i < rawE.length && !rawE[i].equals("SIN_ELEMENTOS") && !rawE[i].isEmpty()) {
			                    // EL ESCAPE \\| ES OBLIGATORIO
			                String[] items = rawE[i].split("\\|");
			                for (String it : items) {
			                    String[] p = it.split(":");
			                        // DEBE SER >= 6 PORQUE ACCEDES HASTA P[5]
			                        if (p.length >= 6) { 
			                            try {
			                        RiskFactorsElementDto e = new RiskFactorsElementDto();
			                        e.setId(Integer.parseInt(p[0]));
			                        e.setName(p[1]);
			                        e.setProbability(new BigDecimal(p[2]));
			                        e.setImpact(new BigDecimal(p[3]));
			                        e.setActive(new BigDecimal(p[4]));
			                        e.setWeight(new BigDecimal(p[5]));
			                        listaE.add(e);
			                            } catch (Exception ex) {
			                                System.err.println("Error parseando elemento: " + it);
			                            }
			                    }
			                }
			            }
			            rf.setElements(listaE);
			            listaF.add(rf);
			        }
			        
			    } catch (Exception e) {
			        System.err.println("Error general en factores: " + e.getMessage());
			        e.printStackTrace();
			    }

			    entryLocal.setRiskfactors(listaF);
			    entryRiskEvaluationsDto.setEntry(entryLocal);
			}

			String SetenciaSceneries = "";
			SetenciaSceneries = " SELECT  elemento ->> 'dsc' AS descr,elemento ->> 'value' AS valor "
					          + " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
					          + " WHERE paramname = 'RISK_SCENERIES' ORDER BY valor ASC ";

			Query queryTypes = entityManager.createNativeQuery(SetenciaSceneries);
			List<Object[]> listasceneries = queryTypes.getResultList();
			SceneryDto2 scene;
			for (Object[] secener : listasceneries) {
				scene = new SceneryDto2();
				scene.setDsc(secener[0] != null ? secener[0].toString() : "");
				scene.setValue(secener[1] != null ? secener[1].toString() : "");
				sceneries.add(scene);
			}

			//scalesDtoAll detalleImpact;
			scalesDtoAll detalleImpact = new scalesDtoAll();
			String SetenciascalesImpact = "";
			/*Setenciascales =  " SELECT elemento ->> 'dsc' AS descr,"
					          + "      elemento ->> 'value' AS valor,"
					          + "      elemento ->> 'filter' AS lng "
					          + " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
					          + " WHERE paramname = 'RISK_SCALE' ORDER BY valor ASC ";*/
			SetenciascalesImpact =  " SELECT elemento ->> 'dsc' AS descr,"
			          + "      elemento ->> 'value' AS valor,"
			          + "      elemento ->> 'filter' AS lng "
			          + " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
			          + " WHERE paramname = 'RISK_SCALEIMPACT' ORDER BY valor ASC ";
			          
			Query queryScales = entityManager.createNativeQuery(SetenciascalesImpact);
			List<Object[]> listascales = queryScales.getResultList();
			ScalesDto scal;
			ScalesDto scal2;
			for (Object[] scales2 : listascales) {
				scal = new ScalesDto();
				scal.setDsc(scales2[0] != null ? scales2[0].toString() : "");
			    scal.setValue(scales2[1] != null ? scales2[1].toString() : "");
			    scal.setLng(scales2[2] != null ? scales2[2].toString() : ""); 
			    scales.add(scal);
			}
			
			detalleImpact.setImpact(scales);
			
			String SetenciascalesProb = "";
			/*Setenciascales =  " SELECT elemento ->> 'dsc' AS descr,"
					          + "      elemento ->> 'value' AS valor,"
					          + "      elemento ->> 'filter' AS lng "
					          + " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
					          + " WHERE paramname = 'RISK_SCALE' ORDER BY valor ASC ";*/
			SetenciascalesProb =  " SELECT elemento ->> 'dsc' AS descr,"
			          + "      elemento ->> 'value' AS valor,"
			          + "      elemento ->> 'filter' AS lng "
			          + " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
			          + " WHERE paramname = 'RISK_SCALEPROB' ORDER BY valor ASC ";
			          
			Query querySetenciascalesProb = entityManager.createNativeQuery(SetenciascalesProb);
			List<Object[]> listaProb= querySetenciascalesProb.getResultList();
			ScalesDto pro;
			for (Object[] scales2 : listaProb) {
				scal2 = new ScalesDto();
				scal2.setDsc(scales2[0] != null ? scales2[0].toString() : "");
				scal2.setValue(scales2[1] != null ? scales2[1].toString() : "");
				scal2.setLng(scales2[2] != null ? scales2[2].toString() : ""); 
				scalespro.add(scal2);
			}
			detalleImpact.setProbability(scalespro);
			
			entryRiskEvaluationsDto.setSceneries(sceneries);
			entryRiskEvaluationsDto.setScales(detalleImpact);
            System.out.println("llegue");
			return ResponseEntity.ok(entryRiskEvaluationsDto);

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

	}


	
	
	@DeleteMapping("/riskevaluations/{riskevaluationid}")
	@Transactional
	public ResponseEntity<?> eliminarriskevaluation(HttpServletRequest request,
			@PathVariable("riskevaluationid") final Integer riskevaluationid)
			throws ParseException, UnsupportedEncodingException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		RespuestaValueDto respuestaValueDto;
		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 module = "";
		String Descmodule = "";
		Optional<Users> encontreSessionUsuario;
		
		Date fecha3 = new Date();
		SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata2 = formatter.format(fecha3);
		Date fechaDate2 = formatter.parse(dataFormattata2);
		
		int idrol;
		String fechaComoCadena;
		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);
			encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) {
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

				if (fechaComoCadena == "") {
					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					respuestaDto.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
				}

				// Este proceso permite obtener un listado de los proveedores. (Priv 440)
				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 823);

				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 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 {

			Optional<Riskevaluations> riskevaluations = riskevaluationsRepository.findById(riskevaluationid);

			// Verifico si encontre la aplicación
			if (!riskevaluations.isPresent()) {
				respuesta.setMsg("Registro no encontrado");
				return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
			}
			
			//Se procede a borrar la evaluación de riesgo
			riskevaluationsRepository.deleteById(riskevaluationid);
			
			Optional<Riskevaluations> riskevaluations2 = riskevaluationsRepository.findById(riskevaluationid);

			if (!riskevaluations2.isPresent()) {//Fue borrado y paso a la auditoria
				module = "Evaluación de Riesgo";
				Descmodule = "Se borró la evaluación de riesgo con id: " + riskevaluationid;
				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(fechaDate2);
				usersService.registrarAuditSesion(auditDto);

				respuestaValueDto= new RespuestaValueDto(riskevaluationid);

				estatus=HttpStatus.OK;
				return new ResponseEntity(respuestaValueDto, estatus);
			}else {
				respuesta.setMsg("No se pudo borrar por alguna razón");
				estatus = HttpStatus.CONFLICT;
				return new ResponseEntity(respuesta, estatus);
			}

		} catch (Exception e) {
			// Manejo de excepciones
			respuesta = new RespuestaDto("Error interno del servidor", false);
			estatus = HttpStatus.INTERNAL_SERVER_ERROR;
		} 

		return new ResponseEntity(respuesta, estatus);

	}



}
