package com.ejie.aa20b.control;

import com.ejie.aa20b.service.Aa20bProcesosJMSService;
import com.ejie.aa20b.service.EdifEstrucService;
import com.ejie.aa20b.service.EdificiosService;
import com.ejie.aa20b.service.PlantasService;
import com.ejie.aa20b.service.ZonasService;
import com.ejie.aa20b.util.Aa20bConstantes;
import com.ejie.x38.dto.JQGridJSONModel;
import com.ejie.x38.dto.Pagination;
import com.ejie.x38.json.JSONArray;
import com.ejie.x38.json.JSONObject;
import com.ejie.x38.util.ObjectConversionManager;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.ejie.aa20b.model.EdifEstruc;
import com.ejie.aa20b.model.Edificios;
import com.ejie.aa20b.model.Plantas;
import com.ejie.aa20b.model.Zonas;

/**
 * EdifEstrucController generated by UDA, 18-feb-2015 9:06:06.
 * 
 * @author UDA
 */

@Controller
@RequestMapping(value = "/edifestruc")
public class EdifEstrucController {

	private static final Logger logger = LoggerFactory
			.getLogger(EdifEstrucController.class);

	@Autowired
	private EdifEstrucService edifEstrucService;

	@Autowired
	private ZonasService zonasService;

	@Autowired
	private PlantasService plantasService;

	@Autowired
	private Aa20bProcesosJMSService procesosJMSService;

	@Autowired
	private EdificiosService edificiosService;

	@Autowired
	private PropertiesFactoryBean appConfiguration;

	/**
	 * Method 'getCreateForm'.
	 * 
	 * @param model
	 *            Model
	 * @return String
	 */
	@RequestMapping(value = "maint", method = RequestMethod.GET)
	public String getCreateForm(Model model) {
		EdifEstrucController.logger.info("[GET - View] : edifestruc");
		return "edifestruc";
	}

	/**
	 * Method 'getById'.
	 * 
	 * @param idedificio
	 *            String
	 * @param idzona
	 *            Integer
	 * @param idplanta
	 *            String
	 * @return edifEstruc EdifEstruc
	 */
	@RequestMapping(value = "/{idedificio}/{idzona}/{idplanta}", method = RequestMethod.GET)
	public @ResponseBody
	EdifEstruc getById(@PathVariable String idedificio,
			@PathVariable Integer idzona, @PathVariable String idplanta) {
		EdifEstruc edifEstruc = new EdifEstruc();
		edifEstruc.setIdedificio(idedificio);
		edifEstruc.setIdzona(idzona);
		edifEstruc.setIdplanta(idplanta);
		edifEstruc = this.edifEstrucService.find(edifEstruc);
		EdifEstrucController.logger
				.info("[GET - findBy_PK] : Obtener EdifEstruc por PK");
		return edifEstruc;
	}

	/**
	 * Method 'getAll'.
	 * 
	 * @param filterEdifEstruc
	 *            EdifEstruc
	 * @return List
	 */
	@RequestMapping(method = RequestMethod.GET)
	public @ResponseBody
	List<EdifEstruc> getAll(@ModelAttribute EdifEstruc filterEdifEstruc) {
		EdifEstrucController.logger
				.info("[GET - find_ALL] : Obtener EdifEstruc por filtro");
		return this.edifEstrucService.findAll(filterEdifEstruc, null);
	}

	/**
	 * Method 'edit'.
	 * 
	 * @param edifEstruc
	 *            EdifEstruc
	 * @return EdifEstruc
	 */
	@RequestMapping(method = RequestMethod.PUT)
	public @ResponseBody
	EdifEstruc edit(@RequestBody EdifEstruc edifEstruc) {
		EdifEstruc edifEstrucAux = this.edifEstrucService.update(edifEstruc);
		EdifEstrucController.logger
				.info("[PUT] : EdifEstruc actualizado correctamente");
		return edifEstrucAux;
	}

	/**
	 * Method 'add'.
	 * 
	 * @param edifEstruc
	 *            EdifEstruc
	 * @return EdifEstruc
	 */
	@RequestMapping(method = RequestMethod.POST)
	public @ResponseBody
	EdifEstruc add(@RequestBody EdifEstruc edifEstruc) {
		EdifEstruc edifEstrucAux = this.edifEstrucService.add(edifEstruc);
		EdifEstrucController.logger
				.info("[POST] : EdifEstruc insertado correctamente");
		return edifEstrucAux;
	}

	/**
	 * Method 'remove'.
	 * 
	 * @param idedificio
	 *            String
	 * @param idzona
	 *            Integer
	 * @param idplanta
	 *            String
	 * @return edifEstruc
	 */
	@RequestMapping(value = "/{idedificio}/{idzona}/{idplanta}", method = RequestMethod.DELETE)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody
	EdifEstruc remove(@PathVariable String idedificio,
			@PathVariable Integer idzona, @PathVariable String idplanta) {
		EdifEstruc edifEstruc = new EdifEstruc();
		edifEstruc.setIdedificio(idedificio);
		edifEstruc.setIdzona(idzona);
		edifEstruc.setIdplanta(idplanta);
		this.edifEstrucService.remove(edifEstruc);
		EdifEstrucController.logger
				.info("[DELETE] : EdifEstruc borrado correctamente");
		return edifEstruc;
	}

	/**
	 * Method 'removeAll'.
	 * 
	 * @param edifEstrucIds
	 *            List
	 * @return edifEstrucList
	 */
	@RequestMapping(value = "/deleteAll", method = RequestMethod.POST)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody
	List<List<String>> removeMultiple(
			@RequestBody List<List<String>> edifEstrucIds) {
		List<EdifEstruc> edifEstrucList = new ArrayList<EdifEstruc>();
		for (List<String> edifEstrucId : edifEstrucIds) {
			Iterator<String> iterator = edifEstrucId.iterator();
			EdifEstruc edifEstruc = new EdifEstruc(); // NOPMD - Objeto nuevo en
														// la lista (parametro
														// del servicio)
			edifEstruc.setIdedificio(ObjectConversionManager.convert(
					iterator.next(), String.class));
			edifEstruc.setIdzona(ObjectConversionManager.convert(
					iterator.next(), java.lang.Integer.class));
			edifEstruc.setIdplanta(ObjectConversionManager.convert(
					iterator.next(), String.class));
			edifEstrucList.add(edifEstruc);
		}
		this.edifEstrucService.removeMultiple(edifEstrucList);
		EdifEstrucController.logger
				.info("[POST - DELETE_ALL] : EdifEstruc borrados correctamente");
		return edifEstrucIds;
	}

	/**
	 * Method 'getAllJQGrid'.
	 * 
	 * @param filterEdifEstruc
	 *            EdifEstruc
	 * @param pagination
	 *            Pagination
	 * @return JQGridJSONModel
	 */
	@RequestMapping(method = RequestMethod.GET, headers = { "JQGridModel=true" })
	public @ResponseBody
	JQGridJSONModel getAllJQGrid(@ModelAttribute EdifEstruc filterEdifEstruc,
			@ModelAttribute Pagination pagination) {
		List<EdifEstruc> edifEstrucs = this.edifEstrucService.findAll(
				filterEdifEstruc, pagination);
		Long recordNum = this.edifEstrucService.findAllCount(filterEdifEstruc);
		EdifEstrucController.logger.info("[GET - jqGrid] : Obtener EdifEstruc");
		return new JQGridJSONModel(pagination, recordNum, edifEstrucs);
	}

	/**
	 * Method 'getById'.
	 * 
	 * @param codEdificio
	 *            String
	 * @return ArrayList<Zonas>
	 */
	@RequestMapping(value = "/buscaZonasLibres", method = RequestMethod.POST)
	public @ResponseBody
	List<Zonas> buscaZonas(String codEdificio, Model model,
			HttpServletRequest request) {
		String language = "es";
		EdifEstrucController.logger
				.info("[GET - BUSCA ZONAS] : BUSCA ZONAS DE ESTRUCTURA edificio: "
						+ codEdificio);
		List<Zonas> zonasLibres = zonasService.obtenerZonasEdificioLibres(
				codEdificio, language);
		EdifEstrucController.logger
				.info("[GET - findBy_PK] : Obtener Zonas por PK");
		return zonasLibres;
	}

	@RequestMapping(value = "/buscaZonasOcupadas", method = RequestMethod.POST)
	public @ResponseBody
	List<Zonas> buscaZonasOcupadas(String codEdificio, Model model,
			HttpServletRequest request) {
		String language = "es";
		EdifEstrucController.logger
				.info("[GET - BUSCA ZONAS] : BUSCA ZONAS DE ESTRUCTURA edificio: "
						+ codEdificio);
		List<Zonas> zonasOcupadas = zonasService.obtenerZonasEdificioOcupadas(
				codEdificio, language);
		EdifEstrucController.logger
				.info("[GET - findBy_PK] : Obtener Zonas por PK");
		return zonasOcupadas;
	}

	@RequestMapping(value = "/sumaZonas", method = RequestMethod.POST)
	public @ResponseBody
	EdifEstruc sumaZonas(@RequestParam String codEdificio,
			@RequestParam ArrayList<Integer> zonasSeleccionadas, Model model,
			HttpServletRequest request) {

		EdifEstruc edifEstrucAux = new EdifEstruc();
		EdifEstruc laEdifEstruc = new EdifEstruc();
		String sinPlantas = "0";

		EdifEstrucController.logger.info("[GET - SUMA ZONAS] : ZONAS: "
				+ zonasSeleccionadas.size());

		for (int i = 0; i < zonasSeleccionadas.size(); i++) {

			laEdifEstruc.setIdedificio(codEdificio);
			laEdifEstruc.setIdzona(zonasSeleccionadas.get(i));
			laEdifEstruc.setIdplanta(sinPlantas);

			EdifEstrucController.logger
					.info("[GET - findBy_PK] : Grabando estructura zona : "
							+ laEdifEstruc.getIdzona());

			EdifEstrucController.logger
					.info("[GET - findBy_PK] : Grabando estructura : "
							+ laEdifEstruc.toString());

			edifEstrucAux = this.edifEstrucService.add(laEdifEstruc);
		}

		if (zonasSeleccionadas.size() > 0) {
			// Como ya se ha asociado una zona concreta ya no puede existir un
			// registro para ese edificio y con IDZONA=0. Por lo tanto
			// se elimina ese registro si existe

			EdifEstruc edifEstrucElim = new EdifEstruc();
			edifEstrucElim.setIdedificio(codEdificio);
			edifEstrucElim.setIdzona(0);
			edifEstrucElim.setIdplanta("0");
			this.edifEstrucService.remove(edifEstrucElim);
		}

		/**
		 * GMAO Si la asignacion de la zona al edificio ha ido bien generamos un
		 * mensaje en la cola para insertar el registro del edificio en BBDD
		 * movilgmao
		 */

		EdifEstrucController.logger
				.info("[JMS] notificar modificación Estructura edificio movilgmao");

		String idEdificio = laEdifEstruc.getIdedificio();
		Integer idZona = 0;
		if (laEdifEstruc.getIdzona() != null && laEdifEstruc.getIdzona() != 0) {
			idZona = laEdifEstruc.getIdzona();
		}
		Edificios edificio = this.edificiosService.obtenerEdificio(idEdificio);

		Zonas zonaAux = new Zonas();
		zonaAux.setIdzona(idZona);
		com.ejie.aa20b.model.Zonas zona = this.zonasService
				.obtenerZona(zonaAux);

		this.procesosJMSService.sincronizarZonaEdifGmao(edificio, zona);

		return edifEstrucAux;
	}

	@RequestMapping(value = "/restaZonas", method = RequestMethod.POST)
	public @ResponseBody
	EdifEstruc restaZonas(@RequestParam String codEdificio,
			@RequestParam ArrayList<Integer> zonasSeleccionadas, Model model,
			HttpServletRequest request) {

		EdifEstruc edifEstrucAux = new EdifEstruc();
		EdifEstruc laEdifEstruc = new EdifEstruc();

		for (int i = 0; i < zonasSeleccionadas.size(); i++) {

			laEdifEstruc.setIdedificio(codEdificio);
			laEdifEstruc.setIdzona(zonasSeleccionadas.get(i));

			EdifEstrucController.logger
					.info("[GET - findBy_PK] : Borrando estructura zona : "
							+ laEdifEstruc.getIdzona());

			EdifEstrucController.logger
					.info("[GET - findBy_PK] : Borrando estructura : "
							+ laEdifEstruc.toString());

			this.edifEstrucService.removeZonas(laEdifEstruc);
		}

		// Si despues de eliminar las zonas seleccionadas ya no queda ninguna
		// debemos meter un registro con el edificio, IDZONA=0 Y planta=0
		// Para indicar que va a tener acceso a todas las zonas.
		EdifEstruc edifEstrucElim = new EdifEstruc();
		edifEstrucElim.setIdedificio(codEdificio);

		List<EdifEstruc> listaEdifEstruc = this.edifEstrucService.findAll(
				edifEstrucElim, null);
		if (listaEdifEstruc.size() == 0) {
			// Añadir registro
			edifEstrucElim.setIdzona(0);
			edifEstrucElim.setIdplanta("0");
			this.edifEstrucService.add(edifEstrucElim);
		}

		EdifEstrucController.logger.info("[GET - BORRA ZONAS] : ZONAS: "
				+ zonasSeleccionadas.size());

		EdifEstrucController.logger.info("[GET - findBy_PK] : BORRA ZONAS");

		/**
		 * GMAO Se deben sincronizar todas las zonas de todos los edificios ya
		 * que no existe servicio en movilgmao para quitar una zona
		 */
		String urlConfig = "";
		try {
			urlConfig = this.appConfiguration.getObject().getProperty(
					"movilgmao.path");
		} catch (Exception e) {

		}

		Edificios edifFilter = new Edificios();
		edifFilter.setBaja("0");
		List<Edificios> edificios = this.edificiosService.findAll(edifFilter,
				null);

		this.procesosJMSService.sincronizarEdifEstruc(edificios,
				Aa20bConstantes.COLA, urlConfig);

		return edifEstrucAux;
	}

	@RequestMapping(value = "/buscaPlantasLibres", method = RequestMethod.POST)
	public @ResponseBody
	List<Plantas> buscaPlantasLibres(String codEdificio, String codZona,
			Model model, HttpServletRequest request) {
		String language = "es";
		EdifEstrucController.logger
				.info("[GET - BUSCA PLANTAS] : BUSCA PLANTAS LIBRES EDIFICIO: "
						+ codEdificio);
		List<Plantas> plantasLibres = plantasService.obtenerPlantasZonaLibres(
				codEdificio, codZona, language);
		EdifEstrucController.logger
				.info("[GET - findBy_PK] : Obtener Zonas por PK");
		return plantasLibres;
	}

	@RequestMapping(value = "/buscaPlantasOcupadas", method = RequestMethod.POST)
	public @ResponseBody
	List<Plantas> buscaPlantasOcupadas(String codEdificio, String codZona,
			Model model, HttpServletRequest request) {
		String language = "es";
		EdifEstrucController.logger
				.info("[GET - BUSCA PLANTAS] : BUSCA PLANTAS OCUPADAS edificio: "
						+ codEdificio);
		List<Plantas> plantasOcupadas = plantasService
				.obtenerPlantasZonaOcupadas(codEdificio, codZona, language);
		EdifEstrucController.logger
				.info("[GET - findBy_PK] : Obtener Plantas zona ocupadas");
		return plantasOcupadas;
	}

	@RequestMapping(value = "/sumaPlantas", method = RequestMethod.POST)
	public @ResponseBody
	EdifEstruc sumaPlantas(@RequestParam String codEdificio,
			@RequestParam Integer codZona,
			@RequestParam ArrayList<String> plantasSeleccionadas, Model model,
			HttpServletRequest request) {
		EdifEstruc edifEstrucAux = new EdifEstruc();
		EdifEstruc laEdifEstruc = new EdifEstruc();

		for (int i = 0; i < plantasSeleccionadas.size(); i++) {

			laEdifEstruc.setIdedificio(codEdificio);
			laEdifEstruc.setIdzona(codZona);
			laEdifEstruc.setIdplanta(plantasSeleccionadas.get(i));

			EdifEstrucController.logger
					.info("[GET - findBy_PK] : Grabando estructura planta : "
							+ laEdifEstruc.getIdzona());

			EdifEstrucController.logger
					.info("[GET - findBy_PK] : Grabando estructura : "
							+ laEdifEstruc.toString());

			edifEstrucAux = this.edifEstrucService.add(laEdifEstruc);
		}

		if (plantasSeleccionadas.size() > 0) {
			// Como ya se ha asociado una planta concreta ya no puede existir un
			// registro para ese edificio y zona con IDPLANTA=0. Por lo tanto
			// se elimina ese registro si existe

			EdifEstruc edifEstrucElim = new EdifEstruc();
			edifEstrucElim.setIdedificio(codEdificio);
			edifEstrucElim.setIdzona(codZona);
			edifEstrucElim.setIdplanta("0");
			this.edifEstrucService.remove(edifEstrucElim);
		}

		EdifEstrucController.logger.info("[GET - SUMA PLANTAS] : PLANTAS: "
				+ plantasSeleccionadas.size());

		EdifEstrucController.logger.info("[GET - findBy_PK] : Suma Plantas");

		/**
		 * GMAO Si la asignacion de la planta al edificio ha ido bien generamos
		 * un mensaje en la cola para insertar el registro del edificio en BBDD
		 * movilgmao
		 */

		EdifEstrucController.logger
				.info("[JMS] notificar modificación Estructura edificio (planta) movilgmao");

		String idEdificio = laEdifEstruc.getIdedificio();
		Integer idZona = 0;
		String idPlanta = "0";
		if (laEdifEstruc.getIdzona() != null && laEdifEstruc.getIdzona() != 0) {
			idZona = laEdifEstruc.getIdzona();
		}
		if (laEdifEstruc.getIdplanta() != null
				&& !laEdifEstruc.getIdplanta().equals("0")) {
			idPlanta = laEdifEstruc.getIdplanta();
		}
		Edificios edificio = this.edificiosService.obtenerEdificio(idEdificio);

		Zonas zonaAux = new Zonas();
		zonaAux.setIdzona(idZona);
		Zonas zona = this.zonasService.obtenerZona(zonaAux);

		Plantas plantaAux = new Plantas();
		plantaAux.setIdplanta(Integer.valueOf(idPlanta));
		Plantas planta = this.plantasService.obtenerPlanta(plantaAux);

		this.procesosJMSService.sincronizarPlantaEdifGmao(edificio, zona,
				planta);

		return edifEstrucAux;
	}

	@RequestMapping(value = "/restaPlantas", method = RequestMethod.POST)
	public @ResponseBody
	EdifEstruc restaPlantas(@RequestParam String codEdificio,
			@RequestParam Integer codZona,
			@RequestParam ArrayList<String> plantasSeleccionadas, Model model,
			HttpServletRequest request) {
		// String language = "es";

		// ArrayList<EdifEstruc> edifEstrucAux = new ArrayList<EdifEstruc>();
		EdifEstruc edifEstrucAux = new EdifEstruc();
		EdifEstruc laEdifEstruc = new EdifEstruc();

		for (int i = 0; i < plantasSeleccionadas.size(); i++) {

			laEdifEstruc.setIdedificio(codEdificio);
			laEdifEstruc.setIdzona(codZona);
			laEdifEstruc.setIdplanta(plantasSeleccionadas.get(i));

			EdifEstrucController.logger
					.info("[GET - findBy_PK] : Borrando estructura planta : "
							+ laEdifEstruc.getIdzona());

			EdifEstrucController.logger
					.info("[GET - findBy_PK] : Borrando estructura : "
							+ laEdifEstruc.toString());

			this.edifEstrucService.remove(laEdifEstruc);
		}

		// Si despues de eliminar las plantas seleccionadas ya no queda ninguna
		// debemos meter un registro con el edificio, idzona Y planta=0
		// Para indicar que va a tener acceso a todas las plantas.
		EdifEstruc edifEstrucElim = new EdifEstruc();
		edifEstrucElim.setIdedificio(codEdificio);
		edifEstrucElim.setIdzona(codZona);

		List<EdifEstruc> listaEdifEstruc = this.edifEstrucService.findAll(
				edifEstrucElim, null);
		if (listaEdifEstruc.size() == 0) {
			// Añadir registro
			edifEstrucElim.setIdplanta("0");
			this.edifEstrucService.add(edifEstrucElim);
		}

		EdifEstrucController.logger.info("[GET - BORRA PLANTAS] : PLANTA: "
				+ plantasSeleccionadas.size());

		EdifEstrucController.logger.info("[GET - findBy_PK] : BORRA PLANTA");

		/**
		 * GMAO Se deben sincronizar todas las zonas de todos los edificios ya
		 * que no existe servicio en movilgmao para quitar una zona
		 */
		String urlConfig = "";
		try {
			urlConfig = this.appConfiguration.getObject().getProperty(
					"movilgmao.path");
		} catch (Exception e) {

		}
		Edificios edifFilter = new Edificios();
		edifFilter.setBaja("0");
		List<Edificios> edificios = this.edificiosService.findAll(edifFilter,
				null);

		this.procesosJMSService.sincronizarEdifEstruc(edificios,
				Aa20bConstantes.COLA, urlConfig);

		return edifEstrucAux;
	}
}
