package com.dacrt.SBIABackend.controler;

import java.net.URI;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.ArrayList;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.dacrt.SBIABackend.dto.ChannelDto;
import com.dacrt.SBIABackend.dto.ChannelsDtoStatus;
import com.dacrt.SBIABackend.dto.EntryOperationLinesDto;
import com.dacrt.SBIABackend.dto.EntryOperationLinesDto2;
import com.dacrt.SBIABackend.dto.EntryPositionDto;
import com.dacrt.SBIABackend.dto.EntryPositionDto2;
import com.dacrt.SBIABackend.dto.Mensaje;
import com.dacrt.SBIABackend.dto.OperationActualizarDto;
import com.dacrt.SBIABackend.dto.OperationlineDto;
import com.dacrt.SBIABackend.dto.OperationlineDtoStatus;
import com.dacrt.SBIABackend.dto.OperationlineDtoStatus3;
import com.dacrt.SBIABackend.dto.PositionActualizarDto;
import com.dacrt.SBIABackend.dto.StatusDto;
import com.dacrt.SBIABackend.dto.StatusDto2;
import com.dacrt.SBIABackend.dto.SuppliersDto;
import com.dacrt.SBIABackend.dto.SuppliersDtoStatus;
import com.dacrt.SBIABackend.dto.UnitsDto;
import com.dacrt.SBIABackend.dto.UnitsUsersDto;
import com.dacrt.SBIABackend.dto.responseDto.ChannelsResponseDto;
import com.dacrt.SBIABackend.dto.responseDto.OperLineResponseDto;
import com.dacrt.SBIABackend.dto.responseDto.SuppliersRespondeDto;
import com.dacrt.SBIABackend.entity.Positions;
import com.dacrt.SBIABackend.entity.Positionunits;
import com.dacrt.SBIABackend.entity.Suppliers;
import com.dacrt.SBIABackend.entity.Units;
import com.dacrt.SBIABackend.entity.Userunits;
import com.dacrt.SBIABackend.entity.Workers;
import com.dacrt.SBIABackend.repository.OperationlinesRepository;
import com.dacrt.SBIABackend.repository.SuppliersRepository;
import com.dacrt.SBIABackend.repository.UnitsRepository;
import com.dacrt.SBIABackend.security.dto.AuditAllDto;
import com.dacrt.SBIABackend.security.dto.AuditRequestDto;
import com.dacrt.SBIABackend.security.dto.EntryDto;
import com.dacrt.SBIABackend.security.dto.ParamsDto;
import com.dacrt.SBIABackend.security.dto.ParamsResponseDto;
import com.dacrt.SBIABackend.security.dto.PrivilegesAllDto;
import com.dacrt.SBIABackend.security.dto.PrivilegesDto;
import com.dacrt.SBIABackend.security.dto.RespuestaDto;
import com.dacrt.SBIABackend.security.dto.RespuestaMsgDto;
import com.dacrt.SBIABackend.security.dto.RespuestaValueDto;
import com.dacrt.SBIABackend.security.dto.RoleDto;
import com.dacrt.SBIABackend.security.dto.RolesResponseDto;
import com.dacrt.SBIABackend.security.dto.RolesUserDto;
import com.dacrt.SBIABackend.security.dto.SuppliersUsersDto;
import com.dacrt.SBIABackend.security.dto.UserDetailsResponseDto;
import com.dacrt.SBIABackend.security.dto.UserListDto;
import com.dacrt.SBIABackend.security.dto.UsersListDto;
import com.dacrt.SBIABackend.security.dto.UsersUnitDto;
import com.dacrt.SBIABackend.security.entity.Params;
import com.dacrt.SBIABackend.security.entity.Roles;
import com.dacrt.SBIABackend.security.entity.Users;
import com.dacrt.SBIABackend.security.enums.RolNombre;
import com.dacrt.SBIABackend.security.repository.AuditRepository;
import com.dacrt.SBIABackend.security.repository.ParamsRepository;
import com.dacrt.SBIABackend.security.repository.RolesPrivilegesRepository;
import com.dacrt.SBIABackend.security.repository.RolesRepository;
import com.dacrt.SBIABackend.security.repository.UsersRepository;
import com.dacrt.SBIABackend.security.service.RolesService;
import com.dacrt.SBIABackend.security.service.SecurityService;
import com.dacrt.SBIABackend.security.service.MenuService;
import com.dacrt.SBIABackend.security.service.ParamsService;
import com.dacrt.SBIABackend.security.service.UsersService;
import com.dacrt.SBIABackend.service.SuppliersService;
import com.dacrt.SBIABackend.service.WorkersService;
import com.dacrt.SBIABackend.utils.HttpReqRespUtils;

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

	@Autowired
	private ParamsRepository paramsRepository;

	@Autowired
	private UsersRepository usersRepository;

	@Autowired
	private AuditRepository auditRepository;
	
	@Autowired
	private OperationlinesRepository operationlinesRepository;

	@Autowired
	private RolesPrivilegesRepository rolesPrivilegesRepository;

	@Autowired
	UsersService usersService;

	@Autowired
	ParamsService paramsService;

	@Autowired
	SecurityService securityService;

	@Autowired
	MenuService menuService;

	@PersistenceContext
	private EntityManager entityManager;

	@Autowired
	SuppliersRepository suppliersRepository;

	// @GetMapping("/menus)
	// public ResponseEntity<MenuResponseDto> menu(@PathVariable final String
	// sessionid) throws ParseException {
	@PostMapping("/operationlines")
	public ResponseEntity<OperLineResponseDto> operationlines(HttpServletRequest request,
			@RequestBody UsersListDto tiposfiltros) throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		OperLineResponseDto operLineResponseDto = new OperLineResponseDto();
		// ParamsDto detalleParams;
		OperationlineDto detalleSuppliers;
		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 = "";
		// String searchModule = "";
		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");
			// Error 400
			return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
		} else {

			sessionid = sessionid.substring(7);
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			// String usuarioIN = encontreSessionUsuario.get().getUsr();
			// int position = usuarioIN.indexOf('(');

			if (encontreSessionUsuario.isPresent()) {

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

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

				if (fechaComoCadena == "") {

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

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

				if (rolisvalid == 0) {

					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					// respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("No tiene los Privilegios");
					return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);

				}
				searchIn = tiposfiltros.getFilters().getSearch();
				  String Salida = usersService.verificarCaracteresValidosConRegex(searchIn);
				  
				  if (Salida=="NOOK") {
					  String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						//respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Caracteres no permitidos en la busqueda"); 
						return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				  }
				 
				searchStatus = tiposfiltros.getFilters().getStatus();

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

			} else {
				String var = "";
				boolean bloked = false;
				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 new com.dacrt.SBIABackend.dto.OperationlineDtoStatus (u.id,u.name,u.status,CASE WHEN u.status = 1 then 'Activo' ELSE 'Inactivo' END AS estatus) FROM Operationlines u";

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

			switch (searchIn) {
			case "": // viene sin busqueda por el like
				// QueryTotal = SentenciaBase;
				// QueryTotal = SentenciaBase + " WHERE " + lowername + " LIKE " + "'%" + "" +
				// "%'";
				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);

			}

			TypedQuery<OperationlineDtoStatus> operLineCount = entityManager.createQuery(QueryTotal,
					OperationlineDtoStatus.class);
			cuantosregistro = (long) operLineCount.getResultList().size();

			String ordena = "";
			if (orderIn == 1 || orderIn == 2 || orderIn == 99 ) {
				ordena = " ASC";
			} else if (orderIn == -1 || orderIn == -2 || orderIn == -99) {
				ordena = " DESC";
			} else {
				String var2 = "";
				boolean bloked = false;
				RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
				respuestaDto = new RespuestaMsgDto("Error interno del servidor");
				estatus = HttpStatus.INTERNAL_SERVER_ERROR;
				return new ResponseEntity(respuestaDto, estatus);
			}

			int absolutoOrden = Math.abs(orderIn);

			switch (absolutoOrden) {
			case 1: // ordena por name ascendente
				QueryTotal = QueryTotal + " ORDER BY " + name + ordena;
				break;
			case 2:// ordena por status ascendente
				QueryTotal = QueryTotal + " ORDER BY " + status + ordena;
				break;
			case 99:// ordena por id
				QueryTotal = QueryTotal + " ORDER BY " + 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<OperationlineDtoStatus> operline = entityManager.createQuery(QueryTotal,
					OperationlineDtoStatus.class);
			operline.setFirstResult(offsetIn);
			operline.setMaxResults(numofrecordsIn);

			List<OperationlineDtoStatus> listacompleta = operline.getResultList();

			List<OperationlineDto> listasSuppliers = new ArrayList<>();
			detalleSuppliers = new OperationlineDto();
			// Se de be hacer el ciclo para poder llenar el objeto de la descripcion del
			// estatus
			for (OperationlineDtoStatus suppliers : listacompleta) {
				detalleSuppliers = new OperationlineDto();

				detalleStatus = new StatusDto2();
				detalleSuppliers.setId(suppliers.getId());
				detalleSuppliers.setName(suppliers.getName());
				
				detalleStatus.setId(suppliers.getStatus());
				detalleStatus.setName(suppliers.getEstatus());
				detalleSuppliers.setStatus(detalleStatus);
				listasSuppliers.add(detalleSuppliers);
			}

			detallePrivilege = new PrivilegesAllDto();

			boolean tieneView = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 430);
			boolean tieneUpdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 431);
			boolean tieneAdd = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 432);
			boolean tieneDelete = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 433);
			// existsByRolidAndPrivilegeid

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

			operLineResponseDto.setNumofrecords(cuantosregistro);
			// paramsResponseDto.setValidthru(ValidThrufechaSalida);
			operLineResponseDto.setSessionvalidthru(fechaComoCadena);
			operLineResponseDto.setRecords(listasSuppliers);
			operLineResponseDto.setPrivileges(detallePrivilege);

			return ResponseEntity.ok(operLineResponseDto);

		} 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("/operationlines/{operationlineid}")
	public ResponseEntity<?> obtenerUnOperationlines(HttpServletRequest request,
			@PathVariable("operationlineid") final Integer operationlineid) 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 = "";

		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(), 430);
				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
			EntryOperationLinesDto entryOperationLinesDto = new EntryOperationLinesDto();
			EntryOperationLinesDto2 entryOperationLinesDto2 = new EntryOperationLinesDto2();

			try {
				Query query;
				Query query2;
				Long cuantosregistro2 = 0L;
				
				StatusDto2 status = new StatusDto2();
				// Sentencia General
				String SentenciaBase = "SELECT p.id,p.name,p.status, "
						+ "                    CASE WHEN p.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS descStatus "
						+ "              FROM main.operationlines p " 
						+ "              WHERE p.id = :operationlineid ";
				query = entityManager.createNativeQuery(SentenciaBase);
				query.setParameter("operationlineid", operationlineid);
				cuantosregistro = (long) query.getResultList().size();
				List<Object[]> resultados = query.getResultList();
				
				if (cuantosregistro > 0) {
					// 4. Recorrer la lista y procesar los resultados
					for (Object[] fila : resultados) {
						entryOperationLinesDto2.setId((int) fila[0]);
						entryOperationLinesDto2.setName((String) fila[1]);

						status.setId((int) fila[2]);
						status.setName((String) fila[3]);
						entryOperationLinesDto2.setStatus(status);
						status = new StatusDto2();

					}

					entryOperationLinesDto.setEntry(entryOperationLinesDto2);

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

			} 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("/operationlines/{operationlineid}")
	public ResponseEntity<?> actualizarOperationlines(HttpServletRequest request,
			@RequestBody OperationActualizarDto operationActualizarDto,
			@PathVariable("operationlineid") final Integer operationlineid) 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 (operationlineid != 0) {// actualizar línea de operación

					try {
						// verifico si tiene el privilegio
						rolisvalid = auditRepository
								.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 431);
						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 (operationActualizarDto.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(operationActualizarDto.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 de la línea de operación en la base de datos
						com.dacrt.SBIABackend.entity.Operationlines obtlineaOperacion = operationlinesRepository.getByOperationId(operationlineid);

						com.dacrt.SBIABackend.entity.Operationlines operation = new com.dacrt.SBIABackend.entity.Operationlines();
						com.dacrt.SBIABackend.entity.Operationlines operation2 = new com.dacrt.SBIABackend.entity.Operationlines();
						// Verifico si encontre la línea de operación
						if (obtlineaOperacion==null) {
							respuesta.setMsg("Registro no encontrado");
							return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
						}

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

						// Construyo los datos de la entidad de linea de operación
						obtlineaOperacion.setStatus(operationActualizarDto.getStatus());
						obtlineaOperacion.setName(operationActualizarDto.getName());
						obtlineaOperacion.setModifiedat(fecha2);

						operation2 = operationlinesRepository.save(obtlineaOperacion);

						if (operation2 != null) {
							
							module = "Línea de Operación";
							Descmodule = "Se actualizó la línea de operación: " + operation2.getName() + " con id: "+operation2.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(operationlineid);
							URI location = URI.create("/operationlines/" + operationlineid); // 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 línea de operación

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

						
						com.dacrt.SBIABackend.entity.Operationlines operation = new com.dacrt.SBIABackend.entity.Operationlines();
						com.dacrt.SBIABackend.entity.Operationlines operation2 = new com.dacrt.SBIABackend.entity.Operationlines();
						// Construyo los datos de la entidad línea de operación
						operation.setStatus(operationActualizarDto.getStatus());
						operation.setName(operationActualizarDto.getName());
						operation.setModifiedat(fecha2);
						operation.setCreatedat(fecha2);
						
						operation2 = operationlinesRepository.save(operation);

						try {
							if (operation2 != null) {
								
								module = "Línea de Operación";
								Descmodule = "Se insertó la línea de operación: " + operation2.getName() + " con id: "+operation2.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(operation2.getId());
								URI location = URI.create("/operationline/" + operation2.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("/operationlines/{operationlineid}")
	public ResponseEntity<?> borrarOperationlines(HttpServletRequest request,
			@PathVariable("operationlineid") final Integer operationlineid) 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(),
							433);
					if (rolisvalid == 0) {
						respuesta.setMsg("No tiene los Privilegios");
						estatus = HttpStatus.FORBIDDEN;
						return new ResponseEntity(respuesta, estatus);
					}

					// Verifico si existe el id de la linea de operación en la base de datos
					com.dacrt.SBIABackend.entity.Operationlines obtlineaOperacion = operationlinesRepository.getByOperationId(operationlineid);

					// Verifico si encontre la linea de operacion
					if (obtlineaOperacion==null) {
						respuesta.setMsg("Registro no encontrado");
						return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
					}

					try {
						    // Se borra la línea de operación
						    operationlinesRepository.deleteById(operationlineid);
						
							module = "Línea de Operación";
							Descmodule = "Se borró la línea de operación: " + obtlineaOperacion.getName() + " con id: "+operationlineid;
							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(operationlineid);
							URI location = URI.create("/operationlines/" + operationlineid); // 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);
				}

			}

			return new ResponseEntity(respuesta, HttpStatus.OK);

		}

	}

}