package com.dacrt.SBIABackend.controler;

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.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.jdbc.core.JdbcTemplate;
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.ExternalReqsActualizarDto;
import com.dacrt.SBIABackend.dto.ExternalreqsRecordDto;
import com.dacrt.SBIABackend.dto.FacilityDto;
import com.dacrt.SBIABackend.dto.ProcessActualizarDto;
import com.dacrt.SBIABackend.dto.StatusDto;
import com.dacrt.SBIABackend.dto.StrategiesDependencyDetDto;
import com.dacrt.SBIABackend.dto.StrategiesRecordDto;
import com.dacrt.SBIABackend.dto.StrategyDetDto;
import com.dacrt.SBIABackend.dto.TypeStrategiDetDto;
import com.dacrt.SBIABackend.dto.TypeUnitDto;
import com.dacrt.SBIABackend.dto.TypesUnitDto;
import com.dacrt.SBIABackend.dto.UnitsUsersDto;
import com.dacrt.SBIABackend.dto.responseDto.ExternalReqsDetailRespondeDto;
import com.dacrt.SBIABackend.dto.responseDto.ExternalreqsResponseDto;
import com.dacrt.SBIABackend.dto.responseDto.StrategiesDetRespondeDto;
import com.dacrt.SBIABackend.entity.Externalreqs;
import com.dacrt.SBIABackend.entity.Processchannels;
import com.dacrt.SBIABackend.entity.Processes;
import com.dacrt.SBIABackend.entity.Processserviceoffers;
import com.dacrt.SBIABackend.entity.Suppliers;
import com.dacrt.SBIABackend.entity.Workers;
import com.dacrt.SBIABackend.repository.ExternalreqsRepository;
import com.dacrt.SBIABackend.repository.ProcessesRepository;
import com.dacrt.SBIABackend.repository.StrategiesRepository;
import com.dacrt.SBIABackend.repository.StrategiesdetRepository;
import com.dacrt.SBIABackend.repository.StrategiesdetprocessesRepository;
import com.dacrt.SBIABackend.repository.StrategiesdetunitsRepository;
import com.dacrt.SBIABackend.repository.UnitprocessesRepository;
import com.dacrt.SBIABackend.repository.UnitsRepository;
import com.dacrt.SBIABackend.repository.UserunitsRepository;
import com.dacrt.SBIABackend.repository.VicepresidenciesRepository;
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.service.FacilitiesService;
import com.dacrt.SBIABackend.service.UnitsService;
import com.dacrt.SBIABackend.service.VicepresidenciesService;
import com.dacrt.SBIABackend.utils.HttpReqRespUtils;

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

	@Autowired
	private ParamsRepository paramsRepository;

	@Autowired
	private UsersRepository usersRepository;

	@Autowired
	private AuditRepository auditRepository;

	@Autowired
	private StrategiesRepository strategiesRepository;

	@Autowired
	private ExternalreqsRepository externalreqsRepository;

	@Autowired
	private StrategiesdetRepository strategiesdetRepository;

	@Autowired
	private RolesPrivilegesRepository rolesPrivilegesRepository;

	@Autowired
	private UnitprocessesRepository unitprocessesRepository;

	@Autowired
	private VicepresidenciesRepository vicepresidenciesRepository;

	@Autowired
	UsersService usersService;

	@Autowired
	SecurityService securityService;

	@Autowired
	ParamsService paramsService;

	@Autowired
	MenuService menuService;

	@Autowired
	UserunitsRepository userunitsRepository;

	@Autowired
	StrategiesdetunitsRepository strategiesdetunitsRepository;

	@Autowired
	StrategiesdetprocessesRepository strategiesdetprocessesRepository;

	@Autowired
	VicepresidenciesService vicepresidenciesService;

	@Autowired
	FacilitiesService facilitiesService;

	@Autowired
	UnitsRepository unitsRepository;

	@Autowired
	ProcessesRepository processesRepository;

	@Autowired
	UnitsService unitsService;

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@PersistenceContext
	private EntityManager entityManager;

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

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

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

	@PostMapping("/externalreqs")
	public ResponseEntity<ExternalreqsResponseDto> externalreqs(HttpServletRequest request,
			@RequestBody UsersListDto tiposfiltros) throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		ExternalreqsResponseDto externalreqsResponseDto = new ExternalreqsResponseDto();
		// ParamsDto detalleParams;
		UnitsUsersDto detalleUnits;
		StatusDto detalleStatus;
		StatusDto detalleStatusReq;
		StatusDto detalleStatusWork;
		StatusDto detalleStatusTerm;
		TypeUnitDto detalleType;
		TypesUnitDto detalleTypes;
		TypesUnitDto detalleTypesD;
		ExternalreqsRecordDto detalleRecord;
		PrivilegesAllDto detallePrivilege;
		List<UnitsUsersDto> listasUnits = new ArrayList<>();
		List<ExternalreqsRecordDto> listasRecord = new ArrayList<>();

		List<TypesUnitDto> listasTypes = new ArrayList<>();
		List<TypesUnitDto> listasTypesD = new ArrayList<>();
		Long cuantosregistro = (long) 0;

		// List<PrivilegesDto> 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();
		int idUser;

		int idrol, searchIdStrategyGeneral, searchUnitid;
		String searchIn = "";
		String searchListUnit = "";
		String contentIn = "";
		int searchIdRequester;
		int searchIdWorker;
		// String searchModule = "";
		int searchStatus = 0;
		int searchVP, searchFacility, searchType;
		String fechaComoCadena;
		int orderIn = 0;
		int offsetIn = 0;
		int numofrecordsIn = 0;
		Optional<Params> deSessDuration = paramsRepository.findByParamname("SESSION_DURATION");
		String SessionDuration = deSessDuration.get().getValue();
		int duracionSession = Integer.parseInt(SessionDuration);
		Date fecha2 = new Date();

		Optional<Users> encontreSessionUsuario;

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

			sessionid = sessionid.substring(7);
			encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			idUser = encontreSessionUsuario.get().getId();

			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);
					// return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);

				}

				// Este proceso permite obtener un listado de las unidades. (Priv 110)
				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 320);
				// validando privilegio de DRP
				// rolisvalidDRP = auditRepository.getCantbyRolAndPrivi(idrol, 314);

				if (rolisvalid == 0) {

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

				}

				//searchIn = tiposfiltros.getFilters().getSearch();
				searchIn = tiposfiltros.getFilters().getSearch();
				
			    String Salida = usersService.verificarCaracteresValidosConRegex(searchIn);
				  
				  if (Salida=="NOOK") {
					  String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						//respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Caracteres no permitidos en la busqueda"); 
						return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				  }
				   
			   searchIn = usersService.eliminarAcentosService(tiposfiltros.getFilters().getSearch());
				searchStatus = tiposfiltros.getFilters().getStatus();
				searchIdRequester = tiposfiltros.getFilters().getRequesterid();
				searchIdWorker = tiposfiltros.getFilters().getWorkerid();
				searchType = tiposfiltros.getFilters().getUnittype();
				orderIn = tiposfiltros.getOrder();
				offsetIn = tiposfiltros.getOffset();
				numofrecordsIn = tiposfiltros.getNumofrecords();
				// se verifica si viene el content null o not null para insertar en la tabla
				// access para el armado de los shorcuts
				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);
			}
		}

		// String Cadena = "elemento ->>";

		try {

			String SentenciaBase = " SELECT  ex.id,ex.status,re.id AS idrequester,re.name AS namerequester, "
					+ "	wo.id idwork,wo.name namework,ex.requirements,ex.scenary,ex.plan,pr.valor,pr.descr "
					+ "    FROM main.externalreqs ex  " + "	LEFT JOIN main.requesters re ON  re.id = ex.requesterid "
					+ "	LEFT JOIN main.workers wo ON wo.id = ex.workerid "
					+ "	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 = 'EXTERNALREQ_TERM' ) pr ON ex.externalreqtermpar = CAST(pr.valor AS integer) ";

			String SetenciaDependencia = "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 = 'EXTERNALREQ_TERM' ORDER BY valor ASC";

			String QueryTotal = "";
			// String SentenciaBase = "";
			String status = "ex.status";
			String LowerSearch = searchIn.toLowerCase();

			switch (searchStatus) {
			case 0: // Busca por cualquier estatus
				QueryTotal = SentenciaBase + " WHERE 1 = 1 ";
				// QueryTotal = SentenciaBase;
				break;
			case 1: // Busca por estatus activo

				QueryTotal = SentenciaBase + " WHERE " + status + " = " + searchStatus;
				// QueryTotal = SentenciaBase + " AND " + status + " = " + searchStatus;
				break;
			case 2: // Busca por estatus Inactivo

				// QueryTotal = SentenciaBase + " WHERE " + "u.status" + " = " + 0;
				QueryTotal = SentenciaBase + " WHERE " + " ex.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("Llamada al servicio malformado");
				estatus = HttpStatus.BAD_REQUEST;
				return new ResponseEntity(respuestaDto, estatus);

			}

			switch (searchIdRequester) { // busqueda por entidad solicitante
			case 0: // Busca por cualquier estatus
				QueryTotal = QueryTotal;
				break;

			default: // viene con el parametro para buscar por el like
				QueryTotal = QueryTotal + " AND  re.id = " + searchIdRequester;

			}

			switch (searchIdWorker) { // busca por el responsable
			case 0:
				QueryTotal = QueryTotal;
				break;

			default:
				QueryTotal = QueryTotal + " AND  wo.id = " + searchIdWorker;

			}

			switch (searchIn) {
			case "": // viene sin busqueda por el like

				QueryTotal = QueryTotal;
				break;

			default: // viene con el parametro para buscar por el like
				//QueryTotal = QueryTotal + " AND " + " LOWER(ex.requirements)" + " LIKE " + "'%" + LowerSearch + "%'"
				QueryTotal = QueryTotal + " AND " + " main.sinacentos(LOWER(ex.plan)) " + " LIKE main.sinacentos(" + "'%" + LowerSearch + "%')"
						+ " OR main.sinacentos(LOWER(ex.scenary)) LIKE main.sinacentos(" + "'%" + LowerSearch + "%')";

			}

			// String groupby = " GROUP BY
			// ed.id,ed.status,e.id,e.name,pr.descr,pr.valor,pr2.descr,pr2.valor,su.id,su.name,ap.id,ap.name,re.id,re.name,fa.id,fa.name,po.id,po.name";
			String groupby = "	GROUP BY ex.id,ex.status,re.id,re.name,wo.id,wo.name,ex.requirements,ex.scenary,ex.plan,pr.valor,pr.descr ";

			QueryTotal = QueryTotal + groupby;

			Query query = entityManager.createNativeQuery(QueryTotal);
			cuantosregistro = (long) query.getResultList().size();

			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("Llamada al servicio malformado");
				estatus = HttpStatus.BAD_REQUEST;
				return new ResponseEntity(respuestaDto, estatus);
			}

			int absolutoOrden = Math.abs(orderIn);

			switch (absolutoOrden) {
			case 1: // ordena por dsc ascendente

				QueryTotal = QueryTotal + " ORDER BY " + "re.name" + ordena;
				break;
			case 2: // ordena por status ascendente

				QueryTotal = QueryTotal + " ORDER BY " + "ex.scenary" + ordena;

				break;
			case 3: // ordena por status ascendente

				QueryTotal = QueryTotal + " ORDER BY " + " wo.name " + ordena;
				break;
			
			case 4: // ordena por status 

				//QueryTotal = QueryTotal + " ORDER BY " + " wo.name " + ordena;
				QueryTotal = QueryTotal + " ORDER BY " + " ex.status " + ordena;
				break;

			case 99: // ordena por status ascendente

				QueryTotal = QueryTotal + " ORDER BY " + "ex.id" + ordena;
				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);

			}

			Query queryDependencia = entityManager.createNativeQuery(SetenciaDependencia);
			List<Object[]> listadepen = queryDependencia.getResultList();
			for (Object[] types : listadepen) {
				detalleTypesD = new TypesUnitDto();

				detalleTypesD.setDsc((String) types[0]);
				detalleTypesD.setValue((String) types[1]);
				listasTypesD.add(detalleTypesD);
			}

			query = entityManager.createNativeQuery(QueryTotal);
			query.setFirstResult(offsetIn);
			query.setMaxResults(numofrecordsIn);
			List<Object[]> listacompleta = query.getResultList();

			for (Object[] reg : listacompleta) {

				detalleStatus = new StatusDto();
				detalleStatusReq = new StatusDto();
				detalleStatusWork = new StatusDto();
				detalleStatusTerm = new StatusDto();
				detalleType = new TypeUnitDto();
				detalleRecord = new ExternalreqsRecordDto();
				// ExternalreqsRecordDto detalleRecord;

				detalleRecord.setId((int) reg[0]);

				detalleStatus.setId((int) reg[1]);

				if ((int) reg[1] == 1) {
					detalleStatus.setName("Activo");

				} else {
					detalleStatus.setName("Inactivo");
				}

				detalleRecord.setStatus(detalleStatus);

				detalleStatusReq.setId((int) reg[2]);
				detalleStatusReq.setName((String) reg[3]);

				detalleRecord.setRequester(detalleStatusReq);

				detalleStatusWork.setId((int) reg[4]);
				detalleStatusWork.setName((String) reg[5]);

				detalleRecord.setWorker(detalleStatusWork);

				detalleRecord.setRequerimientos((String) reg[6]);

				String term = (String) reg[9];
				int termint = Integer.parseInt(term);

				detalleStatusTerm.setId(termint);
				detalleStatusTerm.setName((String) reg[10]);

				detalleRecord.setTerm(detalleStatusTerm);

				detalleRecord.setScenary((String) reg[7]);
				detalleRecord.setPlan((String) reg[8]);

				listasRecord.add(detalleRecord);
			}

			detallePrivilege = new PrivilegesAllDto();

			boolean tieneView = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 320);
			boolean tieneUpdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 321);
			boolean tieneAdd = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 322);
			boolean tieneDelete = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 323);
			// existsByRolidAndPrivilegeid

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

			externalreqsResponseDto.setNumofrecords(cuantosregistro);
			externalreqsResponseDto.setSessionvalidthru(fechaComoCadena);
			externalreqsResponseDto.setRecords(listasRecord);
			externalreqsResponseDto.setPrivileges(detallePrivilege);
			externalreqsResponseDto.setTerm(listasTypesD);

			return ResponseEntity.ok(externalreqsResponseDto);

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

		}

		return new ResponseEntity(respuesta, estatus);

	}

	@GetMapping("/externalreqs/{externalreqid}")
	public ResponseEntity<?> getOneexternalreqs(HttpServletRequest request,
			@PathVariable("externalreqid") final Integer externalreqid) throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		ExternalReqsDetailRespondeDto externalreqsDetailResponseDto = new ExternalReqsDetailRespondeDto();
		// ParamsDto detalleParams;
		UnitsUsersDto detalleUnits;
		StatusDto detalleStatus;
		StatusDto detalleStatusReq;
		StatusDto detalleStatusWork;
		StatusDto detalleStatusTerm;
		TypeUnitDto detalleType;
		TypesUnitDto detalleTypes;
		TypesUnitDto detalleTypesD;
		ExternalreqsRecordDto detalleRecord = null;
		PrivilegesAllDto detallePrivilege;
		List<UnitsUsersDto> listasUnits = new ArrayList<>();
		List<ExternalreqsRecordDto> listasRecord = new ArrayList<>();

		List<TypesUnitDto> listasTypes = new ArrayList<>();
		List<TypesUnitDto> listasTypesD = new ArrayList<>();
		Long cuantosregistro = (long) 0;

		// List<PrivilegesDto> 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();
		int idUser;

		int idrol, searchIdStrategyGeneral, searchUnitid;
		String searchIn = "";
		String searchListUnit = "";
		String contentIn = "";
		int searchIdRequester;
		int searchIdWorker;
		// String searchModule = "";
		int searchStatus = 0;
		int searchVP, searchFacility, searchType;
		String fechaComoCadena;
		int orderIn = 0;
		int offsetIn = 0;
		int numofrecordsIn = 0;
		Optional<Params> deSessDuration = paramsRepository.findByParamname("SESSION_DURATION");
		String SessionDuration = deSessDuration.get().getValue();
		int duracionSession = Integer.parseInt(SessionDuration);
		Date fecha2 = new Date();

		Optional<Users> encontreSessionUsuario;

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

			sessionid = sessionid.substring(7);
			encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			idUser = encontreSessionUsuario.get().getId();

			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);
					// return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);

				}

				// Este proceso permite obtener un listado de las unidades. (Priv 110)
				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 320);
				// validando privilegio de DRP
				// rolisvalidDRP = auditRepository.getCantbyRolAndPrivi(idrol, 314);

				if (rolisvalid == 0) {

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

				}

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

		// String Cadena = "elemento ->>";

		try {

			String SentenciaBase = " SELECT  ex.id,ex.status,re.id AS idrequester,re.name AS namerequester, "
					+ "	wo.id idwork,wo.name namework,ex.requirements,ex.scenary,ex.plan,pr.valor,pr.descr "
					+ "    FROM main.externalreqs ex  " + "	LEFT JOIN main.requesters re ON  re.id = ex.requesterid "
					+ "	LEFT JOIN main.workers wo ON wo.id = ex.workerid "
					+ "	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 = 'EXTERNALREQ_TERM' ) pr ON ex.externalreqtermpar = CAST(pr.valor AS integer) ";

			String QueryTotal = "";
			// String SentenciaBase = "";

			QueryTotal = SentenciaBase + " WHERE ex.id = " + externalreqid;

			String groupby = "	GROUP BY ex.id,ex.status,re.id,re.name,wo.id,wo.name,ex.requirements,ex.scenary,ex.plan,pr.valor,pr.descr ";

			QueryTotal = QueryTotal + groupby;

			Query query = entityManager.createNativeQuery(QueryTotal);
			cuantosregistro = (long) query.getResultList().size();

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

			for (Object[] reg : listacompleta) {

				detalleStatus = new StatusDto();
				detalleStatusReq = new StatusDto();
				detalleStatusWork = new StatusDto();
				detalleStatusTerm = new StatusDto();
				detalleType = new TypeUnitDto();
				detalleRecord = new ExternalreqsRecordDto();
				// ExternalreqsRecordDto detalleRecord;

				detalleRecord.setId((int) reg[0]);

				detalleStatus.setId((int) reg[1]);

				if ((int) reg[1] == 1) {
					detalleStatus.setName("Activo");

				} else {
					detalleStatus.setName("Inactivo");
				}

				detalleRecord.setStatus(detalleStatus);

				detalleStatusReq.setId((int) reg[2]);
				detalleStatusReq.setName((String) reg[3]);

				detalleRecord.setRequester(detalleStatusReq);

				detalleStatusWork.setId((int) reg[4]);
				detalleStatusWork.setName((String) reg[5]);

				detalleRecord.setWorker(detalleStatusWork);

				detalleRecord.setRequerimientos((String) reg[6]);

				String term = (String) reg[9];
				int termint = Integer.parseInt(term);

				detalleStatusTerm.setId(termint);
				detalleStatusTerm.setName((String) reg[10]);

				detalleRecord.setTerm(detalleStatusTerm);

				detalleRecord.setScenary((String) reg[7]);
				detalleRecord.setPlan((String) reg[8]);

				listasRecord.add(detalleRecord);
			}

			externalreqsDetailResponseDto.setEntry(detalleRecord);

			return ResponseEntity.ok(externalreqsDetailResponseDto);

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

		}

		return new ResponseEntity(respuesta, estatus);

	}

	@PostMapping("/externalreqs/{externalreqid}")
	public ResponseEntity<?> actualizarexternalreqs(HttpServletRequest request,
			@RequestBody ExternalReqsActualizarDto externalReqsActualizarDto,
			@PathVariable("externalreqid") final Integer externalreqid) 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<Operationlines> operationLines;

		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 (externalreqid != 0) {// actualizar requerimiento externo
					try {
						// verifico si tiene el privilegio
						rolisvalid = auditRepository
								.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 321);
						if (rolisvalid == 0) {
							respuesta.setMsg("No tiene los Privilegios");
							estatus = HttpStatus.FORBIDDEN;
							return new ResponseEntity(respuesta, estatus);
						}
						
						//searchIn = tiposfiltros.getFilters().getSearch();
						
					    String Salida = usersService.verificarCaracteresValidosConRegex(externalReqsActualizarDto.getScenary());
						  
						  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 externalreqs en la base de datos
						Optional<Externalreqs> obtExternalreqs = externalreqsRepository.findById(externalreqid);
						Externalreqs externalreqs = new Externalreqs();
						Externalreqs externalreqs3 = new Externalreqs();
						// Verifico si encontre el proceso
						if (obtExternalreqs.isPresent()) {
							externalreqs = obtExternalreqs.get();
						} else {
							respuesta.setMsg("Registro no encontrado");
							return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
						}

						// Construyo los datos de la entidad de externalreqs
						externalreqs.setStatus(externalReqsActualizarDto.getStatus());
						 externalreqs.setPlan(externalReqsActualizarDto.getPlan());
						 externalreqs.setExternalreqtermpar(Integer.parseInt(externalReqsActualizarDto.getExternaltermpar()));
						 externalreqs.setRequesterid(externalReqsActualizarDto.getRequesterid());
						 externalreqs.setRequirements(externalReqsActualizarDto.getRequirements());
						 externalreqs.setScenary(externalReqsActualizarDto.getScenary());
						 externalreqs.setWorkerid(externalReqsActualizarDto.getWorkerid());
						externalreqs.setModifiedat(fecha2);

						externalreqs3 = externalreqsRepository.save(externalreqs);

						if (externalreqs3 != null) {
							module = "Entidades Externas";
							Descmodule = "Se actualizó la Entidad Externa: " + externalreqs3.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(externalreqs3.getId());
							URI location = URI.create("/externalreqs/" + externalreqs3.getId()); // O la URL correcta para // tu
							return ResponseEntity.created(location).body(respuestaValueDto);

						}
					} catch (Exception e) {
						respuesta.setMsg("Error interno del servidor ");
						estatus = HttpStatus.INTERNAL_SERVER_ERROR;
					}
				} else {
					try{ 
						rolisvalid=auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 322); 
						 if (rolisvalid == 0) {
							 respuesta.setMsg("No tiene los Privilegios"); 
							 estatus = HttpStatus.FORBIDDEN;
							 return new ResponseEntity(respuesta, estatus); 
					     }
						 
						 
						 //Construyo los datos de la entidad de Externalreqs			 
						 Externalreqs externalreqs = new Externalreqs();
						 Externalreqs externalreqs3 = new Externalreqs();
						 externalreqs.setStatus(externalReqsActualizarDto.getStatus());
						 externalreqs.setPlan(externalReqsActualizarDto.getPlan());
						 externalreqs.setExternalreqtermpar(Integer.parseInt(externalReqsActualizarDto.getExternaltermpar()));
						 externalreqs.setRequesterid(externalReqsActualizarDto.getRequesterid());
						 externalreqs.setRequirements(externalReqsActualizarDto.getRequirements());
						 externalreqs.setScenary(externalReqsActualizarDto.getScenary());
						 externalreqs.setWorkerid(externalReqsActualizarDto.getWorkerid());
						 externalreqs.setModifiedat(fecha2);
						 externalreqs.setCreatedat(fecha2);
						 
						 externalreqs3 = externalreqsRepository.save(externalreqs);

							if (externalreqs3 != null) {
								module = "Entidades Externas";
								Descmodule = "Se agregó la Entidad Externa: " + externalreqs3.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(externalreqs3.getId());
								URI location = URI.create("/externalreqs/" + externalreqs3.getId()); // O la URL correcta para // tu
								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);
						 }
				}
			}
			return new ResponseEntity(respuesta, HttpStatus.OK);
		}

	}
	
	@DeleteMapping("/externalreqs/{externalreqid}")
	public ResponseEntity<?> deleteexternalreqs(HttpServletRequest request,
			@PathVariable("externalreqid") final Integer externalreqid) 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(), 323); 
					if (rolisvalid == 0) {
						respuesta.setMsg("No tiene los Privilegios"); 
						estatus = HttpStatus.FORBIDDEN;
						return new ResponseEntity(respuesta, estatus); 
					}
					
					// Verifico si existe el id de externalreqs en la base de datos
					Optional<Externalreqs> obtExternalreqs = externalreqsRepository.findById(externalreqid);
					Externalreqs externalreqs = new Externalreqs();
					Externalreqs externalreqs3 = new Externalreqs();
					
				    //Verifico si encontre el requisito externos
				    if (obtExternalreqs.isPresent()) {
				    	externalreqs=obtExternalreqs.get();
				    }else {
				    	respuesta.setMsg("Registro no encontrado");
						return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
				    }
				    
				    try {
					    					    
					    
				    	externalreqsRepository.deleteExternalreqsbyid(externalreqs.getId());
						
						module = "Entidades Externas";
						Descmodule = "Se borró la Entidad Externa: " + externalreqs.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(externalreqs.getId()); 
						URI location = URI.create("/externalreqs/" + externalreqs.getId()); // O la URL correcta para // tu
						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);
		}	
	}
}
