package com.dacrt.SBIABackend.controler;

import java.io.PrintWriter;
import java.math.BigDecimal;
import java.net.URI;
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.Optional;

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

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.EntryInstrumentsDto;
import com.dacrt.SBIABackend.dto.FiltrosInstrumentosDto;
import com.dacrt.SBIABackend.dto.InstrumentsActualizarDto;
import com.dacrt.SBIABackend.dto.InstrumentsDto;
import com.dacrt.SBIABackend.dto.InstrumentsListDto;
import com.dacrt.SBIABackend.dto.OperationActualizarDto;
import com.dacrt.SBIABackend.dto.RiskFactorsElementDto;
import com.dacrt.SBIABackend.dto.RiskfactorsDto;
import com.dacrt.SBIABackend.dto.SceneryDto;
import com.dacrt.SBIABackend.dto.SceneryDto2;
import com.dacrt.SBIABackend.dto.StatusDto2;
import com.dacrt.SBIABackend.dto.TypesDto;
import com.dacrt.SBIABackend.dto.TypesUnitDto;
import com.dacrt.SBIABackend.entity.Applications;
import com.dacrt.SBIABackend.entity.Instrumentriskfactors;
import com.dacrt.SBIABackend.entity.Instruments;
import com.dacrt.SBIABackend.repository.InstrumentriskfactorsRepository;
import com.dacrt.SBIABackend.repository.InstrumentsRepository;
import com.dacrt.SBIABackend.security.dto.AuditRequestDto;
import com.dacrt.SBIABackend.security.dto.PrivilegesAllDto;
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 InstrumentsController {
	@Autowired
	private ParamsRepository paramsRepository;

	@Autowired
	private UsersRepository usersRepository;

	@Autowired
	private AuditRepository auditRepository;

	@Autowired
	private InstrumentsRepository instrumentsRepository;
	
	@Autowired
	private InstrumentriskfactorsRepository instrumentriskfactorsRepository;

	@Autowired
	private RolesPrivilegesRepository rolesPrivilegesRepository;

	@Autowired
	UsersService usersService;

	@Autowired
	ParamsService paramsService;

	@Autowired
	SecurityService securityService;

	@Autowired
	MenuService menuService;

	@PersistenceContext
	private EntityManager entityManager;

	@PostMapping("/instruments")
	public ResponseEntity<InstrumentsListDto> listarInstrumentos(HttpServletRequest request,
			HttpServletResponse response,
			@RequestBody FiltrosInstrumentosDto tiposfiltros) throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		InstrumentsDto instrumentos;
		StatusDto2 detalleStatus;
		PrivilegesAllDto detallePrivilege;

		Long cuantosregistro = (long) 0;

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

		String searchIn = "";
		boolean showall;
		String contentIn = "";
		int searchStatus = 0;
		String Scenery = "";
		int idrol;
		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);
				}

				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 810);

				showall = tiposfiltros.getFilters().isShowall();
				
				if (!showall) {
					if (rolisvalid == 0) {
						String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						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.setMsg("Caracteres no permitidos en la busqueda");
					return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				}

				searchStatus = tiposfiltros.getFilters().getStatus();
				
				Scenery = tiposfiltros.getFilters().getSceneryid();
				orderIn = tiposfiltros.getOrder();
				offsetIn = tiposfiltros.getOffset();
				numofrecordsIn = tiposfiltros.getNumofrecords();
				contentIn = tiposfiltros.getContent();
				if (!showall) {
					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");
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

			String SentenciaBase = "SELECT      u.id,       " + "			u.scenery,      "
					+ "			pr.descr AS escenario_nombre,        " + "			u.name,              "
					+ "			u.status,          "
					+ "			CASE WHEN u.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatus, 	 "
					+ "         STRING_AGG(COALESCE(CAST(ir.id AS TEXT), '0'), ',' ORDER BY ir.id) idintrumentosfactor, "
					+ "			STRING_AGG(COALESCE(CAST(f.name AS TEXT), '0'), ',' ORDER BY ir.id) nombre_factor,      "
					+ "			STRING_AGG(COALESCE(CAST(ir.riskfactorid AS TEXT), '0'), ',' ORDER BY ir.id) AS id_factor,        "
					+ "			STRING_AGG(COALESCE(CAST(ir.weight AS TEXT), '0'), ',' ORDER BY ir.id) AS weights,  "
					+ "         cast(COUNT(ir.id) as Integer ) AS totalelementos    "
					+ "FROM      main.instruments u  "
					+ "LEFT JOIN      main.instrumentriskfactors ir ON u.id = ir.instrumentid  "
					+ "LEFT JOIN      main.riskfactors f ON ir.riskfactorid = f.id  "
					+ "LEFT JOIN (     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'     ) pr ON u.scenery = CAST(pr.valor AS integer) ";
					
			String groupby = " GROUP BY      u.id,      u.scenery,      pr.descr,      u.name,      u.status ";

			String QueryTotal = "";
			String name = "u.name";
			String scenario = "escenario_nombre";
			String status = "u.status";
			String id = "u.id";
			String lowername = "main.sinacentos(LOWER(u.name))";
			String LowerSearch = searchIn.toLowerCase();

			if (!showall) {
				switch (searchIn) {
				case "":
					QueryTotal = SentenciaBase + " WHERE TRUE = TRUE";
					break;

				default: // viene con el parametro para buscar por el like
					QueryTotal = SentenciaBase + " WHERE " + lowername + " 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 + " = " + searchStatus;
					QueryTotal = QueryTotal + " AND " + status + " = " + 0;
					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);

				}
				
				if (Scenery.compareTo("") == 0) {
					QueryTotal = QueryTotal + " AND 1=1 ";
				} else {
					QueryTotal = QueryTotal + " AND " + " u.scenery " + " = " + Scenery;
				}	
				
			} else {
				QueryTotal = SentenciaBase + QueryTotal + "WHERE TRUE = TRUE ";
			}
			
			QueryTotal = QueryTotal + groupby;
			
			String ordena = "";
			if (orderIn == 1 || orderIn == 2 || orderIn == 3 || orderIn == 4 || orderIn == 99) {
				ordena = " ASC";
			} else if (orderIn == -1 || orderIn == -2 || orderIn == -3 || orderIn == -4 || 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 escenario+nombre ascendente
				QueryTotal = QueryTotal + " ORDER BY " + scenario + ordena + "," + name + ordena;
				break;
			case 2: // ordena por name ascendente
				QueryTotal = QueryTotal + " ORDER BY " + name + ordena;
				break;
			case 3:// ordena por status ascendente
				QueryTotal = QueryTotal + " ORDER BY " + status + ordena;
				break;
			case 4:// ordena por la cantidad de total de riskfactor
				QueryTotal = QueryTotal + " ORDER BY " + " totalelementos " + ordena;
				break;
			case 99:// ordena por id
				QueryTotal = QueryTotal + " ORDER BY " + id + ordena;
				break;

			}

			Query query;
			if (!showall) {
			query = entityManager.createNativeQuery(QueryTotal);
			cuantosregistro = (long) query.getResultList().size();	
			query.setFirstResult(offsetIn);
			query.setMaxResults(numofrecordsIn);
			TypesUnitDto detalleTypes;
			List<TypesUnitDto> listasTypes = new ArrayList<>();
			List<InstrumentsDto> records = new ArrayList();
			List<Object[]> listacompleta  = query.getResultList();
			InstrumentsListDto listado = new InstrumentsListDto();
			List<RiskfactorsDto> listasElementos = new ArrayList<>();
			RiskfactorsDto detalleElements;
			SceneryDto scenary;
			SceneryDto2 scenary2;
			// Se de be hacer el ciclo para poder llenar el objeto de la descripcion del
			// estatus
			for (Object[] reg : listacompleta) {
				instrumentos = new InstrumentsDto();
				detalleStatus = new StatusDto2();
				scenary = new SceneryDto();
					instrumentos.setId((int) reg[0]);
					instrumentos.setName((String) reg[3]);

					detalleStatus.setId((int) reg[4]);
					detalleStatus.setName((String) reg[5]);
				instrumentos.setStatus(detalleStatus);

					scenary.setId((int) reg[1]);
					scenary.setName((String) reg[2]);
				instrumentos.setScenery(scenary);
				
				String idIntrumentosFactor = (String) reg[6]; // AQUI VIENEN LOS ID DE LOS INTRUMENTOS DE FACTORES
				String NameElements = (String) reg[7]; // AQUI VIENEN LOS NOMBRES DE LOS FACTORES
				String IdElements = (String) reg[8]; // AQUI VIENEN LOS IDS DE LOS FACTORES
				String WeigthElements = (String) reg[9]; // AQUI VIENEN LOS PESOS DE LOS FACTORES

				if (NameElements != null && !IdElements.isEmpty()) {

					String[] idIntrumentosFac = idIntrumentosFactor.split(",");
					String[] Idelements = IdElements.split(",");
					String[] Nameelements = NameElements.split(",");
					String[] Weigthelements = WeigthElements.split(",");
					int i = 0;
					
					listasElementos = new ArrayList<>();
					for (String ofeId : Idelements) {
						detalleElements = new RiskfactorsDto();
						
						String IdIntFact = idIntrumentosFac[i];
						String NombreEle = Nameelements[i];
						String IdEle = Idelements[i];
						String WeigthEle = Weigthelements[i];

						detalleElements.setId(Integer.parseInt(IdIntFact));
						detalleElements.setRiskfactorid(Integer.parseInt(IdEle));
						detalleElements.setName(NombreEle);
						detalleElements.setWeight(new BigDecimal(WeigthEle));
						listasElementos.add(detalleElements);
						i = i + 1;
					}
				} else {
					listasElementos = new ArrayList<>();
					detalleElements = new RiskfactorsDto();

				}

				instrumentos.setRiskfactors(listasElementos);
				records.add(instrumentos);
			}

			detallePrivilege = new PrivilegesAllDto();

			boolean tieneView = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 810);
			boolean tieneUpdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 811);
			boolean tieneAdd = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 812);
			boolean tieneDelete = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 813);

			detallePrivilege.setView(tieneView);
			detallePrivilege.setUpdate(tieneUpdate);
			detallePrivilege.setAdd(tieneAdd);
			detallePrivilege.setDelete(tieneDelete);

			listado.setNumofrecords(cuantosregistro);
			listado.setSessionvalidthru(fechaComoCadena);
			listado.setRecords(records);
			listado.setPrivileges(detallePrivilege);
			
				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);
			}

			listado.setSceneries(listasTypes);
			return ResponseEntity.ok(listado);
			} else {
				query = entityManager.createNativeQuery(QueryTotal);
				cuantosregistro = (long) query.getResultList().size();
				query.setFirstResult(offsetIn);
				query.setMaxResults(numofrecordsIn);
				
				List<Object[]> resultados = query.getResultList();
				String unit = "INSTRUMENTOS";
				response.setContentType("text/csv");
				response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
						"attachment; filename=\"Instrumentos.csv\"");
				try (PrintWriter writer = response.getWriter();
						// CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader(
						// "UNIDADES", "PROCESOS" , "IM" , "AT" , "PR" , "RV" , "PC" , "IN" , "RR" ))) {
						CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader("ESCENARIO",
								"NOMBRE", "FACTORES", "ESTATUS"))) {

					if (cuantosregistro > 0) {
						for (Object[] filaformat2 : resultados) {
							String cadenaescenario = "";
							String cadenanombre = "";
							int cadenafactores = 0;
							String cadenaestatus = "";
							/////////////// seteando el escenario////////////////////
							cadenaescenario = (String) filaformat2[2];
							cadenaescenario = cadenaescenario.replace(',', ' ');
							/////////////// seteando el name////////////////////
							cadenanombre = (String) filaformat2[3];
							cadenanombre = cadenanombre.replace(',', ' ');
							/////////////// seteando la cantidad de elemento////////////////////
							cadenafactores = (int) filaformat2[10];
							// cadenaelementos = cadenaelementos.replace(',', ' ');
							/////////////// seteando el estatus////////////////////
							cadenaestatus = (String) filaformat2[5];
							cadenaestatus = cadenaestatus.replace(',', ' ');

							// }
							String Imprimir = "\"" + cadenaescenario + "\"" + "," + "\"" + cadenanombre + "\"" + "," + "\""
									+ cadenafactores + "\"" + "," + "\"" + cadenaestatus + "\"";
							csvPrinter.printRecord(Imprimir);
						}
						csvPrinter.flush();
					}
					return new ResponseEntity(HttpStatus.OK);

				}
			}

		} 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("/instruments/{instrumentid}")
	public ResponseEntity<EntryInstrumentsDto> obtenerUnInstrumento(HttpServletRequest request,
			@PathVariable("instrumentid") final Integer instrumentid) throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		InstrumentsDto instrumentos;
		StatusDto2 detalleStatus;
		PrivilegesAllDto detallePrivilege;

		Long cuantosregistro = (long) 0;

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

		String searchIn = "";
		String contentIn = "";
		int searchStatus = 0;
		int idrol;
		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");
			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);
				}

				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 810);

				if (rolisvalid == 0) {
					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					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");
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

			Optional<Instruments> instruments = instrumentsRepository.findById(instrumentid);

			// Verifico si encontre la aplicación
			if (!instruments.isPresent()) {
				respuesta.setMsg("Registro no encontrado");
				return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
			}
			
			EntryInstrumentsDto entry3 = new EntryInstrumentsDto();
			InstrumentsDto entry2 = new InstrumentsDto();
			List<TypesDto> sceneries = new ArrayList();
			TypesUnitDto detalleTypes;
			List<TypesUnitDto> listasTypes = new ArrayList<>();
			String SentenciaBase = "SELECT      u.id,       " + "			u.scenery,      "
					+ "			pr.descr AS escenario_nombre,        " + "			u.name,              "
					+ "			u.status,          "
					+ "			CASE WHEN u.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatus, 	 "
					+ "         STRING_AGG(COALESCE(CAST(ir.id AS TEXT), '0'), ',' ORDER BY ir.id) idintrumentosfactor, "
					+ "			STRING_AGG(COALESCE(CAST(f.name AS TEXT), '0'), ',' ORDER BY ir.id) nombre_factor,      "
					+ "			STRING_AGG(COALESCE(CAST(ir.riskfactorid AS TEXT), '0'), ',' ORDER BY ir.id) AS id_factor,        "
					+ "			STRING_AGG(COALESCE(CAST(ir.weight AS TEXT), '0'), ',' ORDER BY ir.id) AS weights  "
					+ "FROM      main.instruments u  "
					+ "LEFT JOIN      main.instrumentriskfactors ir ON u.id = ir.instrumentid  "
					+ "LEFT JOIN      main.riskfactors f ON ir.riskfactorid = f.id  "
					+ "LEFT JOIN (     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'     ) pr ON u.scenery = CAST(pr.valor AS integer) "
					+ " WHERE u.id = :instrumentid "
					+ " GROUP BY      u.id,      u.scenery,      pr.descr,      u.name,      u.status";

			Query query;
			query = entityManager.createNativeQuery(SentenciaBase);
			query.setParameter("instrumentid", instrumentid);
			query.setFirstResult(offsetIn);
			query.setMaxResults(numofrecordsIn);

			List<InstrumentsDto> records = new ArrayList();
			List<Object[]> listacompleta  = query.getResultList();
			List<RiskfactorsDto> listasElementos = new ArrayList<>();
			RiskfactorsDto detalleElements;
			SceneryDto scenary;
			SceneryDto2 scenary2;
			instrumentos = new InstrumentsDto();
			// Se de be hacer el ciclo para poder llenar el objeto de la descripcion del
			// estatus

			for (Object[] reg : listacompleta) {
				
				detalleStatus = new StatusDto2();
				scenary = new SceneryDto();
				instrumentos.setId((int) reg[0]);
				instrumentos.setName((String) reg[3]);

				detalleStatus.setId((int) reg[4]);
				detalleStatus.setName((String) reg[5]);
				instrumentos.setStatus(detalleStatus);

				scenary.setId((int) reg[1]);
				scenary.setName((String) reg[2]);
				instrumentos.setScenery(scenary);
				
				String idIntrumentosFactor = (String) reg[6]; // AQUI VIENEN LOS ID DE LOS INTRUMENTOS DE FACTORES
				String NameElements = (String) reg[7]; // AQUI VIENEN LOS NOMBRES DE LOS FACTORES
				String IdElements = (String) reg[8]; // AQUI VIENEN LOS IDS DE LOS FACTORES
				String WeigthElements = (String) reg[9]; // AQUI VIENEN LOS PESOS DE LOS FACTORES

				if (NameElements != null && !IdElements.isEmpty()) {

					String[] idIntrumentosFac = idIntrumentosFactor.split(",");
					String[] Idelements = IdElements.split(",");
					String[] Nameelements = NameElements.split(",");
					String[] Weigthelements = WeigthElements.split(",");
					int i = 0;
					
					listasElementos = new ArrayList<>();
					for (String ofeId : Idelements) {
						detalleElements = new RiskfactorsDto();
						
						String IdIntFact = idIntrumentosFac[i];
						String NombreEle = Nameelements[i];
						String IdEle = Idelements[i];
						String WeigthEle = Weigthelements[i];

						detalleElements.setId(Integer.parseInt(IdIntFact));
						detalleElements.setRiskfactorid(Integer.parseInt(IdEle));
						detalleElements.setName(NombreEle);
						detalleElements.setWeight(new BigDecimal(WeigthEle));
						listasElementos.add(detalleElements);
						i = i + 1;
					}
				} else {
					listasElementos = new ArrayList<>();
					detalleElements = new RiskfactorsDto();

				}

				instrumentos.setRiskfactors(listasElementos);
				
			}

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

			entry3.setSceneries(listasTypes);
			entry3.setEntry(instrumentos);

			return ResponseEntity.ok(entry3);

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

	}
	
	@Transactional
	@PostMapping("/instruments/{instrumentid}")
	public ResponseEntity<?> actualizarInstrumentos(HttpServletRequest request,
			@RequestBody InstrumentsActualizarDto instrumentsActualizarDto,
			@PathVariable("instrumentid") final Integer instrumentid) throws ParseException {

		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);

		AuditRequestDto auditDto = new AuditRequestDto();
		String module = "";
		String Descmodule = "";

		Date fecha3 = new Date();
		SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata2 = formatter.format(fecha3);
		Date fechaDate2 = formatter.parse(dataFormattata2);

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

		// Verifico la session
		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus = HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {
			sessionid = sessionid.substring(7); // verifico si la sesión del usuario existe.

			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				// Llamada a la funcion que validad el tiempo de Session, retorna la fecha
				// sumandole el tiempo de session activa, y vacio si no esta activa
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());
				if (fechaComoCadena == "") {
					RespuestaMsgDto respuestaDto2;
					String var2 = "";
					boolean bloked2 = false;
					respuestaDto2 = new RespuestaMsgDto(var2);
					respuestaDto2.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto2, HttpStatus.UNAUTHORIZED);
				}

				int rolisvalid = 0;
				if (instrumentid != 0) {// actualizar instrumentos

					try {
						// verifico si tiene el privilegio
						rolisvalid = auditRepository
								.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 811);
						if (rolisvalid == 0) {
							respuesta.setMsg("No tiene los Privilegios");
							estatus = HttpStatus.FORBIDDEN;
							return new ResponseEntity(respuesta, estatus);
						}
						
						// Verificar si el campo nombre no puede ser vacío
						if (instrumentsActualizarDto.getName() == "") {
							String var = "";
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							respuestaDto.setMsg("El campo nombre no puede ser vacío");
							return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
						}
						
						String Salida = usersService
								.verificarCaracteresValidosConRegex(instrumentsActualizarDto.getName());
	  					  
						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);
	  					  }
	  					  
						// Verifico si existe el id del instrumento en la base de datos
						Optional<Instruments> instruments = instrumentsRepository.findById(instrumentid);

						com.dacrt.SBIABackend.entity.Instruments instruments1 = new com.dacrt.SBIABackend.entity.Instruments();
						com.dacrt.SBIABackend.entity.Instruments instruments2 = new com.dacrt.SBIABackend.entity.Instruments();
						// Verifico si encontre la línea de operación
						if (!instruments.isPresent()) {
							respuesta.setMsg("Registro no encontrado");
							return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
						}

						instruments1 = instruments.get();
						// Verificar si el nombre del  existe en la base de datos
						if (instrumentsRepository.existsByName(instrumentsActualizarDto.getName())
								&& instrumentsRepository.getByName(instrumentsActualizarDto.getName()).get().getId()
										.compareTo(instrumentid) != 0) {
							respuesta.setMsg("Registro Duplicado");
							return new ResponseEntity(respuesta, HttpStatus.CONFLICT);
						}

						// Construyo los datos de la entidad del Instrumento
						instruments1.setName(instrumentsActualizarDto.getName());
						instruments1.setScenery(instrumentsActualizarDto.getScenery());
						instruments1.setStatus(instrumentsActualizarDto.getStatus());
						instruments1.setModifiedat(fecha2);

						instruments2 = instrumentsRepository.save(instruments1);

						if (instruments2 != null && instrumentsActualizarDto.getRiskfactors() != null) {
						    for (RiskfactorsDto rfDto : instrumentsActualizarDto.getRiskfactors()) {
						        
						        if (rfDto.getId() == 0) {
						            // --- INSERTAR NUEVO ---
									if (instrumentriskfactorsRepository.existeInstrumentrosFactores(
											instruments2.getId(), rfDto.getRiskfactorid()) > 0) {
						        		respuesta.setMsg("Registro Duplicado");
										return new ResponseEntity(respuesta, HttpStatus.CONFLICT);
						        	}
						        	Instrumentriskfactors nuevoFactor = new Instrumentriskfactors();
						            nuevoFactor.setInstrumentid(instruments2.getId());
						            nuevoFactor.setRiskfactorid(rfDto.getRiskfactorid());
						            nuevoFactor.setWeight(rfDto.getWeight());
						            instrumentriskfactorsRepository.save(nuevoFactor);
						            
						        } else if (rfDto.getId() > 0) {
						            // --- ACTUALIZAR EXISTENTE ---
									Optional<Instrumentriskfactors> existe = instrumentriskfactorsRepository
											.findInstrumeFactores(instrumentid, rfDto.getRiskfactorid());
						            if (existe.isPresent()) {
						                Instrumentriskfactors actual = existe.get();
						                actual.setWeight(rfDto.getWeight());
										// actual.setRiskfactorid(rfDto.getRiskfactorid()); // Si permites cambiar el
										// tipo de factor
						                instrumentriskfactorsRepository.save(actual);
						            }
						            
						        } else if (rfDto.getId() < 0) {
						            // --- BORRAR (ID negativo) ---
									instrumentriskfactorsRepository.deleteInstrumentrosFactores(instruments2.getId(),
											rfDto.getRiskfactorid());
						        }
						    }
						}
						
						if (instruments2 != null) {
							
							module = "Instrumentos";
							Descmodule = "Se actualizó el Instrumento: " + instruments2.getName() + " con id: "
									+ instruments2.getId();
							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 respuestaValueDto = new RespuestaValueDto(instrumentid);
							URI location = URI.create("/instruments/" + instrumentid); // O la URL correcta para // tu
																					// recurso

							return ResponseEntity.created(location).body(respuestaValueDto);
						}
					} catch (Exception e) {
						respuesta.setMsg("Error interno del servidor ");
						estatus = HttpStatus.INTERNAL_SERVER_ERROR;
					}

				} else { // incluir instrumentos
					try {
						rolisvalid = auditRepository
								.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 812);
						if (rolisvalid == 0) {
							respuesta.setMsg("No tiene los Privilegios");
							estatus = HttpStatus.FORBIDDEN;
							return new ResponseEntity(respuesta, estatus);
						}

						// Verificar si el campo nombre no puede ser vacío
						if (instrumentsActualizarDto.getName() == "") {
							String var = "";
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							respuestaDto.setMsg("El campo nombre no puede ser vacío");
							return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
						}

						// Verificar si el registro está duplicado el nombre en la base de datos
						if (instrumentsRepository.existsByName(instrumentsActualizarDto.getName())) {
							String var = "";
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							respuestaDto.setMsg("Registro Duplicado");
							return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
						}

						com.dacrt.SBIABackend.entity.Instruments instruments1 = new com.dacrt.SBIABackend.entity.Instruments();
						com.dacrt.SBIABackend.entity.Instruments instruments2 = new com.dacrt.SBIABackend.entity.Instruments();

						instruments1.setStatus(instrumentsActualizarDto.getStatus());
						instruments1.setName(instrumentsActualizarDto.getName());
						instruments1.setScenery(instrumentsActualizarDto.getScenery());
						instruments1.setModifiedat(fecha2);
						instruments1.setCreatedat(fecha2);
						
						instruments2 = instrumentsRepository.save(instruments1);

						if (instruments2 != null && instrumentsActualizarDto.getRiskfactors() != null) {
						    for (RiskfactorsDto rfDto : instrumentsActualizarDto.getRiskfactors()) {
						        
						        if (rfDto.getId() == 0) {
						            // --- INSERTAR NUEVO ---
									if (instrumentriskfactorsRepository.existeInstrumentrosFactores(
											instruments2.getId(), rfDto.getRiskfactorid()) > 0) {
						        		respuesta.setMsg("Registro Duplicado");
										return new ResponseEntity(respuesta, HttpStatus.CONFLICT);
						        	}
						        	Instrumentriskfactors nuevoFactor = new Instrumentriskfactors();
						            nuevoFactor.setInstrumentid(instruments2.getId());
						            nuevoFactor.setRiskfactorid(rfDto.getRiskfactorid());
						            nuevoFactor.setWeight(rfDto.getWeight());
						            instrumentriskfactorsRepository.save(nuevoFactor);
						            
						        } else if (rfDto.getId() > 0) {
						            // --- ACTUALIZAR EXISTENTE ---
									Optional<Instrumentriskfactors> existe = instrumentriskfactorsRepository
											.findInstrumeFactores(instrumentid, rfDto.getRiskfactorid());
						            if (existe.isPresent()) {
						                Instrumentriskfactors actual = existe.get();
						                actual.setWeight(rfDto.getWeight());
										// actual.setRiskfactorid(rfDto.getRiskfactorid()); // Si permites cambiar el
										// tipo de factor
						                instrumentriskfactorsRepository.save(actual);
						            }
						            
						        } else if (rfDto.getId() < 0) {
						            // --- BORRAR (ID negativo) ---
									instrumentriskfactorsRepository.deleteInstrumentrosFactores(instruments2.getId(),
											rfDto.getRiskfactorid());
						        }
						    }
						}
						
						try {
							if (instruments2 != null) {
								
								module = "Intrumentos";
								Descmodule = "Se insertó el Instrumento: " + instruments2.getName() + " con id: "
										+ instruments2.getId();
								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 respuestaValueDto = new RespuestaValueDto(instruments2.getId());
								URI location = URI.create("/instruments/" + instruments2.getId()); // O la URL correcta
																								// para // tu
																								// recurso
								return ResponseEntity.created(location).body(respuestaValueDto);
							} else {
								respuesta.setMsg("No se pudo actualizar por alguna razón");
								estatus = HttpStatus.CONFLICT;
								return new ResponseEntity(respuesta, estatus);
							}
						} catch (Exception e) {
							respuesta.setMsg("Error interno.  Descripción del error" + e.getMessage());
							estatus = HttpStatus.INTERNAL_SERVER_ERROR;
							return new ResponseEntity(respuesta, estatus);
						}

					} catch (Exception e) {
						respuesta.setMsg("Error interno.  Descripción del error" + e.getMessage());
						estatus = HttpStatus.INTERNAL_SERVER_ERROR;
						return new ResponseEntity(respuesta, estatus);
					}
				}
			}

			return new ResponseEntity(respuesta, HttpStatus.OK);

		}
	}

	@DeleteMapping("/instruments/{instrumentid}")
	public ResponseEntity<?> borrarInstruments(HttpServletRequest request,
			@PathVariable("instrumentid") final Integer instrumentid) throws ParseException {

		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);

		AuditRequestDto auditDto = new AuditRequestDto();
		String module = "";
		String Descmodule = "";

		Date fecha3 = new Date();
		SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata2 = formatter.format(fecha3);
		Date fechaDate2 = formatter.parse(dataFormattata2);

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

		// Verifico la session
		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus = HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {
			sessionid = sessionid.substring(7); // verifico si la sesión del usuario existe.

			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				// Llamada a la funcion que validad el tiempo de Session, retorna la fecha
				// sumandole el tiempo de session activa, y vacio si no esta activa
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());
				if (fechaComoCadena == "") {
					RespuestaMsgDto respuestaDto2;
					String var2 = "";
					boolean bloked2 = false;
					respuestaDto2 = new RespuestaMsgDto(var2);
					respuestaDto2.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto2, HttpStatus.UNAUTHORIZED);
				}

				int rolisvalid = 0;

				try {
					// verifico si tiene el privilegio
					rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(),
							813);
					if (rolisvalid == 0) {
						respuesta.setMsg("No tiene los Privilegios");
						estatus = HttpStatus.FORBIDDEN;
						return new ResponseEntity(respuesta, estatus);
					}

					// Verifico si existe el id del instrumento en la base de datos
					Optional<Instruments> instruments = instrumentsRepository.findById(instrumentid);

					Instruments instruments1 = new Instruments();
					Instruments instruments2 = new Instruments();
					// Verifico si encontre la aplicación
					if (!instruments.isPresent()) {
						respuesta.setMsg("Registro no encontrado");
						return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
					}

					instruments1 = instruments.get();
					try {
						// Se borra el instrumento
						instrumentriskfactorsRepository.deleteInstrumentriskfactorsbyid(instrumentid);
						instrumentsRepository.deleteById(instrumentid);

						module = "Instrumentos";
						Descmodule = "Se borró el instrumento: " + instruments1.getName() + " con id: " + instrumentid;
						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 respuestaValueDto = new RespuestaValueDto(instrumentid);
						URI location = URI.create("/instruments/" + instrumentid); // O la URL correcta para // tu
						// recurso

						return ResponseEntity.created(location).body(respuestaValueDto);

					} catch (Exception e) {
						respuesta.setMsg("No se pudo borrar por alguna razón");
						estatus = HttpStatus.CONFLICT;
						return new ResponseEntity(respuesta, estatus);
					} finally {
						if (entityManager != null && entityManager.isOpen()) {
							entityManager.close();
						}
					}
				} catch (Exception e) {
					respuesta.setMsg("Error interno. Descripción del error " + e.getMessage());
					estatus = HttpStatus.INTERNAL_SERVER_ERROR;
					return new ResponseEntity(respuesta, estatus);
				} finally {
					if (entityManager != null && entityManager.isOpen()) {
						entityManager.close();
					}
				}

			}

			return new ResponseEntity(respuesta, HttpStatus.OK);

		}

	}
}
