package com.ejie.y42b.control;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
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.servlet.ModelAndView;

import com.ejie.x38.control.exception.ControlException;
import com.ejie.x38.control.exception.MethodFailureException;
import com.ejie.x38.control.exception.ResourceNotFoundException;
import com.ejie.x38.control.exception.ServiceUnavailableException;
import com.ejie.x38.dto.JQGridJSONModel;
import com.ejie.x38.dto.Pagination;
import com.ejie.x38.util.ObjectConversionManager;
import com.ejie.y42b.model.Contacto;
import com.ejie.y42b.model.Entidad;
import com.ejie.y42b.model.Etiqueta;
import com.ejie.y42b.model.Y42bFormContacto;
import com.ejie.y42b.model.Y42bFormEntidad;
import com.ejie.y42b.service.EtiquetaService;

/**
 * * EtiquetaController  
 * 
 *  
 */

@Controller()
@RequestMapping(value = "/etiqueta")
public class EtiquetaController {

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

	@Autowired()
	private EtiquetaService etiquetaService;

	@Autowired()
	private Properties appConfiguration;

	/**
	 * Method 'getCreateForm'.
	 * 
	 * @param model
	 *            Model
	 * @return String
	 */
	@RequestMapping(value = "maint", method = RequestMethod.GET)
	public ModelAndView getCreateForm(Model model) {
		model.addAttribute("defaultLanguage",
				this.appConfiguration.get("y42bVistaWar.default.language"));
		model.addAttribute("defaultLayout",
				this.appConfiguration.get("y42bVistaWar.default.layout"));

		return new ModelAndView("etiqueta_mant", "model", model);
	}

	/**
	 * Method 'getCreateForm'.
	 * 
	 * @param entidadId
	 *            entidadId
	 * @param model
	 *            Model
	 * @return String
	 */
	@RequestMapping(value = "vista", method = RequestMethod.GET)
	public ModelAndView getCreateFormView(
			@RequestParam(value = "entidadId", required = false) String entidadId,
			Model model) {
		model.addAttribute("defaultLanguage",
				this.appConfiguration.get("y42bVistaWar.default.language"));
		model.addAttribute("defaultLayout",
				this.appConfiguration.get("y42bVistaWar.default.layout"));

		Y42bFormEntidad entidad = new Y42bFormEntidad();
		entidad.setEntidadId(entidadId);
		model.addAttribute("entidadForm", entidad);

		return new ModelAndView("etiqueta", "model", model);
	}

	/**
	 * Method 'getCreateForm'.
	 * 
	 * @param contactoId
	 *            contactoId
	 * @param model
	 *            Model
	 * @return String
	 */
	@RequestMapping(value = "vistaContacto", method = RequestMethod.GET)
	public ModelAndView getCreateFormViewContacto(
			@RequestParam(value = "contactoId", required = false) String contactoId,
			Model model) {
		model.addAttribute("defaultLanguage",
				this.appConfiguration.get("y42bVistaWar.default.language"));
		model.addAttribute("defaultLayout",
				this.appConfiguration.get("y42bVistaWar.default.layout"));

		Y42bFormContacto contacto = new Y42bFormContacto();
		contacto.setContactoId(contactoId);
		model.addAttribute("contactoForm", contacto);

		return new ModelAndView("y42bEtiquetasContacto", "model", model);
	}

	/**
	 * Method 'getById'.
	 * 
	 * @param etiquetaId
	 *            String
	 * @return String
	 */
	@RequestMapping(value = "/{etiquetaId}", method = RequestMethod.GET)
	public @ResponseBody()
	Etiqueta getById(@PathVariable() String etiquetaId) {
		try {
			Etiqueta etiqueta = new Etiqueta();
			etiqueta.setEtiquetaId(etiquetaId);
			etiqueta = this.etiquetaService.find(etiqueta);
			if (etiqueta == null) {
				throw new Exception(etiquetaId.toString());
			}
			return etiqueta;
		} catch (Exception e) {
			throw new ResourceNotFoundException(etiquetaId.toString());
		}
	}

	/**
	 * Method 'getAll'.
	 * 
	 * @param etiquetaId
	 *            String
	 * @param nombre
	 *            String
	 * @param request
	 *            HttpServletRequest
	 * @return String
	 */
	@RequestMapping(method = RequestMethod.GET)
	public @ResponseBody()
	Object getAll(
			@RequestParam(value = "etiquetaId", required = false) String etiquetaId,
			@RequestParam(value = "nombre", required = false) String nombre,
			HttpServletRequest request) {
		try {
			Etiqueta filterEtiqueta = new Etiqueta(etiquetaId, nombre);
			Pagination pagination = null;
			if (request.getHeader("JQGridModel") != null
					&& request.getHeader("JQGridModel").equals("true")) {
				pagination = new Pagination();
				pagination.setPage(Long.valueOf(request.getParameter("page")));
				pagination.setRows(Long.valueOf(request.getParameter("rows")));
				pagination.setSort(request.getParameter("sidx"));
				pagination.setAscDsc(request.getParameter("sord"));
				List<Etiqueta> etiquetas = this.etiquetaService.findAll(
						filterEtiqueta, pagination);

				if (etiquetas == null) {
					throw new Exception("No data Found.");
				}

				Long total = this.getAllCount(filterEtiqueta, request);
				JQGridJSONModel data = new JQGridJSONModel();
				data.setPage(request.getParameter("page"));
				data.setRecords(total.intValue());
				data.setTotal(total, pagination.getRows());
				data.setRows(etiquetas);
				return data;
			} else {
				List<Etiqueta> etiquetas = this.etiquetaService.findAll(
						filterEtiqueta, pagination);
				if (etiquetas == null) {
					throw new Exception("No data Found.");
				}
				return etiquetas;
			}
		} catch (Exception e) {
			throw new ResourceNotFoundException("No data Found.");
		}
	}

	/**
	 * Method 'getAllCount'.
	 * 
	 * @param filterEtiqueta
	 *            Etiqueta
	 * @param request
	 *            HttpServletRequest
	 * @return Long
	 */
	@RequestMapping(value = "/count", method = RequestMethod.GET)
	public @ResponseBody()
	Long getAllCount(
			@RequestParam(value = "etiqueta", required = false) Etiqueta filterEtiqueta,
			HttpServletRequest request) {
		try {
			return this.etiquetaService
					.findAllCount(filterEtiqueta != null ? filterEtiqueta
							: new Etiqueta());
		} catch (Exception e) {
			throw new ServiceUnavailableException(
					"Count Service is not responding.");
		}
	}

	/**
	 * Method 'edit'.
	 * 
	 * @param etiqueta
	 *            Etiqueta
	 * @param response
	 *            HttpServletResponse
	 * @return Etiqueta
	 */
	@RequestMapping(method = RequestMethod.PUT)
	public @ResponseBody()
	Etiqueta edit(@RequestBody() Etiqueta etiqueta, HttpServletResponse response) {
		try {
			Etiqueta etiquetaAux = this.etiquetaService.update(etiqueta);
			EtiquetaController.logger.info("Entity correctly inserted!");
			return etiquetaAux;
		} catch (Exception e) {
			throw new MethodFailureException("Method failed");
		}
	}

	/**
	 * Method 'add'.
	 * 
	 * @param etiqueta
	 *            Etiqueta
	 * @param nombre
	 *            String
	 * @return Etiqueta
	 */
	@RequestMapping(method = RequestMethod.POST)
	public @ResponseBody()
	Etiqueta add(
			@RequestParam(value = "nombre", required = false) String nombre,
			@RequestBody() Etiqueta etiqueta) {
		try {
			if (null != nombre) {
				etiqueta.setNombre(nombre);
			}
			Etiqueta etiquetaAux = this.etiquetaService.add(etiqueta);
			EtiquetaController.logger.info("Etiqueta añadida correctamente !");
			return etiquetaAux;
		} catch (Exception e) {
			throw new MethodFailureException("Method failed");
		}
	}

	/**
	 * Method 'remove'.
	 * 
	 * @param etiquetaId
	 *            String
	 * @param response
	 *            HttpServletResponse
	 * @return
	 */
	@RequestMapping(value = "/{etiquetaId}", method = RequestMethod.DELETE)
	public void remove(@PathVariable() String etiquetaId,
			HttpServletResponse response) {
		response.setContentType("text/javascript;charset=utf-8");
		response.setHeader("Pragma", "cache");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "private");
		try {
			Etiqueta etiqueta = new Etiqueta();
			etiqueta.setEtiquetaId(etiquetaId);
			this.etiquetaService.remove(etiqueta);
			response.setStatus(HttpServletResponse.SC_OK);
		} catch (Exception e) {
			EtiquetaController.logger.error("Unable to delete " + etiquetaId);
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			throw new MethodFailureException(
					"Esta etiqueta puede tener entidades asociadas");
		}
	}

	/**
	 * Method 'removeAll'.
	 * 
	 * @param etiquetaIds
	 *            ArrayList
	 * @param response
	 *            HttpServletResponse
	 * @return
	 */
	@RequestMapping(value = "/deleteAll", method = RequestMethod.POST)
	public void removeMultiple(
			@RequestBody() ArrayList<ArrayList<String>> etiquetaIds,
			HttpServletResponse response) {
		response.setContentType("text/javascript;charset=utf-8");
		response.setHeader("Pragma", "cache");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "private");
		ArrayList<Etiqueta> etiquetaList = new ArrayList<Etiqueta>();
		try {
			for (ArrayList<String> etiquetaId : etiquetaIds) {
				Iterator<String> iterator = etiquetaId.iterator();
				Etiqueta etiqueta = new Etiqueta();// NOPMD 2012/02/29 (IDA)
				etiqueta.setEtiquetaId(ObjectConversionManager.convert(
						iterator.next(), String.class));
				etiquetaList.add(etiqueta);
			}
			this.etiquetaService.removeMultiple(etiquetaList);
			response.setStatus(HttpServletResponse.SC_OK);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			throw new MethodFailureException("Method failed");
		}
	}

	/**
	 * Method 'handle'.
	 * 
	 * @param e
	 *            ControlException
	 * @return String
	 */
	@ExceptionHandler()
	public @ResponseBody()
	String handle(ControlException e) {
		EtiquetaController.logger.warn(e.getMessage());
		return e.getMessage();
	}

	/**
	 * Method 'getEtiquetaService'.
	 * 
	 * @return EtiquetaService
	 */
	protected EtiquetaService getEtiquetaService() {
		return this.etiquetaService;
	}

	/**
	 * Method 'setEtiquetaService'.
	 * 
	 * @param etiquetaService
	 *            EtiquetaService
	 * @return
	 */
	public void setEtiquetaService(EtiquetaService etiquetaService) {
		this.etiquetaService = etiquetaService;
	}

	/**
	 * Method 'getAppConfiguration'.
	 * 
	 * @return appConfiguration
	 */
	public Properties getAppConfiguration() {
		return this.appConfiguration;
	}

	/**
	 * Method 'setAppConfiguration'.
	 * 
	 * @param appConfiguration
	 *            Properties
	 * @return
	 */
	public void setAppConfiguration(Properties appConfiguration) {
		this.appConfiguration = appConfiguration;
	}

	/**
	 * Method 'unBind' EtiquetaEntidad
	 * 
	 * @param etiquetaId
	 *            String
	 * @param entidadId
	 *            String
	 * @param response
	 *            HttpServletResponse
	 */
	@RequestMapping(value = "/unbindEtiquetaEntidad", method = RequestMethod.POST)
	public void unBindEtiquetaEntidad(
			@RequestParam(value = "etiquetaId", required = false) String etiquetaId,
			@RequestParam(value = "entidadId", required = false) String entidadId,
			HttpServletResponse response) {
		response.setContentType("text/javascript;charset=utf-8");
		response.setHeader("Pragma", "cache");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "private");
		try {
			Etiqueta etiqueta = new Etiqueta();
			Entidad entidad = new Entidad();
			if (etiquetaId != null) {
				etiqueta.setEtiquetaId(etiquetaId);
			}
			if (entidadId != null) {
				entidad.setEntidadId(entidadId);
			}
			etiqueta.getEntidads().add(entidad);
			this.etiquetaService.removeEtiquetaEntidad(etiqueta);
			response.setStatus(HttpServletResponse.SC_OK);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			e.printStackTrace();
		}
	}

	/**
	 * Method 'bind' EtiquetaEntidad
	 * 
	 * @param etiquetaId
	 *            String
	 * @param entidadId
	 *            String
	 * @param response
	 *            HttpServletResponse
	 */
	@RequestMapping(value = "/bindEtiquetaEntidad", method = RequestMethod.POST)
	public void bindEtiquetaEntidad(
			@RequestParam(value = "etiquetaId", required = false) String etiquetaId,
			@RequestParam(value = "entidadId", required = false) String entidadId,
			HttpServletResponse response) {
		response.setContentType("text/javascript;charset=utf-8");
		response.setHeader("Pragma", "cache");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "private");
		try {
			Etiqueta etiqueta = new Etiqueta();
			Entidad entidad = new Entidad();
			if (etiquetaId != null) {
				etiqueta.setEtiquetaId(etiquetaId);
			}
			if (entidadId != null) {
				entidad.setEntidadId(entidadId);
			}
			etiqueta.getEntidads().add(entidad);
			this.etiquetaService.addEtiquetaEntidad(etiqueta);
			response.setStatus(HttpServletResponse.SC_OK);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			e.printStackTrace();
		}

	}

	/**
	 * Method 'unBind' EtiquetaContacto
	 * 
	 * @param etiquetaId
	 *            String
	 * @param contactoId
	 *            String
	 * @param response
	 *            HttpServletResponse
	 */
	@RequestMapping(value = "/unbindEtiquetaContacto", method = RequestMethod.POST)
	public void unBindEtiquetaContacto(
			@RequestParam(value = "etiquetaId", required = false) String etiquetaId,
			@RequestParam(value = "contactoId", required = false) String contactoId,
			HttpServletResponse response) {
		response.setContentType("text/javascript;charset=utf-8");
		response.setHeader("Pragma", "cache");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "private");
		try {
			Etiqueta etiqueta = new Etiqueta();
			Contacto contacto = new Contacto();
			if (etiquetaId != null) {
				etiqueta.setEtiquetaId(etiquetaId);
			}
			if (contactoId != null) {
				contacto.setContactoId(contactoId);
			}
			etiqueta.getContactos().add(contacto);
			this.etiquetaService.removeEtiquetaContacto(etiqueta);
			response.setStatus(HttpServletResponse.SC_OK);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			e.printStackTrace();
		}
	}

	/**
	 * Method 'bind' EtiquetaContacto
	 * 
	 * @param etiquetaId
	 *            String
	 * @param contactoId
	 *            String
	 * @param response
	 *            HttpServletResponse
	 */
	@RequestMapping(value = "/bindEtiquetaContacto", method = RequestMethod.POST)
	public void bindEtiquetaContacto(
			@RequestParam(value = "etiquetaId", required = false) String etiquetaId,
			@RequestParam(value = "contactoId", required = false) String contactoId,
			HttpServletResponse response) {
		response.setContentType("text/javascript;charset=utf-8");
		response.setHeader("Pragma", "cache");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "private");
		try {
			Etiqueta etiqueta = new Etiqueta();
			Contacto contacto = new Contacto();
			if (etiquetaId != null) {
				etiqueta.setEtiquetaId(etiquetaId);
			}
			if (contactoId != null) {
				contacto.setContactoId(contactoId);
			}
			etiqueta.getContactos().add(contacto);
			this.etiquetaService.addEtiquetaContacto(etiqueta);
			response.setStatus(HttpServletResponse.SC_OK);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			e.printStackTrace();
		}

	}

}
