package com.ejie.ab63.control.pagos;

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

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
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 org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.ejie.ab63.comun.Constantes;
import com.ejie.ab63.comun.utilidades.config.Config;
import com.ejie.ab63.model.inicio.InitForm;
import com.ejie.ab63.model.pagos.PagosExpediente;
import com.ejie.ab63.model.usuario.Usuario;
import com.ejie.ab63.service.pagos.PagosExpedienteService;
import com.ejie.ab63.util.UtilDate;
import com.ejie.x38.control.bind.annotation.RequestJsonBody;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRowDto;
import com.ejie.x38.reports.ReportData;

/**
 * PagosExpedienteController  
 * 
 *  
 */

@Controller
@SessionAttributes("usuario")
@RequestMapping(value = "/pagosexpediente")

public class PagosExpedienteController {

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

	@Autowired
	private PagosExpedienteService pagosExpedienteService;

	@Autowired
	private ReloadableResourceBundleMessageSource appMessageSource;

	/*
	 * OPERACIONES CRUD (Create, Read, Update, Delete)
	 * 
	 */

	/**
	 * Operacion CRUD Read. Devuelve el bean correspondiente al identificador
	 * indicado.
	 * 
	 * @param idPagoExpediente
	 *            Integer
	 * @return PagosExpediente Objeto correspondiente al identificador indicado.
	 */
	@RequestMapping(value = "/{idPagoExpediente}", method = RequestMethod.GET)
	public @ResponseBody PagosExpediente get(@PathVariable Integer idPagoExpediente) {
		PagosExpediente pagosExpediente = new PagosExpediente();
		pagosExpediente.setIdPagoExpediente(idPagoExpediente);
		pagosExpediente = this.pagosExpedienteService.find(pagosExpediente);
		PagosExpedienteController.logger.info("[GET - findBy_PK] : Obtener PagosExpediente por PK");
		return pagosExpediente;
	}

	/**
	 * Operacion CRUD Read. Devuelve el bean correspondiente al identificador
	 * indicado.
	 * 
	 * @param idPagoExpediente
	 *            Integer
	 * @return PagosExpediente Objeto correspondiente al identificador indicado.
	 */
	@RequestMapping(value = "/{idExpediente}/{idPagoExpediente}", method = RequestMethod.GET)
	public @ResponseBody PagosExpediente getPago(@PathVariable Integer idPagoExpediente,
			@PathVariable Integer idExpediente) {
		PagosExpediente pagosExpediente = new PagosExpediente();
		pagosExpediente.setIdExpediente(idExpediente);
		pagosExpediente.setIdPagoExpediente(idPagoExpediente);
		pagosExpediente = this.pagosExpedienteService.findPagos(pagosExpediente);
		pagosExpediente.setFechaPagoStr(
				UtilDate.convertirFechaEnString(pagosExpediente.getFechaPago(), "dd/MM/yyyy", "yyyy/MM/dd"));
		pagosExpediente.setFechaEnvSerStr(
				UtilDate.convertirFechaEnString(pagosExpediente.getFechaEnvSer(), "dd/MM/yyyy", "yyyy/MM/dd"));
		pagosExpediente.setFechaDocPagStr(
				UtilDate.convertirFechaEnString(pagosExpediente.getFechaDocPag(), "dd/MM/yyyy", "yyyy/MM/dd"));
		PagosExpedienteController.logger.info("[GET - findBy_PK] : Obtener PagosExpediente por PK");
		return pagosExpediente;
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 *
	 * @param filterPagosExpediente
	 *            PagosExpediente Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return List<PagosExpediente> Lista de objetos correspondientes a la
	 *         busqueda realizada.
	 */
	@RequestMapping(method = RequestMethod.GET)
	public @ResponseBody List<PagosExpediente> getAll(@ModelAttribute PagosExpediente filterPagosExpediente) {
		PagosExpedienteController.logger.info("[GET - find_ALL] : Obtener PagosExpediente por filtro");
		return this.pagosExpedienteService.findAll(filterPagosExpediente, null);
	}

	/**
	 * Operacion CRUD Edit. Modificacion del bean indicado.
	 *
	 * @param pagosExpediente
	 *            PagosExpediente Bean que contiene la informacion a modificar.
	 * @return PagosExpediente Bean resultante de la modificacion.
	 */
	@RequestMapping(value = "/pagos", method = RequestMethod.PUT)
	public @ResponseBody PagosExpediente edit(@RequestBody PagosExpediente pagosExpediente) {
		PagosExpediente pagosExpedienteAux = this.pagosExpedienteService.update(pagosExpediente);
		PagosExpedienteController.logger.info("[PUT] : PagosExpediente actualizado correctamente");
		return pagosExpedienteAux;
	}

	/**
	 * Operacion CRUD Edit. Modificacion del bean indicado.
	 *
	 * @param pagosExpediente
	 *            PagosExpediente Bean que contiene la informacion a modificar.
	 * @return PagosExpediente Bean resultante de la modificacion.
	 */
	@RequestMapping(value = "/{idExpediente}", method = RequestMethod.PUT)
	public @ResponseBody PagosExpediente editPagos(@RequestBody PagosExpediente pagosExpediente,
			HttpServletRequest httpRequest, @ModelAttribute(value = "usuario") Usuario usuario) {
		return this.pagosExpedienteService.editPagos(pagosExpediente, httpRequest, usuario);
	}

	/**
	 * Operacion CRUD Create. Creacion de un nuevo registro a partir del bean
	 * indicado.
	 *
	 * @param pagosExpediente
	 *            PagosExpediente Bean que contiene la informacion con la que se
	 *            va a crear el nuevo registro.
	 * @return PagosExpediente Bean resultante del proceso de creacion.
	 */
	@RequestMapping(value = "/{idExpediente}", method = RequestMethod.POST)
	public @ResponseBody PagosExpediente add(@RequestBody PagosExpediente pagosExpediente,
			@PathVariable Integer idExpediente, HttpServletRequest httpRequest,
			@ModelAttribute(value = "usuario") Usuario usuario) {

		return pagosExpedienteService.add(pagosExpediente, idExpediente, httpRequest, usuario);
	}

	/**
	 * Operacion CRUD Create. Creacion de un nuevo registro a partir del bean
	 * indicado.
	 *
	 * @param pagosExpediente
	 *            PagosExpediente Bean que contiene la informacion con la que se
	 *            va a crear el nuevo registro.
	 * @return PagosExpediente Bean resultante del proceso de creacion.
	 *//*
		 * @RequestMapping(value = "/modificarPagos", method =
		 * RequestMethod.POST) public @ResponseBody PagosExpediente
		 * add(@RequestBody PagosExpediente pagosExpediente,
		 * 
		 * @ModelAttribute("initForm") InitForm datosTramitagune) {
		 * 
		 * if (pagosExpediente.getIdPagoExpediente() != null) { PagosExpediente
		 * pagosExpedienteAux =
		 * this.pagosExpedienteService.updatePagos(pagosExpediente);
		 * PagosExpedienteController.logger.
		 * info("[PUT] : PagosExpediente actualizado correctamente"); return
		 * pagosExpedienteAux; } else { Integer idExpediente =
		 * datosTramitagune.getIdExpediente();
		 * pagosExpediente.setIdExpediente(idExpediente);
		 * 
		 * PagosExpediente pagosExpedienteAux =
		 * this.pagosExpedienteService.add(pagosExpediente);
		 * PagosExpedienteController.logger.
		 * info("[POST] : PagosExpediente insertado correctamente"); return
		 * pagosExpedienteAux; }
		 * 
		 * }
		 */
	/**
	 * Operacion CRUD Delete. Borrado del registro correspondiente al
	 * identificador especificado.
	 *
	 * @param idPagoExpediente
	 *            Integer Identificador del objeto que se desea eliminar.
	 * @return PagosExpediente Bean eliminado.
	 */
	@RequestMapping(value = "{idExpediente}/{idPagoExpediente}", method = RequestMethod.DELETE)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody PagosExpediente remove(@PathVariable Integer idPagoExpediente) {

		return pagosExpedienteService.remove(idPagoExpediente);
	}

	/*
	 * METODOS COMPONENTE RUP_TABLE
	 * 
	 */

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * @param model
	 *            Model
	 * @return String
	 */
	@RequestMapping(value = "/pagos", method = RequestMethod.POST)
	public String getFormEdit(Model model, PagosExpediente pagosExpediente,
			@ModelAttribute(value = "initForm") InitForm initForm) {
		String expediente = initForm.getFolderNumber();
		String nombreExpediente = initForm.getFolderNumber() + " - " + initForm.getTituloExpediente();
		model.addAttribute("nombreExpediente", nombreExpediente);
		model.addAttribute("expediente", expediente);
		model.addAttribute("datosPagos", pagosExpediente);

		Properties prop = Config.loadProperties(Constantes.COD_APPL_CONFIG);
		String url = prop.getProperty("urlVerDocumento");
		url = url.replace("[folderID]", initForm.getFolderId());
		model.addAttribute("urlVerDocumentos", url);

		PagosExpedienteController.logger.info("[GET - View] : pagosexpediente");
		return "pagosExpediente";
	}

	/**
	 * Operacion de filtrado del componente RUP_TABLE.
	 * 
	 * @param filterPagosExpediente
	 *            PagosExpediente Bean que contiene los parametros de filtrado a
	 *            emplear.
	 * @param jqGridRequestDto
	 *            Dto que contiene los parametros de configuracion propios del
	 *            RUP_TABLE a aplicar en el filtrado.
	 * @return JQGridResponseDto<PagosExpediente> Dto que contiene el resultado
	 *         del filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/{idExpediente}/filter", method = RequestMethod.POST)
	public @ResponseBody JQGridResponseDto<PagosExpediente> filter(
			@RequestJsonBody(param = "filter") PagosExpediente filterPagosExpediente,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto, @ModelAttribute("initForm") InitForm datosTramitagune) {
		filterPagosExpediente.setIdExpediente(datosTramitagune.getIdExpediente());
		PagosExpedienteController.logger.info("[POST - filter] : Obtener PagosExpedientes");
		return this.pagosExpedienteService.filter(filterPagosExpediente, jqGridRequestDto, false);
	}

	/**
	 * Operacion de busqueda del componente RUP_TABLE.
	 * 
	 * @param filterPagosExpediente
	 *            PagosExpediente Bean que contiene los parametros de filtrado a
	 *            emplear.
	 * @param searchPagosExpediente
	 *            PagosExpediente Bean que contiene los parametros de busqueda a
	 *            emplear.
	 * @param jqGridRequestDto
	 *            Dto que contiene los parametros de configuracion propios del
	 *            RUP_TABLE a aplicar en la búsqueda.
	 * @return TableRowDto<PagosExpediente> Dto que contiene el resultado de la
	 *         busqueda realizada por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/search", method = RequestMethod.POST)
	public @ResponseBody List<TableRowDto<PagosExpediente>> search(
			@RequestJsonBody(param = "filter") PagosExpediente filterPagosExpediente,
			@RequestJsonBody(param = "search") PagosExpediente searchPagosExpediente,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		PagosExpedienteController.logger.info("[POST - search] : Buscar PagosExpedientes");
		return this.pagosExpedienteService.search(filterPagosExpediente, searchPagosExpediente, jqGridRequestDto,
				false);
	}

	/**
	 * Borrado multiple de registros
	 * 
	 * @param filterPagosExpediente
	 *            PagosExpediente Bean que contiene los parametros de filtrado a
	 *            emplear.
	 * @param jqGridRequestDto
	 *            Dto que contiene los parametros de configuracion propios del
	 *            RUP_TABLE a aplicar en la busqueda.
	 * @return List<String> Lista de los identificadores de los registros
	 *         eliminados.
	 * 
	 */
	@RequestMapping(value = "/deleteAll", method = RequestMethod.POST)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody List<String> removeMultiple(
			@RequestJsonBody(param = "filter") PagosExpediente filterPagosExpediente,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		PagosExpedienteController.logger
				.info("[POST - search] : [POST - removeMultiple] : Eliminar multiples PagosExpedientes");
		this.pagosExpedienteService.removeMultiple(filterPagosExpediente, jqGridRequestDto, false);
		PagosExpedienteController.logger.info("All entities correctly deleted!");

		return jqGridRequestDto.getMultiselection().getSelectedIds();
	}

	/*
	 * METODOS COMPONENTE RUP_TABLE - JERARQUIA
	 */

	/**
	 * Operacion de filtrado del componente RUP_TABLE para presentar los
	 * registros mediante visualizacion jerarquica.
	 * 
	 * @param filterPagosExpediente
	 *            PagosExpediente Bean que contiene los parametros de filtrado a
	 *            emplear.
	 * @param jqGridRequestDto
	 *            Dto que contiene los parametros de configuracion propios del
	 *            RUP_TABLE a aplicar en el filtrado.
	 * @return JQGridResponseDto<JerarquiaDto<PagosExpediente>> Dto que contiene
	 *         el resultado del filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/jerarquia/filter", method = RequestMethod.POST)
	public @ResponseBody JQGridResponseDto<JerarquiaDto<PagosExpediente>> jerarquia(
			@RequestJsonBody(param = "filter") PagosExpediente filterPagosExpediente,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		PagosExpedienteController.logger.info("[POST - jerarquia] : Obtener PagosExpedientes jerarquia");
		return this.pagosExpedienteService.jerarquia(filterPagosExpediente, jqGridRequestDto, false);
	}

	/**
	 * Recupera los hijos de los registros desplegados en la visualizacion
	 * jerarquica.
	 * 
	 * @param filterPagosExpediente
	 *            PagosExpediente Bean que contiene los parametros de filtrado a
	 *            emplear.
	 * @param jqGridRequestDto
	 *            Dto que contiene los parametros de configuracion propios del
	 *            RUP_TABLE a aplicar en el filtrado.
	 * @return JQGridResponseDto<JerarquiaDto<PagosExpediente>> Dto que contiene
	 *         el resultado del filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/jerarquiaChildren", method = RequestMethod.POST)
	public @ResponseBody JQGridResponseDto<JerarquiaDto<PagosExpediente>> jerarquiaChildren(
			@RequestJsonBody(param = "filter") PagosExpediente filterPagosExpediente,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		PagosExpedienteController.logger.info("[POST - jerarquia] : Obtener PagosExpedientes jerarquia - Hijos");
		return this.pagosExpedienteService.jerarquiaChildren(filterPagosExpediente, jqGridRequestDto);
	}

	/**
	 * Permite crear reportes xls o xlsx
	 * 
	 * @param filterDireccion
	 * @param jqGridRequestDto
	 * @param modelMap
	 * @param columns
	 * @param request
	 * @return
	 */
	@RequestMapping(value = { "{idExpediente}/xlsReport", "{idExpediente}/xlsxReport" }, method = RequestMethod.POST)
	protected ModelAndView getExcelPOI(@ModelAttribute PagosExpediente filterPagosExpediente,
			@ModelAttribute JQGridRequestDto jqGridRequestDto, ModelMap modelMap,
			@RequestParam(value = "columns", required = false) String columns, HttpServletRequest request) {

		Locale locale = LocaleContextHolder.getLocale();

		columns = "[['numeroPago','" + appMessageSource.getMessage("excel.numeroPago", null, locale) + "']"
				+ ",['importePago','" + appMessageSource.getMessage("excel.importePago", null, locale) + "']"
				+ ",['porcentajePago','" + appMessageSource.getMessage("excel.porcentajePago", null, locale) + "']"
				+ ",['fechaPago','" + appMessageSource.getMessage("excel.fechaPago", null, locale) + "']"
				+ ",['fechaEnvSer','" + appMessageSource.getMessage("excel.fechaEnvSer", null, locale) + "']"
				+ ",['fechaDocPag','" + appMessageSource.getMessage("excel.fechaDocPag", null, locale) + "']" + "]";

		// Acceso a BD para recuperar datos
		List<PagosExpediente> listProgramasPage = this.pagosExpedienteService
				.findAllLikeExportExcel(filterPagosExpediente, jqGridRequestDto, null);
		jqGridRequestDto.setPage(null);
		jqGridRequestDto.setRows(null);
		List<PagosExpediente> listProgramasAll = this.pagosExpedienteService
				.findAllLikeExportExcel(filterPagosExpediente, jqGridRequestDto, null);

		// Nombre fichero
		modelMap.put("fileName", appMessageSource.getMessage("excel.pagosExpedienteNombreExcel", null, locale));

		// Datos
		List<Object> reportData = new ArrayList<Object>();
		// Hoja 1
		ReportData<PagosExpediente> usuarioExcelDataAll = new ReportData<PagosExpediente>();
		// nombre hoja
		usuarioExcelDataAll
				.setSheetName(appMessageSource.getMessage("usuarioExcel.totalPagosExpediente", null, locale));
		// cabeceras hoja
		usuarioExcelDataAll.setHeaderNames(ReportData.parseColumns(columns));
		// datos hoja
		usuarioExcelDataAll.setModelData(listProgramasAll);
		reportData.add(usuarioExcelDataAll);
		// Hoja 2
		ReportData<PagosExpediente> usuarioExcelDataPage = new ReportData<PagosExpediente>();
		// nombre hoja
		usuarioExcelDataPage
				.setSheetName(appMessageSource.getMessage("usuarioExcel.pagosPag1Expediente", null, locale));
		// cabeceras hoja
		usuarioExcelDataPage.setHeaderNames(ReportData.parseColumns(columns));
		// datos hoja
		usuarioExcelDataPage.setModelData(listProgramasPage);
		reportData.add(usuarioExcelDataPage);
		modelMap.put("reportData", reportData);

		// Generacion del XLS o XLSX
		if (request.getServletPath().indexOf("xlsReport") != -1) {
			return new ModelAndView("xlsReport", modelMap);
		} else {
			return new ModelAndView("xlsxReport", modelMap);
		}
	}
}
