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.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.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.CompaniesActualizarDto;
import com.dacrt.SBIABackend.dto.CompaniesDto;
import com.dacrt.SBIABackend.dto.CompaniesListDto;
import com.dacrt.SBIABackend.dto.CompaniesResponseDto;
import com.dacrt.SBIABackend.dto.EntryCompaniesDto;
import com.dacrt.SBIABackend.dto.OperationActualizarDto;
import com.dacrt.SBIABackend.dto.PrivilegesDto2;
import com.dacrt.SBIABackend.dto.ResourcesDto;
import com.dacrt.SBIABackend.dto.ResourcesResponseDto2;
import com.dacrt.SBIABackend.dto.ResourcesStatusDto;
import com.dacrt.SBIABackend.dto.StatusDto;
import com.dacrt.SBIABackend.dto.StatusDto2;
import com.dacrt.SBIABackend.dto.responseDto.ResourcesResponseDto;
import com.dacrt.SBIABackend.entity.Companies;
import com.dacrt.SBIABackend.entity.Resources;
import com.dacrt.SBIABackend.repository.CompaniesRepository;
import com.dacrt.SBIABackend.repository.ResourceRepository;
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.RoleDto;
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.ResourcesService;
import com.dacrt.SBIABackend.utils.HttpReqRespUtils;

@RestController
//@RequestMapping("/units")   
@CrossOrigin(origins = "*")
public class CompaniesController {
	@Autowired
	private ParamsRepository paramsRepository;

	@Autowired
	private UsersRepository usersRepository;

	@Autowired
	private AuditRepository auditRepository;

	@Autowired
	private CompaniesRepository companiesRepository;

	@Autowired
	private RolesPrivilegesRepository rolesPrivilegesRepository;

	@Autowired
	UsersService usersService;

	@Autowired
	ParamsService paramsService;

	@Autowired
	SecurityService securityService;

	@Autowired
	MenuService menuService;

	@PersistenceContext
	private EntityManager entityManager;

	@PostMapping("/companies")
	public ResponseEntity<?> listadoCompanies(HttpServletRequest request, @RequestBody CompaniesListDto tiposfiltros)
			throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;

		PrivilegesAllDto detallePrivilege;
		Long cuantosregistro = (long) 0;
		List<PrivilegesDto2> 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 idrol;
		String searchIn = "";
		String contentIn = "";
		int searchStatus = 0;
		int formatList = 0;
		String fechaComoCadena;
		int orderIn = 0;
		int offsetIn = 0;
		int numofrecordsIn = 0;
		Date fecha2 = new Date();

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

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

			if (encontreSessionUsuario.isPresent()) {

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

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

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

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

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

		try {

			// Sentencia General
			String SentenciaBase = "SELECT u.id,u.name,u.status,"
					+ "                    CASE WHEN u.status = 1 then 'Activo' ELSE 'Inactivo' END AS estatus,"
					+ "                    u.dsc,u.createdat " 
					+ "             FROM main.companies u";

			String QueryTotal = "";
			String name = "u.name";
			String status = "u.status";
			String fechaCreacion = "u.createdat";
			String descr = "u.dsc";
			String lowername = "LOWER(u.name)";
			String lowerdsc = "LOWER(u.dsc)";
			String LowerSearch = searchIn.toLowerCase();

			switch (searchIn) {
				case "": QueryTotal = SentenciaBase + " WHERE TRUE = TRUE";
					     break;
				default: QueryTotal = SentenciaBase + " WHERE (" + lowername + " LIKE  " + "'%" + LowerSearch + "%' OR "
							+ lowerdsc + " LIKE " + "'%" + LowerSearch + "%' )";
			}

			switch (searchStatus) {
				case 0:
					QueryTotal = QueryTotal;
					break;
				case 1:
					QueryTotal = QueryTotal + " AND " + status + " = " + searchStatus;
					break;
				case 2:
					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);
			}
			
			String ordena = "";
			if (orderIn == 1 || orderIn == 2 || orderIn == 3) {
				ordena = " ASC";
			} else if (orderIn == -1 || orderIn == -2 || orderIn == -3) {
				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:
					QueryTotal = QueryTotal + " ORDER BY " + fechaCreacion + ordena;
					break;
				case 2:
					QueryTotal = QueryTotal + " ORDER BY " + name + ordena;
					break;
				case 3:
					QueryTotal = QueryTotal + " ORDER BY " + status + 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 queryCompanies = entityManager.createNativeQuery(QueryTotal);
			queryCompanies.setFirstResult(offsetIn);
			queryCompanies.setMaxResults(numofrecordsIn);
			List<Object[]> listacompleta = queryCompanies.getResultList();
			cuantosregistro = (long) queryCompanies.getResultList().size();
			CompaniesDto detalleCompanies = new CompaniesDto();
			StatusDto2 detalleStatus = new StatusDto2();
			List<CompaniesDto> records = new ArrayList();
			CompaniesResponseDto listado = new CompaniesResponseDto();
			
			for (Object[] fila : listacompleta) {
				detalleCompanies.setId((int) fila[0]);
				detalleCompanies.setName((String) fila[1]);
				detalleCompanies.setDsc((String) fila[4]);
				detalleStatus.setId((int) fila[2]);
				detalleStatus.setName((String) fila[3]);
				detalleCompanies.setStatus(detalleStatus);

				records.add(detalleCompanies);
				
				detalleCompanies = new CompaniesDto();
				detalleStatus = new StatusDto2();
			}

			detallePrivilege = new PrivilegesAllDto();
			boolean tieneView = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 390);
			boolean tieneUpdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 391);
			boolean tieneAdd = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 392);
			boolean tieneDelete = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 393);

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

			listado.setNumofrecords(cuantosregistro);
			// paramsResponseDto.setValidthru(ValidThrufechaSalida);
			listado.setSessionvalidthru(fechaComoCadena);
			listado.setRecords(records);
			listado.setPrivileges(detallePrivilege);
			return ResponseEntity.ok(listado);
			

		} 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("/companies/{companyid}")
	public ResponseEntity<?> obtenerUnoCompanies(HttpServletRequest request, 
			@PathVariable("companyid") final Integer companyid)
			throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;

		PrivilegesAllDto detallePrivilege;
		Long cuantosregistro = (long) 0;
		List<PrivilegesDto2> 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 idrol;
		String fechaComoCadena;
		Date fecha2 = new Date();

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

			sessionid = sessionid.substring(7);
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);

			if (encontreSessionUsuario.isPresent()) {
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

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

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

				if (rolisvalid == 0) {
					respuesta.setMsg("No tiene los Privilegios");
					estatus = HttpStatus.FORBIDDEN;
					return new ResponseEntity(respuesta, estatus);
				}
			} else {
				String var = "";
				boolean bloked = false;
				RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
				respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Sesión expirada o inválida");
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

			// Sentencia General
			String SentenciaBase = "SELECT u.id,u.name,u.status,"
					+ "                    CASE WHEN u.status = 1 then 'Activo' ELSE 'Inactivo' END AS estatus,"
					+ "                    u.dsc,u.createdat " 
					+ "             FROM main.companies u"
					+ "				WHERE u.id = :companyid";

			Query queryCompanies = entityManager.createNativeQuery(SentenciaBase);
			queryCompanies.setParameter("companyid", companyid);
			cuantosregistro = (long) queryCompanies.getResultList().size();
			
			List<Object[]> listacompleta = queryCompanies.getResultList();
			
			CompaniesDto detalleCompanies = new CompaniesDto();
			StatusDto2 detalleStatus = new StatusDto2();
			EntryCompaniesDto entryReponse = new EntryCompaniesDto();
			
			if (cuantosregistro>0) {
				for (Object[] fila : listacompleta) {
					detalleCompanies.setId((int) fila[0]);
					detalleCompanies.setName((String) fila[1]);
					detalleCompanies.setDsc((String) fila[4]);
					detalleStatus.setId((int) fila[2]);
					detalleStatus.setName((String) fila[3]);
					detalleCompanies.setStatus(detalleStatus);

					entryReponse.setEntry(detalleCompanies);
				}
			}else {
				String var = "";
		    	RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
				respuestaDto.setMsg("Registro No encontrado");
				return new ResponseEntity(respuestaDto, HttpStatus.NOT_FOUND);
			}
				
			return ResponseEntity.ok(entryReponse);
			

		} 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);
	}
	
	@PostMapping("/companies/{companyid}")
	public ResponseEntity<?> actualizarCompanies(HttpServletRequest request,
			@RequestBody CompaniesActualizarDto companiesActualizarDto,
			@PathVariable("companyid") final Integer companyid) 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 (companyid != 0) {// actualizar la compañia

					try {
						// verifico si tiene el privilegio
						rolisvalid = auditRepository
								.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 391);
						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 (companiesActualizarDto.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(companiesActualizarDto.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
						Optional<Companies> companies = companiesRepository.findById(companyid);
						
						
						Companies companies1 = new Companies();
						
						
						Companies companies2 = new Companies();
						// Verifico si encontre la Companies
						if (!companies.isPresent()) {
							respuesta.setMsg("Registro no encontrado");
							return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
						}

						companies1=companies.get();
						
						// Verificar si el nombre del  existe en la base de datos
						if (companiesRepository.existsByName(companiesActualizarDto.getName()) && companiesRepository.getByName(companiesActualizarDto.getName()).get().getId()!=companyid) {
							respuesta.setMsg("Registro Duplicado");
							return new ResponseEntity(respuesta, HttpStatus.CONFLICT);
						}

						// Construyo los datos de la entidad de Compañías
						companies1.setStatus(companiesActualizarDto.getStatus());
						companies1.setName(companiesActualizarDto.getName());
						companies1.setDsc(companiesActualizarDto.getDsc());
						companies1.setCreatedat(companies.get().getCreatedat());
						companies1.setModifiedat(fecha2);

						companies2 = companiesRepository.save(companies1);

						if (companies2 != null) {
							
							module = "Compañías";
							Descmodule = "Se actualizó la Compañías: " + companies2.getName() + " con id: "+companies2.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(companyid);
							URI location = URI.create("/companies/" + companyid); // O la URL correcta para la companies

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

				} else { // incluir compañía

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

						
						Companies companies1 = new Companies();
						Companies companies2 = new Companies();
						
						//Construyo los datos de la entidad Compañía
						companies1.setStatus(companiesActualizarDto.getStatus());
						companies1.setName(companiesActualizarDto.getName());
						companies1.setDsc(companiesActualizarDto.getDsc());
						companies1.setModifiedat(fecha2);
						companies1.setCreatedat(fecha2);
						
						companies2 = companiesRepository.save(companies1);

						try {
							if (companies2 != null) {
								
								module = "Compañías";
								Descmodule = "Se insertó la Compañía: " + companies2.getName() + " con id: "+companies2.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(companies2.getId());
								URI location = URI.create("/companies/" + companies2.getId()); // O la URL correcta para la compañía
								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("/companies/{companyid}")
	public ResponseEntity<?> borrarCompanies(HttpServletRequest request,
			@PathVariable("companyid") final Integer companyid) throws ParseException {
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		RoleDto detalleRoles;
		PrivilegesAllDto detallePrivilege;

		String var = "";
		boolean bloked = false;
		RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
		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();
		RespuestaValueDto respuestaValueDto;
		String searchIn = "";

		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.

		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus = HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {
			sessionid = sessionid.substring(7);
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);

			if (encontreSessionUsuario.isPresent()) {
				String fechaComoCadena;
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());
				
				if (fechaComoCadena == "") {
					String var2 = "";
					boolean bloked2 = false;
					RespuestaMsgDto respuestaDto2 = new RespuestaMsgDto(var2);
					// respuestaDto.setBlocked(bloked);
					respuestaDto2.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);

				}

				Roles roles = encontreSessionUsuario.get().getRolid();
				int idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 393);
	
				if (rolisvalid == 0) {
					RespuestaMsgDto respuestaPrivDto = new RespuestaMsgDto(var);
					// respuestaDto.setBlocked(bloked);
					respuestaPrivDto.setMsg("No tiene los Privilegios");
					return new ResponseEntity(respuestaPrivDto, HttpStatus.FORBIDDEN);

				}

				try {

					if (companiesRepository.existsById(companyid)) {
						Optional<Companies> company = companiesRepository.findById(companyid);
						
						//Compruebo que la comáñia no este asociada a un usuario
						if (companiesRepository.existsByCompanyCampana(companyid)) {
						    respuesta.setMsg("No se pudo borrar debido a que la compañía está asociada a una o más campañas");
						    return new ResponseEntity<>(respuesta, HttpStatus.CONFLICT);
						}

						if (companiesRepository.existsByCompanyUnidad(companyid)) {
						    respuesta.setMsg("No se pudo borrar debido a que la compañía está asociada a una o más unidades");
						    return new ResponseEntity<>(respuesta, HttpStatus.CONFLICT);
						}

						if (companiesRepository.existsByCompanyUsuario(companyid)) {
						    respuesta.setMsg("No se pudo borrar debido a que la compañía está asociada a uno o más usuarios");
						    return new ResponseEntity<>(respuesta, HttpStatus.CONFLICT);
						}
						
						if (companiesRepository.existsByCompanyPosition(companyid)) {
						    respuesta.setMsg("No se pudo borrar debido a que la compañía está asociada a uno o más cargos");
						    return new ResponseEntity<>(respuesta, HttpStatus.CONFLICT);
						}
							
						//Borro la compañía
						companiesRepository.delete(company.get());
						
						String module = "Compañías";
						String Descmodule = "Se eliminó la compañia: " + company.get().getName() + " con Id: "
								+ companyid;

						auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());

						String singo1 = "(";
						String singo2 = ")";
						String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1)
								.concat(encontreSessionUsuario.get().getEmail().concat(singo2));
						auditDto.setUserref(usryemail);
						auditDto.setModule(module);
						auditDto.setDesc(Descmodule);
						auditDto.setCreatedat(fechaDate);
						usersService.registrarAuditSesion(auditDto);

						respuestaValueDto = new RespuestaValueDto(companyid);
						URI location = URI.create("/companies/" + companyid); // O la URL correcta de companies
						return ResponseEntity.created(location).body(respuestaValueDto);
						
					} else {// Registro no encontrado
						respuesta.setMsg("Registro no encontrado");
						estatus = HttpStatus.NOT_FOUND;
						return new ResponseEntity(respuesta, estatus);

					}

				} catch (Exception e) {// Error Interno
					// Manejo de excepciones
					respuesta.setMsg("Error interno del servidor");
					estatus = HttpStatus.INTERNAL_SERVER_ERROR;
					return new ResponseEntity(respuesta, estatus);
				} finally {
					if (entityManager != null && entityManager.isOpen()) {
						entityManager.close();
					}
				}
			} else {
				respuesta.setMsg("Sesión expirada o inválida");
				estatus = HttpStatus.UNAUTHORIZED;
				return new ResponseEntity(respuesta, estatus);

			}

		}

	}
	
}
