/*
* Copyright 2021 E.J.I.E., S.A.
*
* Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);
* Solo podrá usarse esta obra si se respeta la Licencia.
* Puede obtenerse una copia de la Licencia en
*
* http://ec.europa.eu/idabc/eupl.html
*
* Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,
* el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,
* SIN GARANT�?AS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.
* Véase la Licencia en el idioma concreto que rige los permisos y limitaciones
* que establece la Licencia.
*/
package com.ejie.ad74a.control;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ejie.ad74a.model.Expedientes;
import com.ejie.ad74a.service.ExpedientesService;
import com.ejie.ad74a.util.comun.UtilLiterales;
import com.ejie.ad74a.util.comun.UtilTokenXlnets;
import com.ejie.ad74a.util.constantes.ProcedimientosEnum;
import com.ejie.x38.control.bind.annotation.RequestJsonBody;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.json.JSONArray;
import com.ejie.x38.json.JSONObject;

/**
 * BandejasController generated by UDA, 18-may-2023 12:08:16.
 * 
 * @author UDA
 */
@Controller
@RequestMapping(value = "/bandejas")
public class BandejasController {
	private static final Logger logger = LoggerFactory.getLogger(BandejasController.class);

	@Autowired
	private ExpedientesService expedientesSevice;

	@javax.annotation.Resource
	private ReloadableResourceBundleMessageSource appMessageSource;

	private JSONObject mapaEstadosTotal;

	// Enumerador para no tener que crear en constantes
	private enum EstadosEnum {
		PENDIENTES(1L, "pendientes"), //
		ESTUDIO(2L, "estudio"), //
		SUBSANACION(3L, "subsanacion"), //
		DESISTIMIENTO(4L, "deisitimiento"), //
		RESOLUCION(5L, "resolucion"), //
		NOTIFICAR(6L, "notificar"), //
		CIERRE(7L, "cierre"), //
		FINALIZADAS(8L, "finalizadas");

		private EstadosEnum(Long id, String url) {
			this.id = id;
			this.url = url;
		}

		private Long id;
		private String url;

		public Long getId() {
			return id;
		}

		public String getUrl() {
			return url;
		}

	}

	@GetMapping(value = "/cuadromando")
	public String getCuadroMando(Model model, HttpServletRequest request) {

		Map<String, String> tecnicosExpediente = new HashMap<String, String>();
		try {
			tecnicosExpediente = UtilTokenXlnets.getListTecnicos();
		} catch (Exception e) {
			logger.error("Error al obtener los técnicos");
		}

		model.addAttribute("tecnicos", tecnicosExpediente);
		model.addAttribute("procedimientos", ProcedimientosEnum.getCurrentProcs());
		model.addAttribute("expediente", new Expedientes());
		model.addAttribute("title", UtilLiterales.getLiteralMessage(appMessageSource, "title.cuadroMando"));

		return "cuadroMando";
	}

	/**
	 * Operación de filtrado del componente RUP_TABLE.
	 * 
	 * @param filterBandejaPapel0 Bean BandejaPapel0 que contiene los parámetros de
	 *                            filtrado a emplear.
	 * @param tableRequestDto     Dto que contiene los parámetros de configuración
	 *                            propios del RUP_TABLE a aplicar en el filtrado.
	 *
	 * @return TableResourceResponseDto<BandejaPapel0> Dto que contiene el resultado
	 *         del filtrado realizado por el componente RUP_TABLE.
	 */
	@PostMapping(value = "/filter")
	public @ResponseBody String filter(@RequestJsonBody(param = "expediente") Expedientes expediente,
			@RequestJsonBody TableRequestDto tableRequestDto) {
		BandejasController.logger.info("[POST - filter] : Obtener cuadroMando");

		List<JSONObject> listaDatos = this.expedientesSevice.findCuadroMando(expediente);

		ProcedimientosEnum[] procedimientos;
		if (expediente.getIdProcedimiento00() != null) {
			procedimientos = new ProcedimientosEnum[1];
			procedimientos[0] = ProcedimientosEnum.getById(expediente.getIdProcedimiento00());
		} else {
			procedimientos = ProcedimientosEnum.values();
		}

		return this.procesarCuadroMando(listaDatos, procedimientos);
	}

	private String procesarCuadroMando(List<JSONObject> listaDatos, ProcedimientosEnum[] procedimientos) {

		JSONObject result = new JSONObject();
		JSONArray estados = new JSONArray();

		JSONObject estado = new JSONObject();
		JSONObject totalEstado = new JSONObject();
		mapaEstadosTotal = new JSONObject();

		JSONObject totalProcs = new JSONObject();
		Long estadoActual = -1L;
		String procActual = "";

		// Inicializamos a 0 los totales por procedimiento y por estado
		for (ProcedimientosEnum procedimiento : procedimientos) {
			JSONObject procData = new JSONObject();

//			procData.put("desc", procedimiento.getLabelDesc());
//			procData.put("total", 0L);
//			totalProcs.put(procedimiento.getId(), procData);

			if (!procedimiento.getId().equalsIgnoreCase(ProcedimientosEnum.X87_TEA_1.getId())
					|| !procedimiento.getId().equalsIgnoreCase(ProcedimientosEnum.X87_TEA_2.getId())
					|| !procedimiento.getId().equalsIgnoreCase(ProcedimientosEnum.X87_TEA_4.getId())) {
				procData.put("desc", procedimiento.getLabelDesc());
				procData.put("total", 0L);
				totalProcs.put(procedimiento.getId(), procData);
			}

		}

		for (JSONObject obj : listaDatos) {

			BandejasController.logger.info(obj.toString());

			if (estadoActual.compareTo(-1L) == 0) {
				// Primera vez
				estadoActual = obj.getLong("idEstado");
				estado.put("id", estadoActual);
				estado.put("desces", obj.getString("descEstadoEs"));
				estado.put("desceu", obj.getString("descEstadoEu"));
				estado.put("url", this.getBandejaUrl(estadoActual));

				// Inicializamos a 0 los totales por procedimiento y por estado
				for (ProcedimientosEnum procedimiento : procedimientos) {
					totalEstado.put(procedimiento.getId(), 0L);
				}

				totalEstado.put(obj.getString("idProcedimiento"), obj.getLong("total"));
				estado.put("totales", totalEstado);

			} else if (estadoActual.compareTo(obj.getLong("idEstado")) == 0) {
				// Mismo estado

//				if (procActual.equals(obj.getString("idProcedimiento"))) {
//					Long tot = totalEstado.getLong(obj.getString("idProcedimiento")) + obj.getLong("total");
//					totalEstado.put(obj.getString("idProcedimiento"), tot);
//				} else {
//					totalEstado.put(obj.getString("idProcedimiento"), obj.getLong("total"));
//				}

				Long tot = 0L;
				if (procActual.equals(obj.getString("idProcedimiento"))) {
					tot = totalEstado.getLong(obj.getString("idProcedimiento")) + obj.getLong("total");
				} else {
					tot = obj.getLong("total");
				}
				if (obj.getString("idProcedimiento").equalsIgnoreCase(ProcedimientosEnum.X87_TEA_1.getId())) {
					totalEstado.put(ProcedimientosEnum.ALTA.getId(),
							totalEstado.getLong(ProcedimientosEnum.ALTA.getId()) + tot);
				} else if (obj.getString("idProcedimiento").equalsIgnoreCase(ProcedimientosEnum.X87_TEA_2.getId())) {
					totalEstado.put(ProcedimientosEnum.BAJA.getId(),
							totalEstado.getLong(ProcedimientosEnum.BAJA.getId()) + tot);
				} else if (obj.getString("idProcedimiento").equalsIgnoreCase(ProcedimientosEnum.X87_TEA_4.getId())) {
					totalEstado.put(ProcedimientosEnum.REVISION_PRECIO.getId(),
							totalEstado.getLong(ProcedimientosEnum.REVISION_PRECIO.getId()) + tot);
				} else {
					totalEstado.put(obj.getString("idProcedimiento"), tot);
				}

				estado.put("totales", totalEstado);

			} else {
				// Cambio de estado
				estados.put(estado);
				// Nuevo estado
				estadoActual = (Long) obj.getLong("idEstado");
				estado = new JSONObject();
				estado.put("id", estadoActual);
				estado.put("desces", obj.getString("descEstadoEs"));
				estado.put("desceu", obj.getString("descEstadoEu"));
				estado.put("url", this.getBandejaUrl(estadoActual));

				totalEstado = new JSONObject();
				for (ProcedimientosEnum procedimiento : procedimientos) {
					totalEstado.put(procedimiento.getId(), 0L);
				}

//				totalEstado.put(obj.getString("idProcedimiento"), obj.getLong("total"));

				if (obj.getString("idProcedimiento").equalsIgnoreCase(ProcedimientosEnum.X87_TEA_1.getId())) {
					totalEstado.put(ProcedimientosEnum.ALTA.getId(),
							totalEstado.getLong(ProcedimientosEnum.ALTA.getId()) + obj.getLong("total"));
				} else if (obj.getString("idProcedimiento").equalsIgnoreCase(ProcedimientosEnum.X87_TEA_2.getId())) {
					totalEstado.put(ProcedimientosEnum.BAJA.getId(),
							totalEstado.getLong(ProcedimientosEnum.BAJA.getId()) + obj.getLong("total"));
				} else if (obj.getString("idProcedimiento").equalsIgnoreCase(ProcedimientosEnum.X87_TEA_4.getId())) {
					totalEstado.put(ProcedimientosEnum.REVISION_PRECIO.getId(),
							totalEstado.getLong(ProcedimientosEnum.REVISION_PRECIO.getId()) + obj.getLong("total"));
				} else {
					totalEstado.put(obj.getString("idProcedimiento"), obj.getLong("total"));
				}
				estado.put("totales", totalEstado);

			}

//			JSONObject totalProcObj = totalProcs.getJSONObject(obj.getString("idProcedimiento"));
//			Long tot = totalProcObj.getLong("total") + obj.getLong("total");
//			totalProcObj.put("total", tot);
//			totalProcs.put(obj.getString("idProcedimiento"), totalProcObj);

			JSONObject totalProcObj;
			if (obj.getString("idProcedimiento").equalsIgnoreCase(ProcedimientosEnum.X87_TEA_1.getId())) {
				totalProcObj = totalProcs.getJSONObject(ProcedimientosEnum.ALTA.getId());
				Long tot = totalProcObj.getLong("total") + obj.getLong("total");
				totalProcObj.put("total", tot);
				totalProcs.put(ProcedimientosEnum.ALTA.getId(), totalProcObj);
			} else if (obj.getString("idProcedimiento").equalsIgnoreCase(ProcedimientosEnum.X87_TEA_2.getId())) {
				totalProcObj = totalProcs.getJSONObject(ProcedimientosEnum.BAJA.getId());
				Long tot = totalProcObj.getLong("total") + obj.getLong("total");
				totalProcObj.put("total", tot);
				totalProcs.put(ProcedimientosEnum.BAJA.getId(), totalProcObj);
			} else if (obj.getString("idProcedimiento").equalsIgnoreCase(ProcedimientosEnum.X87_TEA_4.getId())) {
				totalProcObj = totalProcs.getJSONObject(ProcedimientosEnum.REVISION_PRECIO.getId());
				Long tot = totalProcObj.getLong("total") + obj.getLong("total");
				totalProcObj.put("total", tot);
				totalProcs.put(ProcedimientosEnum.REVISION_PRECIO.getId(), totalProcObj);
			} else {
				totalProcObj = totalProcs.getJSONObject(obj.getString("idProcedimiento"));
				Long tot = totalProcObj.getLong("total") + obj.getLong("total");
				totalProcObj.put("total", tot);
				totalProcs.put(obj.getString("idProcedimiento"), totalProcObj);
			}

			procActual = obj.getString("idProcedimiento");

		}
		estados.put(estado);

		result.put("estados", estados);
		result.put("procedimientos", totalProcs);

		return result.toString();
	}

	private String getBandejaUrl(Long id) {
		if (EstadosEnum.PENDIENTES.getId().compareTo(id) == 0) {
			return EstadosEnum.PENDIENTES.getUrl();
		} else if (EstadosEnum.ESTUDIO.getId().compareTo(id) == 0) {
			return EstadosEnum.ESTUDIO.getUrl();
		} else if (EstadosEnum.SUBSANACION.getId().compareTo(id) == 0) {
			return EstadosEnum.SUBSANACION.getUrl();
		} else if (EstadosEnum.DESISTIMIENTO.getId().compareTo(id) == 0) {
			return EstadosEnum.DESISTIMIENTO.getUrl();
		} else if (EstadosEnum.FINALIZADAS.getId().compareTo(id) == 0) {
			return EstadosEnum.FINALIZADAS.getUrl();
		} else if (EstadosEnum.RESOLUCION.getId().compareTo(id) == 0) {
			return EstadosEnum.RESOLUCION.getUrl();
		} else if (EstadosEnum.NOTIFICAR.getId().compareTo(id) == 0) {
			return EstadosEnum.NOTIFICAR.getUrl();
		} else if (EstadosEnum.CIERRE.getId().compareTo(id) == 0) {
			return EstadosEnum.CIERRE.getUrl();
		}

		return "";
	}

	@GetMapping(value = "/filterExpedientes")
	public String filterExpedientes(HttpServletRequest request, Model model,
			@RequestParam(value = "procedimiento", required = true) String procedimiento,
			@RequestParam(value = "tecnico", required = false) String tecnico,
			@RequestParam(value = "estado", required = false) String estado) {
		BandejasController.logger.info("[GET - filterExpedientes] : bandejas");

		Expedientes expediente = new Expedientes();

		request.setAttribute("expediente", expediente);
		request.setAttribute("tecnico", tecnico);
		request.setAttribute("mapaEstadosTotal", mapaEstadosTotal);

		return "expedientes/maint";
	}

}
