package com.dacrt.SBIABackend.controler;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
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.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
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.AppTypeDto;
import com.dacrt.SBIABackend.dto.ApplicationDto;
import com.dacrt.SBIABackend.dto.ApplicationDto2;
import com.dacrt.SBIABackend.dto.ApplicationResponseDto2;
import com.dacrt.SBIABackend.dto.AppstrategyHeaderDto;
import com.dacrt.SBIABackend.dto.AppstrategyResponseDto;
import com.dacrt.SBIABackend.dto.CampaignFormat2Dto;
import com.dacrt.SBIABackend.dto.ChannelDto;
import com.dacrt.SBIABackend.dto.ChannelDto2;
import com.dacrt.SBIABackend.dto.ContentDto;
import com.dacrt.SBIABackend.dto.DrptestDto;
import com.dacrt.SBIABackend.dto.DrptestedDto3;
import com.dacrt.SBIABackend.dto.DrptesttypesDto;
import com.dacrt.SBIABackend.dto.FacilityDto2;
import com.dacrt.SBIABackend.dto.PeriodParResponseDto;
import com.dacrt.SBIABackend.dto.RecordCatalogoResponseDto;
import com.dacrt.SBIABackend.dto.RecuperationDto;
import com.dacrt.SBIABackend.dto.RegisteredDto;
import com.dacrt.SBIABackend.dto.ResultDto;
import com.dacrt.SBIABackend.dto.ServiceOffers6Dto;
import com.dacrt.SBIABackend.dto.StatusDto;
import com.dacrt.SBIABackend.dto.StatusDto2;
import com.dacrt.SBIABackend.dto.TestTypeResquestDto;
import com.dacrt.SBIABackend.dto.TestedDto;
import com.dacrt.SBIABackend.dto.TypeDto;
import com.dacrt.SBIABackend.dto.ValueDto;
import com.dacrt.SBIABackend.dto.responseDto.ApplicationResponseDto;
import com.dacrt.SBIABackend.repository.ApplicationsRepository;
import com.dacrt.SBIABackend.repository.FacilitiesRepository;
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.UsersListDto;
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;

@RestController
@CrossOrigin(origins = "*")
public class AppstrategypropController {
	@Autowired
	private ParamsRepository paramsRepository;

	@Autowired
	private UsersRepository usersRepository;

	@Autowired
	private AuditRepository auditRepository;

	@Autowired
	private RolesPrivilegesRepository rolesPrivilegesRepository;

	@Autowired
	UsersService usersService;

	@Autowired
	ParamsService paramsService;

	@Autowired
	SecurityService securityService;

	@Autowired
	MenuService menuService;

	@PersistenceContext
	private EntityManager entityManager;

	@Autowired
	SuppliersRepository suppliersRepository;
	
	@Autowired
	ApplicationsRepository applicationsRepository;
	
	@Autowired
	FacilitiesRepository facilitiesRepository;
	
	@PostMapping("/dashboard/appstrategyprop")
	public ResponseEntity<?> applications(HttpServletRequest request, 
			@RequestBody TestTypeResquestDto tiposfiltros)
			throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		ApplicationResponseDto applicationResponseDto = new ApplicationResponseDto();
		ApplicationResponseDto2 applicationResponseDto2 = new ApplicationResponseDto2();
		RecordCatalogoResponseDto appFormatResponseDto = new RecordCatalogoResponseDto();
		// ParamsDto detalleParams;
		ApplicationDto detalleApplication;
		ApplicationDto2 detalleApplication2;
		StatusDto detalleStatus;
		PrivilegesAllDto detallePrivilege;
		FacilityDto2 detallefacility;
		Long cuantosregistro = (long) 0;
		CampaignFormat2Dto detalleCompaing2;

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

		int idrol;
		String testtypeIn = "";
		String drptestyesnoparSearch = "";
		String apptypeSearch = "";
		String contentIn = "";
		int searchStatus = 0;
		int facilityIn = 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);
				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);

				}
				
				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 700);
				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);

				}
				

				testtypeIn = tiposfiltros.getTesttype();
				
				

			} 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 SentenciaBaseIn1 = "";
			Query query;
			Query query3;
		    String tipoTest1;
		    		    
			if (tiposfiltros.getTesttype()=="") { //Por Default
				tipoTest1=" AND a.drptesttypepar in (2) ";
			}    
			else {
				tipoTest1="	AND a.drptesttypepar in ( "+tiposfiltros.getTesttype()+" ) "; 
			}
		    		    
				
			SentenciaBaseIn1 = "WITH aplicaciones_totales AS ( "
					+ "    SELECT "
					+ "        COUNT(DISTINCT s.applicationid) AS cuenta_total "
					+ "    FROM "
					+ "        main.strategiesdet s "
					+ "    INNER JOIN "
					+ "        main.strategies es ON es.id = s.strategyid "
					+ "    INNER JOIN "
					+ "        main.applications a ON s.applicationid = a.id "
					+ "    WHERE "
					+ "        s.applicationid IS NOT NULL "
					+ "        AND es.strategytypepar = 2 "
					+ "        AND a.status = 1 "
					+ "), "
					+ "aplicaciones_probadas AS ( "
					+ "    SELECT "
					+ "        COUNT(a.id) AS cuenta_probadas "
					+ "    FROM "
					+ "	     main.applications a "
					+ "    INNER JOIN "
					+ "        main.strategiesdet s ON a.id = s.applicationid "
					+ "    INNER JOIN "
					+ "        main.strategies es ON es.id = s.strategyid "
					+ "    WHERE es.strategytypepar = 2 "
					+ "        AND a.status = 1 "
					+ tipoTest1
					+ ") "
					+ "SELECT "
					+ "    COALESCE(ap.cuenta_probadas, 0) AS probadas, "
					+ "    COALESCE(at.cuenta_total - ap.cuenta_probadas, 0) AS noprobadas, "
					+ "    COALESCE(ROUND((COALESCE(ap.cuenta_probadas, 0) * 100.0) / NULLIF(at.cuenta_total, 0), 2),0.00) AS porceprobadas,  "
					+ "	   COALESCE(ROUND(((COALESCE(at.cuenta_total, 0) - COALESCE(ap.cuenta_probadas, 0)) * 100.0) / NULLIF(at.cuenta_total, 0), 2),0.00) AS porcenoprobadas "
					+ "FROM "
					+ "    aplicaciones_totales at, "
					+ "    aplicaciones_probadas ap";

			String QueryTotalIn1 = "";
			AppstrategyResponseDto appstrategyResponseDto= new AppstrategyResponseDto();
			AppstrategyHeaderDto appstrategyHeaderDto = new AppstrategyHeaderDto("Proporción de Aplicaciones con Estrategías DRP y Pruebas");
			ContentDto contentDto = new ContentDto();
			ContentDto contentDto2 = new ContentDto();
			List<ContentDto> contentDtoList = new ArrayList();
			ValueDto valueDto = new ValueDto();
			ValueDto valueDto2 = new ValueDto();
			query = entityManager.createNativeQuery(SentenciaBaseIn1);
			Object[] filaProbadas = (Object[]) query.getSingleResult();
			appstrategyResponseDto.setHeader(appstrategyHeaderDto);
			
			contentDto.setName("Probadas");
			valueDto.setPercent(filaProbadas[2].toString());
			valueDto.setNumber(new BigDecimal((BigInteger) filaProbadas[0]));
			contentDto.setValue(valueDto);
			
			contentDtoList.add(contentDto);
			
			contentDto2.setName("No Probadas");
			valueDto2.setPercent(filaProbadas[3].toString());
			valueDto2.setNumber(new BigDecimal((BigInteger) filaProbadas[1]));
			contentDto2.setValue(valueDto2);
			 
			contentDtoList.add(contentDto2);
			appstrategyResponseDto.setContent(contentDtoList);
		
			String QueryTypes = "SELECT CAST(elem AS TEXT) " + "	FROM main.params pa, "
					+ "	jsonb_array_elements(CAST(pa.value AS jsonb)) AS elem "
					+ "	WHERE pa.paramname = 'APPS_TESTTYPE' ";
			
			query3 = entityManager.createNativeQuery(QueryTypes);
			List<Object[]> resultadosTypes;
			DrptesttypesDto drptesttypesDto = new DrptesttypesDto();
			List<DrptesttypesDto> tipoAppList = new ArrayList();
			resultadosTypes = query3.getResultList();
			JSONObject jsonObject;
			String jsonStringTipo = "";
			if (resultadosTypes.size() > 0) {
				for (Object tipos : resultadosTypes) {
					jsonStringTipo = (String) tipos; // Recupera el JSON como String
					jsonObject = new JSONObject(jsonStringTipo); // Convierte String a JSONObject
					// Extrae los valores del JSONObject
					String dsc = jsonObject.getString("dsc");
					String value = jsonObject.getString("value");

					drptesttypesDto.setId(Integer.parseInt(value));
					drptesttypesDto.setName(dsc);
					tipoAppList.add(drptesttypesDto);
					drptesttypesDto = new DrptesttypesDto();
				}
			}
			
			appstrategyResponseDto.setFilters(tipoAppList);
			return ResponseEntity.ok(appstrategyResponseDto);



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

		return new ResponseEntity(respuesta, estatus);

	}
}
