package com.ejie.m62fb.control.registroVPP;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

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

import com.ejie.m62fb.utils.constants.IberErrorsMsgConstants;
import com.ejie.m62fb.utils.error.UFException;
import com.ejie.m62fb.utils.memory.ListUtils;
import com.ejie.m62fb.model.importar.Feedback;
import com.ejie.m62fb.model.importar.FeedbackAviso;
import com.ejie.m62fb.model.importar.FeedbackError;
import com.ejie.m62fb.model.jaxb.comunicacionAD.ComunicacionAlojamientosDotacionales;
import com.ejie.m62fb.model.jaxb.comunicacionVPPAyto.ComunicacionVPPAyuntamientos;
import com.ejie.m62fb.model.jaxb.solicitudCalifProv.SolicitudCalificacionProvisional;
import com.ejie.m62fb.service.registroVPP.CargaFicheroADService;
import com.ejie.m62fb.service.registroVPP.CargaFicheroComunicacionVPPAytoService;
import com.ejie.m62fb.service.registroVPP.CargaFicheroSolicCalifProvDefService;
import com.ejie.m62fb.service.registroVPP.CargaFicherosService;
import com.ejie.m62fb.utils.constants.AppConstantes;
import com.ejie.x38.control.bind.annotation.RequestJsonBody;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.ejie.x38.reports.ReportData;

/**
 * M62fbDisponibilidadVivsController generated by UDA, 17-oct-2012 15:45:51.
 * 
XXXX
 */

@Controller
@RequestMapping(value = "/viviendas/importxls/validarfichero")
public class ValidaFicherosController {
	
	private static final Logger logger = LoggerFactory
			.getLogger(ValidaFicherosController.class);
	@Autowired
	private CargaFicherosService cargaFicherosService;
	@Autowired
	private CargaFicheroADService cargaFicheroADervice;
	@Autowired
	private CargaFicheroSolicCalifProvDefService cargaFicheroSolicCalifProvDefService;
	@Autowired
	private CargaFicheroComunicacionVPPAytoService cargaFicheroComunicacionVPPAyto;

	/**
	 * 
	 * @param filterExcepciones
	 * @param jqGridRequestDto
	 * @param request
	 * @param session
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/filter", method = RequestMethod.POST)
	public @ResponseBody
	JQGridResponseDto<Feedback> filter(
			@RequestJsonBody(param = "filter") Feedback filterExcepciones,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto,
			HttpServletRequest request, HttpSession session) {
		ValidaFicherosController.logger
				.info("[POST - filter] : Obtener errores");
		try {
			// obtenemos de la session la lista de errores
			List<Feedback> erroresSession = (List<Feedback>) session
					.getAttribute("LISTAERRORES");

			if (erroresSession != null && erroresSession.size() > 0) {
				JQGridResponseDto<Feedback> data = new JQGridResponseDto<Feedback>(
						jqGridRequestDto, Long.valueOf(erroresSession
								.size()), ListUtils.paginateList(
										erroresSession, jqGridRequestDto));
				return data;
			}
			// Devolvemos una lista vacia
			return devolverListaVacia();
		} catch (UFException e) {
			// Si recibimos una exception UF la relanzamos.
			throw e;
		} catch (Exception e) {
			// Cualquier otra exception de la aplicación.
			throw new UFException(IberErrorsMsgConstants.UNEXPECTED_MSG);
		}
	}
	/**
	 * 
	 * @return Lista vacia
	 */
	private JQGridResponseDto<Feedback> devolverListaVacia() {
		// Devolvemos una lista vacia
		JQGridResponseDto<Feedback> jqGridResponseDto = new JQGridResponseDto<Feedback>();
		jqGridResponseDto.setPage("1");
		jqGridResponseDto.setRecords(0);
		jqGridResponseDto.setTotal(Long.valueOf(0), Long.valueOf(0));
		jqGridResponseDto.setRows(new ArrayList<Feedback>());
		return jqGridResponseDto;
	}
	/**
	 * 
	 * @param numExpediente
	 * @param fechaEntrada
	 * @param comboTipoFicheroCarga
	 * @param file
	 * @return
	 * @throws IOException 
	 * @throws JAXBException 
	 * @throws ParseException 
	 */
	
	@RequestMapping(value="/comprobar", method = RequestMethod.POST)
	public @ResponseBody List<Map<String,Object>> addForm(
			@RequestParam(value = "numExpediente", required = true) String numExpediente,
			@RequestParam(value = "fechaEntrada", required = true) Date fechaEntrada,
			@RequestParam(value = "comboTipoFicheroCarga", required = true) int comboTipoFicheroCarga,
			@RequestParam(value = "tipoCarga", required = true) int tipoCarga,
			@RequestParam(value="datosXml", required=true) MultipartFile file,HttpSession session) throws JAXBException, IOException, ParseException {
		List<Map<String,Object>> filesMetaInfo = new ArrayList<Map<String,Object>>();
		if (tipoCarga==1){
			 importarConAvisos( session);
			 return filesMetaInfo;
		}
		JAXBContext jaxbContext;
		Unmarshaller jaxbUnmarshaller;
		this.cargaFicherosService.validarTipoExpediente(comboTipoFicheroCarga, numExpediente);
		List<Feedback> listaErroresAvisos=new ArrayList<Feedback>();
		session.removeAttribute("LISTAERRORES");
		session.removeAttribute("numExpediente");
		session.removeAttribute("fechaEntrada");
		session.removeAttribute("comboTipoFicheroCarga");
		session.removeAttribute("file");
		switch (comboTipoFicheroCarga) {
			case AppConstantes.COMUNICACION_VPP_AYUNTAMIENTOS:
				this.cargaFicherosService.validarTipoFichero(AppConstantes.COMUNICACION_VPP_AYUNTAMIENTOS,file.getOriginalFilename().split("\\.")[0]);
				jaxbContext = JAXBContext.newInstance(AppConstantes.INSTANCE_COMUNICACION_VPP_AYUNTAMIENTOS);
				 jaxbUnmarshaller = jaxbContext.createUnmarshaller();
				//ComunicacionAlojamientosDotacionales comunicacionAlojamiento = (ComunicacionAlojamientosDotacionales) jaxbUnmarshaller.unmarshal(file2);
				ComunicacionVPPAyuntamientos comunicacionVPPAyuntamientos = (ComunicacionVPPAyuntamientos) jaxbUnmarshaller.unmarshal(file.getInputStream());
				
				cargaFicherosService.validarVersionFichero(
						AppConstantes.COMUNICACION_VPP_AYUNTAMIENTOS, 
						comunicacionVPPAyuntamientos.getVersion());
				session.setAttribute("fileObj", comunicacionVPPAyuntamientos);
				listaErroresAvisos=cargaFicheroComunicacionVPPAyto.cargarFicheroComunicacionVPPAyto(comunicacionVPPAyuntamientos, numExpediente, fechaEntrada);
				
			break;
		case AppConstantes.CONTRATOS_COMUNICACION_ALOJAMIENTOS_DOTACIONALES:
			this.cargaFicherosService.validarTipoFichero(AppConstantes.CONTRATOS_COMUNICACION_ALOJAMIENTOS_DOTACIONALES,file.getOriginalFilename().split("\\.")[0]);
			jaxbContext = JAXBContext.newInstance(AppConstantes.INSTANCE_CONTRATOS_COMUNICACION_ALOJAMIENTOS_DOTACIONALES);
			 jaxbUnmarshaller = jaxbContext.createUnmarshaller();
			//ComunicacionAlojamientosDotacionales comunicacionAlojamiento = (ComunicacionAlojamientosDotacionales) jaxbUnmarshaller.unmarshal(file2);
			ComunicacionAlojamientosDotacionales comunicacionAlojamiento = (ComunicacionAlojamientosDotacionales) jaxbUnmarshaller.unmarshal(file.getInputStream());
			cargaFicherosService.validarVersionFichero(
					AppConstantes.CONTRATOS_COMUNICACION_ALOJAMIENTOS_DOTACIONALES, 
					comunicacionAlojamiento.getVersion());
			session.setAttribute("fileObj", comunicacionAlojamiento);
			listaErroresAvisos=cargaFicheroADervice.cargarFicheroComunicacionAloDot(comunicacionAlojamiento, numExpediente, fechaEntrada);
			
			break;
		case AppConstantes.CONTRATOS_SOLICITUD_CALIFICACION_PROVISIONAL_DEFINITIVA:
			this.cargaFicherosService.validarTipoFichero(AppConstantes.CONTRATOS_SOLICITUD_CALIFICACION_PROVISIONAL_DEFINITIVA,file.getOriginalFilename().split("\\.")[0]);
			jaxbContext = JAXBContext.newInstance(AppConstantes.INSTANCE_CONTRATOS_SOLICITUD_CALIFICACION_PROVISIONAL_DEFINITIVA);
			 jaxbUnmarshaller = jaxbContext.createUnmarshaller();
			//ComunicacionAlojamientosDotacionales comunicacionAlojamiento = (ComunicacionAlojamientosDotacionales) jaxbUnmarshaller.unmarshal(file2);
			SolicitudCalificacionProvisional solicitudCalificacionProvisional = (SolicitudCalificacionProvisional) jaxbUnmarshaller.unmarshal(file.getInputStream());
			cargaFicherosService.validarVersionFichero(
					AppConstantes.CONTRATOS_SOLICITUD_CALIFICACION_PROVISIONAL_DEFINITIVA,
					solicitudCalificacionProvisional.getVersion());
			session.setAttribute("fileObj", solicitudCalificacionProvisional);
			listaErroresAvisos=cargaFicheroSolicCalifProvDefService.cargarFicheroContratosSolicCalifDef(solicitudCalificacionProvisional, numExpediente, fechaEntrada);
				break;
		default:
			break;
		}
//		List<Map<String,Object>> filesMetaInfo = new ArrayList<Map<String,Object>>();
		filesMetaInfo.add(this.getFileReturnMap(file));
		StringBuilder mensajeTXT=new StringBuilder();
		//mensajeTXT.append("aviso");
		for (Feedback mensaje : listaErroresAvisos) {
			if(mensaje.getTipo()==FeedbackError.TIPO){
				mensajeTXT=new StringBuilder("error");
			}
			if(mensaje.getTipo()==FeedbackAviso.TIPO){
				if(mensajeTXT.length()==0){
					mensajeTXT=new StringBuilder("aviso");
				}
			}
		}
		if (mensajeTXT.length()>0){
			session.setAttribute("LISTAERRORES", listaErroresAvisos);
			session.setAttribute("numExpediente", numExpediente);
			session.setAttribute("fechaEntrada", fechaEntrada);
			session.setAttribute("comboTipoFicheroCarga", comboTipoFicheroCarga);
			
			throw new UFException(mensajeTXT.toString());
		}
			
		return filesMetaInfo;
		
	}
	/**
	 * 
	 */
	@RequestMapping(value="importarConAvisos", method = RequestMethod.GET)
	public @ResponseBody Boolean importarConAvisos(HttpSession session) throws JAXBException, IOException, ParseException {
		try{
			JAXBContext jaxbContext;
			Unmarshaller jaxbUnmarshaller;
			
			List<Feedback> listaErroresAvisos=new ArrayList<Feedback>();
//			MultipartFile file=(MultipartFile)session.getAttribute("file");
			Date fechaEntrada=(Date)session.getAttribute("fechaEntrada");
			String numExpediente=session.getAttribute("numExpediente").toString();
			int comboTipoFicheroCarga=(Integer)session.getAttribute("comboTipoFicheroCarga");
			this.cargaFicherosService.validarTipoExpediente(comboTipoFicheroCarga, numExpediente);
			
			switch (comboTipoFicheroCarga) {
				case AppConstantes.COMUNICACION_VPP_AYUNTAMIENTOS:
					jaxbContext = JAXBContext.newInstance(AppConstantes.INSTANCE_COMUNICACION_VPP_AYUNTAMIENTOS);
					 jaxbUnmarshaller = jaxbContext.createUnmarshaller();
					ComunicacionVPPAyuntamientos comunicacionVPPAyuntamientos = (ComunicacionVPPAyuntamientos)session.getAttribute("fileObj");//jaxbUnmarshaller.unmarshal(file.getInputStream());
					cargaFicheroComunicacionVPPAyto.insertarDatosComunicacionVPPAyto(comunicacionVPPAyuntamientos,numExpediente,fechaEntrada);
				break;
			case AppConstantes.CONTRATOS_COMUNICACION_ALOJAMIENTOS_DOTACIONALES:
				jaxbContext = JAXBContext.newInstance(AppConstantes.INSTANCE_CONTRATOS_COMUNICACION_ALOJAMIENTOS_DOTACIONALES);
				 jaxbUnmarshaller = jaxbContext.createUnmarshaller();
				ComunicacionAlojamientosDotacionales comunicacionAlojamiento = (ComunicacionAlojamientosDotacionales) session.getAttribute("fileObj");//jaxbUnmarshaller.unmarshal(file.getInputStream());
				cargaFicheroADervice.insertarDatosComunicacionAloDot(comunicacionAlojamiento,numExpediente,fechaEntrada);
				break;
			case AppConstantes.CONTRATOS_SOLICITUD_CALIFICACION_PROVISIONAL_DEFINITIVA:
				jaxbContext = JAXBContext.newInstance(AppConstantes.INSTANCE_CONTRATOS_SOLICITUD_CALIFICACION_PROVISIONAL_DEFINITIVA);
				 jaxbUnmarshaller = jaxbContext.createUnmarshaller();
				SolicitudCalificacionProvisional solicitudCalificacionProvisional = (SolicitudCalificacionProvisional) session.getAttribute("fileObj");//jaxbUnmarshaller.unmarshal(file.getInputStream());
				cargaFicheroSolicCalifProvDefService.insertarDatosContratosSolicCalifDef(solicitudCalificacionProvisional,numExpediente,fechaEntrada);
					break;
			default:
				break;
			}
			
			//return filesMetaInfo;
			StringBuilder mensajeTXT=new StringBuilder();
			for (Feedback mensaje : listaErroresAvisos) {
				if(mensaje.getTipo()==FeedbackError.TIPO){
					mensajeTXT.append("<div style='color:red;background-color:yellow'>");
					mensajeTXT.append("<ul>");
					mensajeTXT.append("<li>HOJA:").append(mensaje.getHoja()).append("</li>");
					mensajeTXT.append("<li>ELEMENTO:").append(mensaje.getElemento()).append("</li>");
					mensajeTXT.append("<li>DATO:").append(mensaje.getDato()).append("</li>");
					mensajeTXT.append("<li>DESCRIPCION:").append(mensaje.getDescripcion()).append("</li>");
					mensajeTXT.append("</ul>");
					mensajeTXT.append("</div>");
				}
			}
			if (mensajeTXT.length()>0){
				
				throw new UFException(mensajeTXT.toString());
			}
			session.removeAttribute("fileObj");
				return true;
		}
		catch(Exception e){
			throw new UFException(e.getMessage());
		}
	}
	
	private Map<String,Object> getFileReturnMap(MultipartFile file){
		
		Map<String,Object> mapaRetorno = new HashMap<String, Object>();
		
		mapaRetorno.put("url", "../upload?fileName="+file.getOriginalFilename());
		mapaRetorno.put("name", file.getOriginalFilename());
		mapaRetorno.put("type", file.getContentType());
		mapaRetorno.put("size", file.getSize());
		mapaRetorno.put("delete_url", "../upload?fileName="+file.getOriginalFilename());
		mapaRetorno.put("delete_type", "DELETE");
		
		return mapaRetorno;
		
	}
	
	@RequestMapping(value = {"xlsReport" , "xlsxReport"}, method = RequestMethod.POST)
	protected ModelAndView getExcelPOI(@ModelAttribute Feedback feedbackFilter, 
			@ModelAttribute JQGridRequestDto jqGridRequestDto,
			ModelMap modelMap,
			@RequestParam(value = "columns", required = false) String columns,
			HttpServletRequest request,HttpSession session){
		
		//Acceso a BD para recuperar datos
		//List<Elemento> listElementoPage = this.elementosService.findAllLike(filterElemento, jqGridRequestDto, false);
		jqGridRequestDto.setPage(null);
		jqGridRequestDto.setRows(null);
		// obtenemos de la session la lista de errores
		List<Feedback> erroresSession = (List<Feedback>) session
				.getAttribute("LISTAERRORES");
		
		//Nombre fichero
		modelMap.put("fileName", "Errores-Avisos");
		
		//Datos
		List<Object> reportData = new ArrayList<Object>();
			//Hoja 1
			ReportData<Feedback> erroresExcelDataAll = new ReportData<Feedback>();
				//nombre hoja
			erroresExcelDataAll.setSheetName("Todos los Elementos");
				//cabeceras hoja
			erroresExcelDataAll.setHeaderNames(ReportData.parseColumns(columns));
				//datos hoja
			erroresExcelDataAll.setModelData(erroresSession);
			reportData.add(erroresExcelDataAll);
		modelMap.put("reportData", reportData);
		
		//Generación del XLS o XLSX
		if (request.getServletPath().indexOf("xlsReport")!=-1){
			return new ModelAndView("xlsReport", modelMap);
		}else{
			return new ModelAndView("xlsxReport", modelMap);
		}
		
	}
}
