package com.dacrt.SBIABackend.controler;

import java.io.IOException;
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.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.ChannelDto;
import com.dacrt.SBIABackend.dto.ChannelsDtoStatus;
import com.dacrt.SBIABackend.dto.ChannelsResponse2Dto;
import com.dacrt.SBIABackend.dto.EntryOperationLinesDto;
import com.dacrt.SBIABackend.dto.EntryOperationLinesDto2;
import com.dacrt.SBIABackend.dto.EntryServicesOffers;
import com.dacrt.SBIABackend.dto.EntryServicesOffers2;
import com.dacrt.SBIABackend.dto.OperationActualizarDto;
import com.dacrt.SBIABackend.dto.ScheduleDto;
import com.dacrt.SBIABackend.dto.ServiceoffersDto1;
import com.dacrt.SBIABackend.dto.ServiceoffersDto2;
import com.dacrt.SBIABackend.dto.ServiceoffersDto3;
import com.dacrt.SBIABackend.dto.ServiceoffersDto4;
import com.dacrt.SBIABackend.dto.ServiceoffersDto5;
import com.dacrt.SBIABackend.dto.StatusDto;
import com.dacrt.SBIABackend.dto.StatusDto2;
import com.dacrt.SBIABackend.dto.TimetableDto;
import com.dacrt.SBIABackend.dto.Weekdays;
import com.dacrt.SBIABackend.dto.Weekdays2Dto;
import com.dacrt.SBIABackend.dto.requestDto.ServiceOffersActualizarDto;
import com.dacrt.SBIABackend.dto.responseDto.ChannelsResponseDto;
import com.dacrt.SBIABackend.entity.Serviceoffers;
import com.dacrt.SBIABackend.repository.ServiceoffersRepository;
import com.dacrt.SBIABackend.repository.SuppliersRepository;
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;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

@RestController
//@RequestMapping("/units")   
@CrossOrigin(origins = "*")
public class ServiceoffersController {

	@Autowired
	private ParamsRepository paramsRepository;

	@Autowired
	private UsersRepository usersRepository;

	@Autowired
	private AuditRepository auditRepository;

	@Autowired
	private RolesPrivilegesRepository rolesPrivilegesRepository;

	@Autowired
	UsersService usersService;

	@Autowired
	ParamsService paramsService;

	@Autowired
	SecurityService securityService;

	@Autowired
	MenuService menuService;

	@PersistenceContext
	private EntityManager entityManager;

	@Autowired
	private ObjectMapper objectMapper;

	@Autowired
	ServiceoffersRepository serviceOffersRepository;

	@Value("${spring.datasource.url}")
	private String conexion;

	@Value("${spring.datasource.username}")
	private String userbd;

	@Value("${spring.datasource.password}")
	private String passbd;

	// @GetMapping("/menus)
	// public ResponseEntity<MenuResponseDto> menu(@PathVariable final String
	// sessionid) throws ParseException {
	@PostMapping("/serviceoffers")
	public ResponseEntity<?> serviceoffersList(HttpServletRequest request, @RequestBody UsersListDto tiposfiltros)
			throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		ServiceoffersDto3 channelsResponseDto = new ServiceoffersDto3();
		// ParamsDto detalleParams;
		ServiceoffersDto2 detalleSuppliers = new ServiceoffersDto2();
		ServiceoffersDto4 detalleSuppliersFormat2 = new ServiceoffersDto4();
		ServiceoffersDto5 detalleSuppliersFormat2_1 = new ServiceoffersDto5();
		StatusDto 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();
		StatusDto2 statusDto = new StatusDto2();
		int idrol;
		String searchIn = "";
		int oferta24x7In = 0;
		String contentIn = "";
		// String searchModule = "";
		int searchStatus = 0;

		String fechaComoCadena;
		int orderIn = 0;
		int offsetIn = 0;
		int numofrecordsIn = 0;
		int formatList = 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);
			// String usuarioIN = encontreSessionUsuario.get().getUsr();
			// int position = usuarioIN.indexOf('(');

			if (encontreSessionUsuario.isPresent()) {

				Date FechaReg = encontreSessionUsuario.get().getValidthru();

				// fechaComoCadena = securityService.consultarSessionActiva(FechaReg,fecha2);
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

				if (fechaComoCadena == "") {

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

				}

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

				if (formatList != 2) {
					if (rolisvalid == 0) {
						respuesta.setMsg("No tiene los Privilegios");
						estatus = HttpStatus.FORBIDDEN;
						return new ResponseEntity(respuesta, estatus);
					}
				}
				searchIn = tiposfiltros.getFilters().getSearch();
				String Salida1 = usersService.verificarCaracteresValidosConRegex(searchIn);

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

				searchStatus = tiposfiltros.getFilters().getStatus();
				oferta24x7In = tiposfiltros.getFilters().getOffer_full();

				orderIn = tiposfiltros.getOrder();
				offsetIn = tiposfiltros.getOffset();
				numofrecordsIn = tiposfiltros.getNumofrecords();
				contentIn = tiposfiltros.getContent();
				if (contentIn != null) {
					menuService.iscontentdiffnull(contentIn, encontreSessionUsuario.get().getId());
				}

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

		try {

			String SentenciaBase = "SELECT u.id,u.name,"
					+ "CASE WHEN u.offer_full = 1 then 'true' ELSE 'false' END AS offer_full,"
					+ "CASE WHEN u.mon = 1 then 'true' ELSE 'false' END AS mon, "
					+ "CASE WHEN u.tue = 1 then 'true' ELSE 'false' END AS tue, "
					+ "CASE WHEN u.wed = 1 then 'true' ELSE 'false' END AS wed, "
					+ "CASE WHEN u.thu = 1 then 'true' ELSE 'false' END AS jue, "
					+ "CASE WHEN u.fri = 1 then 'true' ELSE 'false' END AS fri, "
					+ "CASE WHEN u.sat = 1 then 'true' ELSE 'false' END AS sat, "
					+ "CASE WHEN u.sun = 1 then 'true' ELSE 'false' END AS sun," + " u.schedule," + " u.status, "
					+ " CASE WHEN u.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatu  "
					+ "FROM main.serviceoffers u";
			Query query;
			String QueryTotal = "";
			String name = "u.name";
			String status = "u.status";
			String oferta = "u.offer_full";
			String lowername = "LOWER(u.name)";
			String LowerSearch = searchIn.toLowerCase();

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

			}

			switch (oferta24x7In) {
			case 0: // Busca por cualquier estatus
				QueryTotal = QueryTotal;
				break;
			case 1: // Busca por ofertas de servicios con 1
				QueryTotal = QueryTotal + " AND " + oferta + " = " + oferta24x7In;
				break;
			case 2: // Busca por ofertas de servicios con 2
				QueryTotal = QueryTotal + " AND " + oferta + " = " + 0;
				break;

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

			}

			String ordena = "";
			if (orderIn == 1 || orderIn == 2 || orderIn == 3 || orderIn == 4 || orderIn == 5 || orderIn == 6
					|| orderIn == 7 || orderIn == 8 || orderIn == 9 || orderIn == 10 || orderIn == 99) {
				ordena = " ASC";
			} else if (orderIn == -1 || orderIn == -2 || orderIn == -3 || orderIn == -4 || orderIn == -5
					|| orderIn == -6 || orderIn == -7 || orderIn == -8 || orderIn == -9 || orderIn == -10
					|| orderIn == -99) {
				ordena = " DESC";
			} else {
				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);
			}

			int absolutoOrden = Math.abs(orderIn);

			switch (absolutoOrden) {
			case 1: // ordena por name
				QueryTotal = QueryTotal + " ORDER BY " + name + ordena;
				break;
			case 2:// ordena por status
				QueryTotal = QueryTotal + " ORDER BY " + status + ordena;
				break;
			case 3:// ordena por oferta 24x7
				QueryTotal = QueryTotal + " ORDER BY " + " u.offer_full " + ordena;
				break;
			case 4:// ordena por mon
				QueryTotal = QueryTotal + " ORDER BY " + " u.mon " + ordena;
				break;
			case 5:// ordena por tue
				QueryTotal = QueryTotal + " ORDER BY " + " u.tue " + ordena;
				break;
			case 6:// ordena por wed
				QueryTotal = QueryTotal + " ORDER BY " + " u.wed " + ordena;
				break;
			case 7:// ordena por thu
				QueryTotal = QueryTotal + " ORDER BY " + " u.thu " + ordena;
				break;
			case 8:// ordena por fri
				QueryTotal = QueryTotal + " ORDER BY " + " u.fri " + ordena;
				break;
			case 9:// ordena por sat
				QueryTotal = QueryTotal + " ORDER BY " + " u.sat " + ordena;
				break;
			case 10:// ordena por sun
				QueryTotal = QueryTotal + " ORDER BY " + " u.sun " + ordena;
				break;
			case 99:// ordena por id
				QueryTotal = QueryTotal + " ORDER BY " + " u.id " + ordena;
				break;
			}

			// Se mapea la entidad se le pasa el query y lo bota como un tipo de objeto
			// ParamDto-Buscar en los DTO
			/*
			 * TypedQuery<ServiceoffersDto1> channels =
			 * entityManager.createQuery(QueryTotal, ServiceoffersDto1.class);
			 * channels.setFirstResult(offsetIn); channels.setMaxResults(numofrecordsIn);
			 */

			query = entityManager.createNativeQuery(QueryTotal);
			cuantosregistro = (long) query.getResultList().size();
			if (formatList != 2) {
				query.setFirstResult(offsetIn);
				query.setMaxResults(numofrecordsIn);
			}
			/*
			 * TypedQuery<ServiceoffersDto1> channelsCount =
			 * entityManager.createQuery(QueryTotal, ServiceoffersDto1.class);
			 */

			List<Object[]> listacompleta = query.getResultList();

			List<ServiceoffersDto2> listasSuppliers = new ArrayList<>();
			List<ServiceoffersDto5> listasSuppliersFormat2 = new ArrayList<>();
			detalleSuppliers = new ServiceoffersDto2();

			Weekdays2Dto weekdays = new Weekdays2Dto();
			String dia = "";
			String ofer = "";
			// Se de be hacer el ciclo para poder llenar el objeto de la descripcion del
			// estatus
			if (formatList != 2) {
				for (Object[] fila : listacompleta) {
					detalleSuppliers.setId((int) fila[0]);
					detalleSuppliers.setName((String) fila[1]);
					ofer = (String) fila[2];

					if (ofer.compareTo("true") == 0)
						detalleSuppliers.setOffer_full(true);
					else
						detalleSuppliers.setOffer_full(false);

					dia = (String) fila[3];
					if (dia.compareTo("true") == 0)
						weekdays.setMonday(true);
					else
						weekdays.setMonday(false);

					dia = "";
					dia = (String) fila[4];
					if (dia.compareTo("true") == 0)
						weekdays.setTuesday(true);
					else
						weekdays.setTuesday(false);

					dia = "";
					dia = (String) fila[5];
					if (dia.compareTo("true") == 0)
						weekdays.setWednesday(true);
					else
						weekdays.setWednesday(false);

					dia = "";
					dia = (String) fila[6];
					if (dia.compareTo("true") == 0)
						weekdays.setThursday(true);
					else
						weekdays.setThursday(false);

					dia = "";
					dia = (String) fila[7];
					if (dia.compareTo("true") == 0)
						weekdays.setFriday(true);
					else
						weekdays.setFriday(false);

					dia = "";
					dia = (String) fila[8];
					if (dia.compareTo("true") == 0)
						weekdays.setSaturday(true);
					else
						weekdays.setSaturday(false);

					dia = "";
					dia = (String) fila[9];
					if (dia.compareTo("true") == 0)
						weekdays.setSunday(true);
					else
						weekdays.setSunday(false);

					dia = "";

					detalleSuppliers.setWeekdays(weekdays);
					String scheduleJsonStr = (String) fila[10];

					if (scheduleJsonStr == null) {
						scheduleJsonStr = scheduleJsonStr = "";
					} else {
						scheduleJsonStr = scheduleJsonStr.trim();
					}

					// Reemplazar comillas simples por comillas dobles
					if (scheduleJsonStr.compareTo("") != 0 && !scheduleJsonStr.isEmpty()) {
						// Reemplazar comillas simples por comillas dobles
						String correctedTimetableJsonStr = scheduleJsonStr.replace("'", "\"");
						List<ScheduleDto> scheduleDtos = new ArrayList();
						try {
							scheduleDtos = objectMapper.readValue(correctedTimetableJsonStr,
									new TypeReference<List<ScheduleDto>>() {
									});
							detalleSuppliers.setSchedule(scheduleDtos);
						} catch (IOException e) {
							detalleSuppliers.setSchedule(Collections.emptyList());
							e.printStackTrace(); // Log the error
						}
					} else
						detalleSuppliers.setSchedule(Collections.emptyList());

					statusDto.setId((int) fila[11]);
					statusDto.setName((String) fila[12]);
					detalleSuppliers.setStatus(statusDto);
					listasSuppliers.add(detalleSuppliers);
					detalleSuppliers = new ServiceoffersDto2();
					weekdays = new Weekdays2Dto();
					statusDto = new StatusDto2();
				}

				detallePrivilege = new PrivilegesAllDto();
				boolean tieneView = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 495);
				boolean tieneUpdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 496);
				boolean tieneAdd = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 497);
				boolean tieneDelete = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 498);

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

				channelsResponseDto.setNumofrecords(cuantosregistro);
				channelsResponseDto.setValidthru(fechaComoCadena);
				channelsResponseDto.setRecords(listasSuppliers);
				channelsResponseDto.setPrivileges(detallePrivilege);

				return ResponseEntity.ok(channelsResponseDto);
			} else {
				for (Object[] fila : listacompleta) {
					detalleSuppliersFormat2_1.setId((int) fila[0]);
					detalleSuppliersFormat2_1.setName((String) fila[1]);
					ofer = (String) fila[2];

					if (ofer.compareTo("true") == 0)
						detalleSuppliersFormat2_1.setOffer_full(true);
					else
						detalleSuppliersFormat2_1.setOffer_full(false);

					statusDto.setId((int) fila[11]);
					statusDto.setName((String) fila[12]);
					detalleSuppliersFormat2_1.setStatus(statusDto);
					listasSuppliersFormat2.add(detalleSuppliersFormat2_1);
					detalleSuppliersFormat2_1 = new ServiceoffersDto5();
					weekdays = new Weekdays2Dto();
					statusDto = new StatusDto2();
				}

				detalleSuppliersFormat2.setSessionvalidthru(fechaComoCadena);
				detalleSuppliersFormat2.setRecords(listasSuppliersFormat2);
				return ResponseEntity.ok(detalleSuppliersFormat2);
			}
		} catch (Exception e) {
			// Manejo de excepciones
			respuesta = new RespuestaDto("Error interno del servidor" + e.getMessage(), false);
			estatus = HttpStatus.INTERNAL_SERVER_ERROR;
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}

		return new ResponseEntity(respuesta, estatus);

	}

	@GetMapping("/serviceoffers/{serviceofferid}")
	public ResponseEntity<?> obtenerServiceoffers(HttpServletRequest request,
			@PathVariable("serviceofferid") final Integer serviceofferid) 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);

		String contentIn = "";
		StatusDto2 statusDto = new StatusDto2();
		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);
				}

				// Obtengo el rol de usuario y verifico si corresponde al privilegio del usuario
				int rolisvalid = 0;
				rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 495);
				if (rolisvalid == 0) {
					respuesta.setMsg("No tiene los Privilegios");
					estatus = HttpStatus.FORBIDDEN;
					return new ResponseEntity(respuesta, estatus);
				}

			} else { // Si la sesión que viene es inválida
				respuesta.setMsg("Sesión expirada o inválida");
				estatus = HttpStatus.BAD_REQUEST;
				return new ResponseEntity(respuesta, estatus);
			}

			// Aqui empieza la carga de la data de respuesta
			EntryServicesOffers entryServicesOffers = new EntryServicesOffers();
			EntryServicesOffers2 entryServicesOffers2 = new EntryServicesOffers2();

			try {
				Query query;
				Query query2;
				Long cuantosregistro2 = 0L;
				// Sentencia General
				String SentenciaBase = "SELECT u.id,u.name,"
						+ "CASE WHEN u.offer_full = 1 then 'true' ELSE 'false' END AS offer_full,"
						+ "CASE WHEN u.mon = 1 then 'true' ELSE 'false' END AS mon, "
						+ "CASE WHEN u.tue = 1 then 'true' ELSE 'false' END AS tue, "
						+ "CASE WHEN u.wed = 1 then 'true' ELSE 'false' END AS wed, "
						+ "CASE WHEN u.thu = 1 then 'true' ELSE 'false' END AS jue, "
						+ "CASE WHEN u.fri = 1 then 'true' ELSE 'false' END AS fri, "
						+ "CASE WHEN u.sat = 1 then 'true' ELSE 'false' END AS sat, "
						+ "CASE WHEN u.sun = 1 then 'true' ELSE 'false' END AS sun," + " u.schedule,  " + " u.status, "
						+ " CASE WHEN u.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatu  "
						+ "FROM main.serviceoffers u " + "WHERE u.id = :serviceofferid ";
				query = entityManager.createNativeQuery(SentenciaBase);
				query.setParameter("serviceofferid", serviceofferid);
				cuantosregistro = (long) query.getResultList().size();
				List<Object[]> resultados = query.getResultList();

				Weekdays2Dto weekdays = new Weekdays2Dto();
				String dia = "";
				String ofer = "";
				if (cuantosregistro > 0) {
					// 4. Recorrer la lista y procesar los resultados
					for (Object[] fila : resultados) {
						entryServicesOffers2.setId((int) fila[0]);
						entryServicesOffers2.setName((String) fila[1]);

						ofer = (String) fila[2];
						if (ofer.compareTo("true") == 0)
							entryServicesOffers2.setOffer_full(true);
						else
							entryServicesOffers2.setOffer_full(false);

						dia = (String) fila[3];
						if (dia.compareTo("true") == 0)
							weekdays.setMonday(true);
						else
							weekdays.setMonday(false);

						dia = "";
						dia = (String) fila[4];
						if (dia.compareTo("true") == 0)
							weekdays.setTuesday(true);
						else
							weekdays.setTuesday(false);

						dia = "";
						dia = (String) fila[5];
						if (dia.compareTo("true") == 0)
							weekdays.setWednesday(true);
						else
							weekdays.setWednesday(false);

						dia = "";
						dia = (String) fila[6];
						if (dia.compareTo("true") == 0)
							weekdays.setThursday(true);
						else
							weekdays.setThursday(false);

						dia = "";
						dia = (String) fila[7];
						if (dia.compareTo("true") == 0)
							weekdays.setFriday(true);
						else
							weekdays.setFriday(false);

						dia = "";
						dia = (String) fila[8];
						if (dia.compareTo("true") == 0)
							weekdays.setSaturday(true);
						else
							weekdays.setSaturday(false);

						dia = "";
						dia = (String) fila[9];
						if (dia.compareTo("true") == 0)
							weekdays.setSunday(true);
						else
							weekdays.setSunday(false);

						dia = "";
						String scheduleJsonStr = (String) fila[10];

						if (scheduleJsonStr == null) {
							scheduleJsonStr = scheduleJsonStr = "";
						} else {
							scheduleJsonStr = scheduleJsonStr.trim();
						}

						if (scheduleJsonStr.compareTo("") != 0 && !scheduleJsonStr.isEmpty()) {
							// Reemplazar comillas simples por comillas dobles
							String correctedTimetableJsonStr = scheduleJsonStr.replace("'", "\"");
							List<ScheduleDto> scheduleDtos = new ArrayList();
							try {
								scheduleDtos = objectMapper.readValue(correctedTimetableJsonStr,
										new TypeReference<List<ScheduleDto>>() {
										});
								entryServicesOffers2.setSchedule(scheduleDtos);
							} catch (IOException e) {
								entryServicesOffers2.setSchedule(Collections.emptyList());
								e.printStackTrace(); // Log the error
							}
						} else
							entryServicesOffers2.setSchedule(Collections.emptyList());

						// Reemplazar comillas simples por comillas dobles
						/*
						 * String correctedTimetableJsonStr = scheduleJsonStr.replace("'", "\"");
						 * List<ScheduleDto> scheduleDtos = new ArrayList(); try { scheduleDtos =
						 * objectMapper.readValue(correctedTimetableJsonStr, new
						 * TypeReference<List<ScheduleDto>>() { });
						 * entryServicesOffers2.setSchedule(scheduleDtos); } catch (IOException e) {
						 * entryServicesOffers2.setSchedule(Collections.emptyList());
						 * e.printStackTrace(); // Log the error }
						 */

						statusDto.setId((int) fila[11]);
						statusDto.setName((String) fila[12]);

						entryServicesOffers2.setStatus(statusDto);
						entryServicesOffers2.setWeekdays(weekdays);
						entryServicesOffers.setEntry(entryServicesOffers2);
					}

					return ResponseEntity.ok(entryServicesOffers);

				} else {
					respuesta.setMsg("Registro no encontrado");
					return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
				}

			} catch (Exception e) {
				respuesta.setMsg("Error interno del servidor " + e.getMessage());
				estatus = HttpStatus.INTERNAL_SERVER_ERROR;
			} finally {
				if (entityManager != null && entityManager.isOpen()) {
					entityManager.close();
				}
			}
		}
		return new ResponseEntity(respuesta, HttpStatus.OK);
	}

	@PostMapping("/serviceoffers/{serviceofferid}")
	public ResponseEntity<?> actualizarOperationlines(HttpServletRequest request,
			@RequestBody ServiceOffersActualizarDto serviceOffersActualizarDto,
			@PathVariable("serviceofferid") final Integer serviceofferid) 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;

				String Salida1 = usersService.verificarCaracteresValidosConRegex(serviceOffersActualizarDto.getName());

				if (Salida1 == "NOOK") {
					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					// respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("Caracteres no permitidos en la busqueda");
					return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				}

				if (serviceofferid != 0) {// actualizar línea de operación

					try {
						// verifico si tiene el privilegio
						rolisvalid = auditRepository
								.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 496);
						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 (serviceOffersActualizarDto.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);
						}

						// Verifico si existe el id de la oferta de servicios
						Optional<Serviceoffers> obtserviceOffers = serviceOffersRepository.findById(serviceofferid);

						Serviceoffers serviceOffers1 = new Serviceoffers();
						Serviceoffers serviceOffers2 = new Serviceoffers();

						// Verifico si encontré la oferta de servicios
						if (!obtserviceOffers.isPresent()) {
							respuesta.setMsg("Registro no encontrado");
							return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
						}

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

						// verificar si ya existe una oferta de servicio con 24x7

						if (serviceOffersRepository.cantOfferFull() > 0
								&& serviceOffersActualizarDto.getOffer_full().compareTo("true") == 0
								&& obtserviceOffers.get().getOffer_full() != 1) {
							respuesta.setMsg("Ya existe una Oferta de Servicio 24x7");
							estatus = HttpStatus.CONFLICT;
							;
							return new ResponseEntity(respuesta, estatus);
						}

						serviceOffers1 = obtserviceOffers.get();
						// Construyo los datos de la entidad de servicio de ofertas
						serviceOffers1.setStatus(serviceOffersActualizarDto.getStatus());
						serviceOffers1.setName(serviceOffersActualizarDto.getName());
						serviceOffers1.setOffer_full(
								serviceOffersActualizarDto.getOffer_full().compareTo("true") == 0 ? 1 : 0);
						serviceOffers1.setMon(serviceOffersActualizarDto.getMonday().compareTo("true") == 0 ? 1 : 0);
						serviceOffers1.setTue(serviceOffersActualizarDto.getTuesday().compareTo("true") == 0 ? 1 : 0);
						serviceOffers1.setWed(serviceOffersActualizarDto.getWednesday().compareTo("true") == 0 ? 1 : 0);
						serviceOffers1.setThu(serviceOffersActualizarDto.getThursday().compareTo("true") == 0 ? 1 : 0);
						serviceOffers1.setFri(serviceOffersActualizarDto.getFriday().compareTo("true") == 0 ? 1 : 0);
						serviceOffers1.setSat(serviceOffersActualizarDto.getSaturday().compareTo("true") == 0 ? 1 : 0);
						serviceOffers1.setSun(serviceOffersActualizarDto.getSunday().compareTo("true") == 0 ? 1 : 0);

						// Mapeo de la lista de horarios a String JSON
						try {
							if (serviceOffersActualizarDto.getSchedule() != null
									&& !serviceOffersActualizarDto.getSchedule().isEmpty()) {
								String scheduleJson = objectMapper
										.writeValueAsString(serviceOffersActualizarDto.getSchedule());
								serviceOffers1.setSchedule(scheduleJson);
							} else {
								serviceOffers1.setSchedule(""); // O null, dependiendo de si permites schedule vacío
							}
						} catch (JsonProcessingException e) {
							// Manejo de errores si hay un problema al convertir la lista a JSON String
							System.err.println("Error al serializar el schedule a JSON: " + e.getMessage());
							// Podrías lanzar una excepción personalizada aquí o manejar el error de otra
							// forma
							serviceOffers1.setSchedule(""); // Asigna un valor por defecto
						}

						serviceOffers1.setModifiedat(fecha2);

						serviceOffers2 = serviceOffersRepository.save(serviceOffers1);

						if (serviceOffers2 != null) {

							module = "Ofertas de Servicios";
							Descmodule = "Se actualizó la Oferta de Servicio: " + serviceOffers2.getName() + " con id: "
									+ serviceOffers2.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(serviceofferid);
							URI location = URI.create("/serviceoffers/" + serviceofferid);

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

				} else { // incluir línea de operación

					try {
						rolisvalid = auditRepository
								.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 497);
						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 (serviceOffersActualizarDto.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 (serviceOffersRepository.existsByName(serviceOffersActualizarDto.getName())) {
							String var = "";
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							respuestaDto.setMsg("Registro Duplicado");
							return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
						}

						if (serviceOffersRepository.cantOfferFull() > 0
								&& serviceOffersActualizarDto.getOffer_full().compareTo("true") == 0) {
							respuesta.setMsg("Ya existe una Oferta de Servicio 24x7");
							estatus = HttpStatus.CONFLICT;
							;
							return new ResponseEntity(respuesta, estatus);
						}

						Serviceoffers serviceOffers1 = new Serviceoffers();
						Serviceoffers serviceOffers2 = new Serviceoffers();

						// Construyo los datos de la entidad de servicio de ofertas

						if (serviceOffersActualizarDto.getOffer_full().compareTo("true") == 0) {
							Connection conexion2 = DriverManager.getConnection(conexion, userbd, passbd);
							// (PreparedStatement sentenciaPreparada = conexion2.prepareStatement(sql))
							Statement sentenciaPreparada = null;
							try {

								sentenciaPreparada = conexion2.createStatement();
								int ofer = serviceOffersActualizarDto.getOffer_full().compareTo("true") == 0 ? 1 : 0;
								int mon = serviceOffersActualizarDto.getMonday().compareTo("true") == 0 ? 1 : 0;
								int tue = serviceOffersActualizarDto.getTuesday().compareTo("true") == 0 ? 1 : 0;
								int wed = serviceOffersActualizarDto.getWednesday().compareTo("true") == 0 ? 1 : 0;
								int thu = serviceOffersActualizarDto.getThursday().compareTo("true") == 0 ? 1 : 0;
								int fri = serviceOffersActualizarDto.getFriday().compareTo("true") == 0 ? 1 : 0;
								int sat = serviceOffersActualizarDto.getSaturday().compareTo("true") == 0 ? 1 : 0;
								int sun = serviceOffersActualizarDto.getSunday().compareTo("true") == 0 ? 1 : 0;
								String scheduleJson = " ";
								try {
									if (serviceOffersActualizarDto.getSchedule() != null
											&& !serviceOffersActualizarDto.getSchedule().isEmpty()) {
										scheduleJson = objectMapper
												.writeValueAsString(serviceOffersActualizarDto.getSchedule());
										// serviceOffers1.setSchedule(scheduleJson);
									} else {
										scheduleJson = ""; // O null, dependiendo de si permites schedule vacío
									}
								} catch (JsonProcessingException e) {
									// Manejo de errores si hay un problema al convertir la lista a JSON String
									System.err.println("Error al serializar el schedule a JSON: " + e.getMessage());
									// Podrías lanzar una excepción personalizada aquí o manejar el error de otra
									// forma
									scheduleJson = ""; // Asigna un valor por defecto
								}

								String sql = " INSERT INTO main.serviceoffers (id,name,status,offer_full,mon,tue,wed,thu,fri,sat,sun,schedule) "
										+ "VALUES (" + -1 + "," + "'" + serviceOffersActualizarDto.getName() + "'" + ","
										+ serviceOffersActualizarDto.getStatus() + "," + ofer + "," + mon + "," + tue
										+ "," + wed + "," + thu + "," + fri + "," + sat + "," + sun + "," + "'"
										+ scheduleJson + "'" + " )";
								sentenciaPreparada.execute(sql);

								serviceOffers1.setStatus(serviceOffersActualizarDto.getStatus());
								serviceOffers1.setOffer_full(
										serviceOffersActualizarDto.getOffer_full().compareTo("true") == 0 ? 1 : 0);
								serviceOffers1.setName(serviceOffersActualizarDto.getName());
								serviceOffers1
										.setMon(serviceOffersActualizarDto.getMonday().compareTo("true") == 0 ? 1 : 0);
								serviceOffers1
										.setTue(serviceOffersActualizarDto.getTuesday().compareTo("true") == 0 ? 1 : 0);
								serviceOffers1.setWed(
										serviceOffersActualizarDto.getWednesday().compareTo("true") == 0 ? 1 : 0);
								serviceOffers1.setThu(
										serviceOffersActualizarDto.getThursday().compareTo("true") == 0 ? 1 : 0);
								serviceOffers1
										.setFri(serviceOffersActualizarDto.getFriday().compareTo("true") == 0 ? 1 : 0);
								serviceOffers1.setSat(
										serviceOffersActualizarDto.getSaturday().compareTo("true") == 0 ? 1 : 0);
								serviceOffers1
										.setSun(serviceOffersActualizarDto.getSunday().compareTo("true") == 0 ? 1 : 0);
								serviceOffers1.setModifiedat(fecha2);
								serviceOffers1.setCreatedat(fecha2);
								serviceOffers1.setId(-1);
								serviceOffers2 = serviceOffers1;

							} catch (Exception e) {
								respuesta = new RespuestaMsgDto("Error insertando Oferta de Servicio 24x7");
								estatus = HttpStatus.CONFLICT;
								return new ResponseEntity(respuesta, estatus);

							} finally { // <--- BLOQUE FINALLY PARA CERRAR RECURSOS
								try {
									if (sentenciaPreparada != null) {
										sentenciaPreparada.close();
									}
								} catch (SQLException se) {
									System.err.println("Error al cerrar Statement: " + se.getMessage());
								}
								try {
									if (conexion2 != null) {
										conexion2.close();
									}
								} catch (SQLException se) {
									System.err.println("Error al cerrar Connection: " + se.getMessage());
								}
							}
						} else {
							serviceOffers1.setStatus(serviceOffersActualizarDto.getStatus());
							serviceOffers1.setOffer_full(
									serviceOffersActualizarDto.getOffer_full().compareTo("true") == 0 ? 1 : 0);
							serviceOffers1.setName(serviceOffersActualizarDto.getName());
							serviceOffers1
									.setMon(serviceOffersActualizarDto.getMonday().compareTo("true") == 0 ? 1 : 0);
							serviceOffers1
									.setTue(serviceOffersActualizarDto.getTuesday().compareTo("true") == 0 ? 1 : 0);
							serviceOffers1
									.setWed(serviceOffersActualizarDto.getWednesday().compareTo("true") == 0 ? 1 : 0);
							serviceOffers1
									.setThu(serviceOffersActualizarDto.getThursday().compareTo("true") == 0 ? 1 : 0);
							serviceOffers1
									.setFri(serviceOffersActualizarDto.getFriday().compareTo("true") == 0 ? 1 : 0);
							serviceOffers1
									.setSat(serviceOffersActualizarDto.getSaturday().compareTo("true") == 0 ? 1 : 0);
							serviceOffers1
									.setSun(serviceOffersActualizarDto.getSunday().compareTo("true") == 0 ? 1 : 0);

							// Mapeo de la lista de horarios a String JSON
							try {
								if (serviceOffersActualizarDto.getSchedule() != null
										&& !serviceOffersActualizarDto.getSchedule().isEmpty()) {
									String scheduleJson = objectMapper
											.writeValueAsString(serviceOffersActualizarDto.getSchedule());
									serviceOffers1.setSchedule(scheduleJson);
								} else {
									serviceOffers1.setSchedule(""); // O null, dependiendo de si permites schedule vacío
								}
							} catch (JsonProcessingException e) {
								// Manejo de errores si hay un problema al convertir la lista a JSON String
								System.err.println("Error al serializar el schedule a JSON: " + e.getMessage());
								// Podrías lanzar una excepción personalizada aquí o manejar el error de otra
								// forma
								serviceOffers1.setSchedule(""); // Asigna un valor por defecto
							}

							serviceOffers1.setModifiedat(fecha2);
							serviceOffers1.setCreatedat(fecha2);

							serviceOffers2 = serviceOffersRepository.save(serviceOffers1);
						}

						try {
							if (serviceOffers2 != null) {

								module = "Ofertas de Servicios";
								Descmodule = "Se insertó la Oferta de Servicio: " + serviceOffers2.getName()
										+ " con id: " + serviceOffers2.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(serviceOffers2.getId());
								URI location = URI.create("/serviceoffers/" + serviceOffers2.getId());

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

		}
	}

	@DeleteMapping("/serviceoffers/{serviceofferid}")
	public ResponseEntity<?> borrarServiceoffers(HttpServletRequest request,
			@PathVariable("serviceofferid") final Integer serviceofferid) 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(),
							498);
					if (rolisvalid == 0) {
						respuesta.setMsg("No tiene los Privilegios");
						estatus = HttpStatus.FORBIDDEN;
						return new ResponseEntity(respuesta, estatus);
					}

					// Verifico si existe el id de la oferta de servicios
					Optional<Serviceoffers> obtserviceOffers = serviceOffersRepository.findById(serviceofferid);

					// Verifico si encontre la oferta de Servicios
					if (!obtserviceOffers.isPresent()) {
						respuesta.setMsg("Registro no encontrado");
						return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
					}

					Query queryCanales;
					Query queryAplicaciones;
					try {
						// Se borra la oferta de servicios de los procesos
						serviceOffersRepository.deleteProcessserviceoffersbyid(serviceofferid);

						// Se borra la oferta de servicios de los canales
						String ofertasCanales = "SELECT s.id,s.serviceoffers " + "FROM main.channels s "
								+ "WHERE ? = ANY(CAST(string_to_array(serviceoffers, ',') AS int[]))  "
								+ "ORDER BY id ASC ";

						queryCanales = entityManager.createNativeQuery(ofertasCanales);
						queryCanales.setParameter(1, serviceofferid);
						cuantosregistro = (long) queryCanales.getResultList().size();
						List<Object[]> resultados = queryCanales.getResultList();
						String currentServiceOffers = "";
						int idCanal = 0;
						if (cuantosregistro > 0) {
							// 4. Recorrer la lista y procesar los resultados
							for (Object[] fila : resultados) {
								idCanal = (Integer) fila[0];
								currentServiceOffers = (String) fila[1];
								List<String> offerIds = Arrays.asList(currentServiceOffers.split(","));
								List<String> updatedOfferIds = offerIds.stream()
										.filter(id -> !id.trim().equals(String.valueOf(serviceofferid)))
										.collect(Collectors.toList());
								String newServiceOffers = String.join(",", updatedOfferIds);

								serviceOffersRepository.updateChannelsOffersbyid(idCanal, newServiceOffers);
							}
						}

						// Se borra la oferta de servicios de las aplicaciones
						String ofertasAplicaciones = "SELECT s.id,s.serviceoffers " + "FROM main.applications s "
								+ "WHERE ? = ANY(CAST(string_to_array(serviceoffers, ',') AS int[]))  "
								+ "ORDER BY id ASC ";

						queryAplicaciones = entityManager.createNativeQuery(ofertasAplicaciones);
						queryAplicaciones.setParameter(1, serviceofferid);
						cuantosregistro = (long) queryAplicaciones.getResultList().size();
						List<Object[]> resultados2 = queryAplicaciones.getResultList();
						currentServiceOffers = "";
						int idAplicacion = 0;
						if (cuantosregistro > 0) {
							// 4. Recorrer la lista y procesar los resultados
							for (Object[] fila : resultados2) {
								idAplicacion = (Integer) fila[0];
								currentServiceOffers = (String) fila[1];
								List<String> offerIds = Arrays.asList(currentServiceOffers.split(","));
								List<String> updatedOfferIds = offerIds.stream()
										.filter(id -> !id.trim().equals(String.valueOf(serviceofferid)))
										.collect(Collectors.toList());
								String newServiceOffers = String.join(",", updatedOfferIds);

								serviceOffersRepository.updateApplicationOffersbyid(idAplicacion, newServiceOffers);
							}
						}

						serviceOffersRepository.deleteById(serviceofferid);

						module = "Ofertas de Servicios";
						Descmodule = "Se borró la Oferta de Servicio: " + obtserviceOffers.get().getName() + " con id: "
								+ serviceofferid;
						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(serviceofferid);
						URI location = URI.create("/serviceoffers/" + serviceofferid); // 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);
					}
				} 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);

		}

	}
}