package com.ejie.y42b.control;

import java.util.ArrayList;
import java.util.Date;
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.Envio;
import com.ejie.y42b.model.Item;
import com.ejie.y42b.service.ItemService;

/**
 * * ItemController  
 * 
 *  
 */

@Controller()
@RequestMapping(value = "/item")
public class ItemController {

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

	@Autowired()
	private ItemService itemService;

	@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("y42bTestWar.default.language"));
		model.addAttribute("defaultLayout",
				this.appConfiguration.get("y42bTestWar.default.layout"));
		return new ModelAndView("item", "model", model);
	}

	/**
	 * Method 'getById'.
	 * 
	 * @param itemRef
	 *            String
	 * @param envioEnvioId
	 *            String
	 * @return String
	 */
	@RequestMapping(value = "/{itemRef}/{envioEnvioId}", method = RequestMethod.GET)
	public @ResponseBody()
	Item getById(@PathVariable() String itemRef,
			@PathVariable() String envioEnvioId) {
		try {
			Item item = new Item();
			item.setEnvio(new Envio());
			item.setItemRef(itemRef);
			item.getEnvio().setEnvioId(envioEnvioId);
			item = this.itemService.find(item);
			if (item == null) {
				throw new Exception(itemRef.toString()
						+ envioEnvioId.toString());
			}
			return item;
		} catch (Exception e) {
			throw new ResourceNotFoundException(itemRef.toString()
					+ envioEnvioId.toString());
		}
	}

	/**
	 * Method 'getAll'.
	 * 
	 * @param itemRef
	 *            String
	 * @param envioEnvioId
	 *            String
	 * @param nombre
	 *            String
	 * @param nombreLocalizacion
	 *            String
	 * @param telefono
	 *            String
	 * @param email
	 *            String
	 * @param seleccionado
	 *            String
	 * @param fechaMailingEnvio
	 *            Date
	 * @param mailingResponseCode
	 *            String
	 * @param fechaMailingRecepcion
	 *            Date
	 * @param xmlcampo1
	 *            String
	 * @param xmlcampo2
	 *            String
	 * @param xmlcampo3
	 *            String
	 * @param xmlcampo4
	 *            String
	 * @param xmlcampo5
	 *            String
	 * @param xmlcampo6
	 *            String
	 * @param xmlcampo7
	 *            String
	 * @param xmlcampo8
	 *            String
	 * @param xmlcampo9
	 *            String
	 * @param xmlcampo10
	 *            String
	 * @param activa
	 *            String
	 * @param request
	 *            HttpServletRequest
	 * @return String
	 */
	@RequestMapping(method = RequestMethod.GET)
	public @ResponseBody()
	Object getAll(
			@RequestParam(value = "itemRef", required = false) String itemRef,
			@RequestParam(value = "envioEnvioId", required = false) String envioEnvioId,
			@RequestParam(value = "nombre", required = false) String nombre,
			@RequestParam(value = "nombreLocalizacion", required = false) String nombreLocalizacion,
			@RequestParam(value = "telefono", required = false) String telefono,
			@RequestParam(value = "email", required = false) String email,
			@RequestParam(value = "seleccionado", required = false) String seleccionado,
			@RequestParam(value = "fechaMailingEnvio", required = false) Date fechaMailingEnvio,
			@RequestParam(value = "mailingResponseCode", required = false) String mailingResponseCode,
			@RequestParam(value = "fechaMailingRecepcion", required = false) Date fechaMailingRecepcion,
			@RequestParam(value = "xmlcampo1", required = false) String xmlcampo1,
			@RequestParam(value = "xmlcampo2", required = false) String xmlcampo2,
			@RequestParam(value = "xmlcampo3", required = false) String xmlcampo3,
			@RequestParam(value = "xmlcampo4", required = false) String xmlcampo4,
			@RequestParam(value = "xmlcampo5", required = false) String xmlcampo5,
			@RequestParam(value = "xmlcampo6", required = false) String xmlcampo6,
			@RequestParam(value = "xmlcampo7", required = false) String xmlcampo7,
			@RequestParam(value = "xmlcampo8", required = false) String xmlcampo8,
			@RequestParam(value = "xmlcampo9", required = false) String xmlcampo9,
			@RequestParam(value = "xmlcampo10", required = false) String xmlcampo10,
			@RequestParam(value = "activa", required = false) String activa,
			HttpServletRequest request) {
		try {
			Item filterItem = new Item(itemRef, new Envio(envioEnvioId, null,
					null, null, null, null, null, null, null, null, null, null,
					null, null, null, null, null, null, null, null, null, null,
					null, null, null, null), nombre, nombreLocalizacion,
					telefono, email, seleccionado, fechaMailingEnvio,
					mailingResponseCode, fechaMailingRecepcion, xmlcampo1,
					xmlcampo2, xmlcampo3, xmlcampo4, xmlcampo5, xmlcampo6,
					xmlcampo7, xmlcampo8, xmlcampo9, xmlcampo10, activa);
			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<Item> items = this.itemService.findAll(filterItem,
						pagination);

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

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

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

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

	/**
	 * Method 'add'.
	 * 
	 * @param item
	 *            Item
	 * @return Item
	 */
	@RequestMapping(method = RequestMethod.POST)
	public @ResponseBody()
	Item add(@RequestBody() Item item) {
		try {
			Item itemAux = this.itemService.add(item);
			ItemController.logger.info("Entity correctly inserted!");
			return itemAux;
		} catch (Exception e) {
			throw new MethodFailureException("Method failed");
		}
	}

	/**
	 * Method 'remove'.
	 * 
	 * @param itemRef
	 *            String
	 * @param envioEnvioId
	 *            String
	 * @param response
	 *            HttpServletResponse
	 * @return
	 */
	@RequestMapping(value = "/{itemRef}/{envioEnvioId}", method = RequestMethod.DELETE)
	public void remove(@PathVariable() String itemRef,
			@PathVariable() String envioEnvioId, HttpServletResponse response) {
		response.setContentType("text/javascript;charset=utf-8");
		response.setHeader("Pragma", "cache");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "private");
		try {
			Item item = new Item();
			item.setEnvio(new Envio());
			item.setItemRef(itemRef);
			item.getEnvio().setEnvioId(envioEnvioId);
			this.itemService.remove(item);
			response.setStatus(HttpServletResponse.SC_OK);
		} catch (Exception e) {
			ItemController.logger.error("Unable to delete " + itemRef
					+ envioEnvioId);
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			throw new MethodFailureException("Method failed");
		}
	}

	/**
	 * Method 'confRecibido'.
	 * 
	 * @param codorg
	 *            String
	 * @param codenvio
	 *            String
	 * @param response
	 *            HttpServletRequest
	 * @return
	 */
	@RequestMapping(value = "/confRecibido")
	public @ResponseBody()
	void confRecibido(
			@RequestParam(value = "codorg", required = false) String codorg,
			@RequestParam(value = "codenvio", required = false) String codenvio,
			HttpServletResponse response) {
		try {
			Item item = new Item();
			item.setEnvio(new Envio());
			item.setItemRef(codorg);
			item.getEnvio().setEnvioId(codenvio);

			item = this.itemService.find(item);
			if (item == null) {
				throw new Exception(codorg.toString() + codenvio.toString());
			}
			Date fechaMailingRecepcion = new Date();
			item.setFechaMailingRecepcion(fechaMailingRecepcion);

			this.itemService.update(item);
			response.setStatus(HttpServletResponse.SC_OK);
		} catch (Exception e) {
			ItemController.logger
					.error("Unable to delete " + codorg + codenvio);
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			throw new MethodFailureException("Method failed");
		}
	}

	/**
	 * Method 'removeAll'.
	 * 
	 * @param itemIds
	 *            ArrayList
	 * @param response
	 *            HttpServletResponse
	 * @return
	 */
	@RequestMapping(value = "/deleteAll", method = RequestMethod.POST)
	public void removeMultiple(
			@RequestBody() ArrayList<ArrayList<String>> itemIds,
			HttpServletResponse response) {
		response.setContentType("text/javascript;charset=utf-8");
		response.setHeader("Pragma", "cache");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "private");
		ArrayList<Item> itemList = new ArrayList<Item>();
		try {
			Item item = new Item();
			Envio newEnvio = new Envio();
			for (ArrayList<String> itemId : itemIds) {
				Iterator<String> iterator = itemId.iterator();

				item.setEnvio(newEnvio);
				item.setItemRef(ObjectConversionManager.convert(
						iterator.next(), String.class));
				item.getEnvio().setEnvioId(
						ObjectConversionManager.convert(iterator.next(),
								String.class));
				itemList.add(item);
			}
			this.itemService.removeMultiple(itemList);
			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) {
		ItemController.logger.warn(e.getMessage());
		return e.getMessage();
	}

	/**
	 * Method 'getItemService'.
	 * 
	 * @return ItemService
	 */
	protected ItemService getItemService() {
		return this.itemService;
	}

	/**
	 * Method 'setItemService'.
	 * 
	 * @param itemService
	 *            ItemService
	 * @return
	 */
	public void setItemService(ItemService itemService) {
		this.itemService = itemService;
	}

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

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