package com.ejie.m62fb.service.registroVPP;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;
import com.ejie.m62fb.dao.registroVPP.ContratoAlquilerDao;
import com.ejie.m62fb.dao.registroVPP.ContratoViviendaDao;
import com.ejie.m62fb.dao.registroVPP.ExpedienteViviendaDao;
import com.ejie.m62fb.dao.registroVPP.InquilinoDao;
import com.ejie.m62fb.dao.registroVPP.PropietarioDao;
import com.ejie.m62fb.dao.registroVPP.ViviendaDao;
import com.ejie.m62fb.model.ContratoVivienda;
import com.ejie.m62fb.model.ExpedienteVivienda;
import com.ejie.m62fb.model.Inquilino;
import com.ejie.m62fb.model.Propietario;
import com.ejie.m62fb.model.Vivienda;
import com.ejie.m62fb.model.importar.Feedback;
import com.ejie.m62fb.model.importar.FeedbackError;
import com.ejie.m62fb.model.jaxb.solicitudCalifProv.SolicitudCalificacionProvisional;
import com.ejie.m62fb.model.jaxb.solicitudCalifProv.SolicitudCalificacionProvisional.ContratosAlquiler.ContratoAlquiler;
import com.ejie.m62fb.model.jaxb.solicitudCalifProv.SolicitudCalificacionProvisional.ContratosCompraVenta.ContratoCompraVenta;
import com.ejie.m62fb.model.jaxb.solicitudCalifProv.SolicitudCalificacionProvisional.ContratosCompraVenta.ContratoCompraVenta.Titular;
import com.ejie.m62fb.model.persona.Persona;
import com.ejie.m62fb.model.tipos.TipoSiNo;
import com.ejie.m62fb.model.tipos.TipoTransmision;
import com.ejie.m62fb.utils.constants.AppConstantes;
import com.ejie.m62fb.utils.sql.BDUtils;
import com.ejie.x38.util.DateTimeManager;

/**
 * CargaFicheroSolicCalifProvDefServiceImpl.
 * 
XXXX
 */
@Service(value = "cargaFicheroSolicCalifProvDefService")
public class CargaFicheroSolicCalifProvDefServiceImpl implements CargaFicheroSolicCalifProvDefService {
	@Autowired
	private CargaFicherosService cargaFicherosService;
	@Autowired
	private ExpedienteViviendaDao expedienteViviendaDao;
	@Autowired
	private ViviendaDao viviendaDao;
	@Autowired
	private ContratoViviendaDao contratoViviendaDao;
	@Autowired
	private ContratoAlquilerDao contratoAlquilerDao;
	@Autowired 
	private PropietarioDao propietarioDao;
	@Autowired 
	private InquilinoDao inquilinoDao;
	@Autowired
	ReloadableResourceBundleMessageSource  messageSource;
	@Override
	
	
	//1-CARGA FICHERO SOLICITUD DE CALIF PROVIS DEFINITIVA
	public List<Feedback> cargarFicheroContratosSolicCalifDef(SolicitudCalificacionProvisional solicitudCalificacionProvisional,
			String numExpediente, Date fechaEntrada) throws ParseException {
		List<Feedback> listaErroresAvisos = validarContratosSolicCalifDef(solicitudCalificacionProvisional,numExpediente);
		if (listaErroresAvisos.size()==0){
			insertarDatosContratosSolicCalifDef(solicitudCalificacionProvisional,numExpediente,fechaEntrada);
		}
		return listaErroresAvisos;
	}
	
	//1.1-VALIDAR CONTRATOS COMPRAVENTA SOLICITUD DE CALIF PROVIS DEFINITIVA
	private void validarContratoCompraVenta(List<Feedback> listaErroresAvisos,List<ContratoCompraVenta> contratos,String numExpediente,Locale locale){
		for (ContratoCompraVenta contratoXML  : contratos) {
			//VALIDAR QUE LA VIVIENDA EXISTA
			ExpedienteVivienda expedienteVivienda = new ExpedienteVivienda(numExpediente.substring(0,15)+
					String.format("%03d", Integer.parseInt(contratoXML.getNumVivienda())));
			if(expedienteViviendaDao.findIdVivienda(expedienteVivienda.getNumExpediente())==null){
				FeedbackError error = new FeedbackError();
				error.setHoja(AppConstantes.NOM_HOJA_CONTRATOS_COMPRA);
				error.setElemento(messageSource.getMessage("error.importar.xls.vivienda", null, locale));
				error.setDescripcion(messageSource.getMessage("error.importar.xls.vivienda.no.existe", 
						new Object[] {contratoXML.getNumVivienda(),numExpediente}, locale));
				listaErroresAvisos.add(error);
			}
			//VALIDAR CONTRATO COMPRAVENTA
			cargaFicherosService.validarContratoCompra(listaErroresAvisos, contratoXML.getNumVivienda(), contratoXML.getFecVenta(), locale);
			//VALIDAR TITULARES
			List<String> titulares=new ArrayList<String>();
			for (Titular titular : contratoXML.getTitular()) {
				cargaFicherosService.validarDatosTitular(listaErroresAvisos,titulares, AppConstantes.NOM_HOJA_CONTRATOS_COMPRA,
						contratoXML.getNumVivienda(), titular.getDNI(), titular.getNombre(), titular.getApellido1(), titular.getApellido2(), locale);
			}
		}
	}
	//1.2-VALIDAR CONTRATOS ALQUILER SOLICITUD DE CALIF PROVIS DEFINITIVA
	/**
	 * Validar Contrato de alquiler de 
	 * @param listaErroresAvisos
	 * @param contratos
	 * @param numExpediente
	 * @param locale
	 */
	private void validarContratoAlquiler(List<Feedback> listaErroresAvisos,List<ContratoAlquiler> contratos,String numExpediente,Locale locale){
		for (ContratoAlquiler contratoXML  : contratos) {
			//VALIDAR QUE LA VIVIENDA EXISTA
			ExpedienteVivienda expedienteVivienda = new ExpedienteVivienda(numExpediente.substring(0,15)+
					String.format("%03d", Integer.parseInt(contratoXML.getNumVivienda())));
			if(expedienteViviendaDao.findIdVivienda(expedienteVivienda.getNumExpediente())==null){
				FeedbackError error = new FeedbackError();
				error.setHoja(AppConstantes.NOM_HOJA_CONTRATOS_ALQUILER);
				error.setElemento(messageSource.getMessage("error.importar.xls.vivienda", null, locale));
				error.setDescripcion(messageSource.getMessage("error.importar.xls.vivienda.no.existe", 
						new Object[] {contratoXML.getNumVivienda(),numExpediente}, locale));
				listaErroresAvisos.add(error);
			}
			//VALIDAR CONTRATO ALQUILER
			cargaFicherosService.validarContratoAlquiler(listaErroresAvisos, contratoXML.getNumVivienda(), contratoXML.getFecInicioAlquiler(), contratoXML.getFecFinAlquiler(), locale);
			//VALIDAR TITULARES
			List<String> titulares=new ArrayList<String>();
			for (com.ejie.m62fb.model.jaxb.solicitudCalifProv.SolicitudCalificacionProvisional.ContratosAlquiler.ContratoAlquiler.Titular 
					titular : contratoXML.getTitular()) {
				
				cargaFicherosService.validarDatosTitular(listaErroresAvisos,titulares, AppConstantes.NOM_HOJA_CONTRATOS_ALQUILER,
						contratoXML.getNumVivienda(), titular.getDNI(), titular.getNombre(), titular.getApellido1(), titular.getApellido2(), locale);
			}
		}
	}
	private List<Feedback> validarContratosSolicCalifDef(SolicitudCalificacionProvisional solicitudCalificacionProvicional,String numExpediente){
		Locale locale = LocaleContextHolder.getLocale();
		List<Feedback> listaErroresAvisos=new ArrayList<Feedback>();
		//INICIO CONTRATO COMPRAVENTA
		validarContratoCompraVenta(listaErroresAvisos,solicitudCalificacionProvicional.getContratosCompraVenta().getContratoCompraVenta(),numExpediente,locale);
		//FIN CONTRATO COMPRAVENTA
		//INICIO CONTRATO ALQUILER
		validarContratoAlquiler(listaErroresAvisos,solicitudCalificacionProvicional.getContratosAlquiler().getContratoAlquiler(),numExpediente,locale);
		//FIN CONTRATO ALQUILER
		return listaErroresAvisos;
	}
	public void insertarDatosContratosSolicCalifDef(
			SolicitudCalificacionProvisional solicitudCalificacionProvisional,
			String numExpediente,Date fechaEntradaContrato) throws ParseException{
		for (ContratoCompraVenta contratoXML  : solicitudCalificacionProvisional.getContratosCompraVenta().getContratoCompraVenta()) {
			ContratoVivienda contratoVivienda=new ContratoVivienda();
			//VIVIENDA + GARAJE + TRASTERO
//			Alojamiento alojamiento= getDatosAlojamiento(solicitudCalificacionProvisional,contratoXML.getNumVivienda());
			//ExpedienteVivienda
			ExpedienteVivienda expedienteVivienda = new ExpedienteVivienda(numExpediente.substring(0,15)+
					String.format("%03d", Integer.parseInt(contratoXML.getNumVivienda())));
			contratoVivienda.setExpedienteVivienda(expedienteVivienda);
			//Vivienda
			Vivienda vivienda = new Vivienda(expedienteViviendaDao.findIdVivienda(expedienteVivienda.getNumExpediente()));
			contratoVivienda.setVivienda(viviendaDao.find(vivienda));
			//COD_TIPO_TRANS = 1 PRIMERA
			contratoVivienda.setTipoTransmision(new TipoTransmision(TipoTransmision.PRIMERA));
			//FECHA VENTA
			SimpleDateFormat format = contratoXML.getFecVenta().length()>10?DateTimeManager.getTimestampFormat(AppConstantes.ES_LOCALE):DateTimeManager.getDateTimeFormat(AppConstantes.ES_LOCALE);
			contratoVivienda.setFecTransmision(format.parse(contratoXML.getFecVenta()));
			//FEC_ENT_CONTRATO  -> Fecha entrada que se ha introducido al comienzo de la carga
			contratoVivienda.setFecEntContrato(fechaEntradaContrato);
			//IND_VIV_ADAPTADA
			contratoVivienda.setIndVivAdaptada(new TipoSiNo(contratoVivienda.getVivienda().getIndVivAdaptada()));
			
			BigDecimal numPropieterio=contratoViviendaDao.findNumPropietarioMaxMasUno(vivienda.getNumVivienda());
			contratoVivienda=contratoViviendaDao.add(contratoVivienda);
			for (Titular titular : contratoXML.getTitular()) {
				Propietario propietario=new Propietario(numPropieterio);
				Persona persona=cargaFicherosService.addPersonaIfNoExists(titular.getDNI(),titular.getNombre(),titular.getApellido1(),titular.getApellido2());

				propietario.setVivienda(vivienda);
				propietario.setExpedienteVivienda(expedienteVivienda);
				propietario.setPersona(persona);
				propietario.setIndTitular(new TipoSiNo(BDUtils.TRUE));
				double porcentaje=100.00/contratoXML.getTitular().size();
				propietario.setPorTitularidad(BigDecimal.valueOf(porcentaje));
				propietarioDao.add(propietario);
			}
		}
		for (ContratoAlquiler contratoXML  : solicitudCalificacionProvisional.getContratosAlquiler().getContratoAlquiler()) {
			com.ejie.m62fb.model.ContratoAlquiler contratoAlquiler=new com.ejie.m62fb.model.ContratoAlquiler();
			//VIVIENDA + GARAJE + TRASTERO
//			Alojamiento alojamiento= getDatosAlojamiento(solicitudCalificacionProvisional,contratoXML.getNumVivienda());
			//ExpedienteVivienda
			ExpedienteVivienda expedienteVivienda = new ExpedienteVivienda(numExpediente.substring(0,15)+
					String.format("%03d", Integer.parseInt(contratoXML.getNumVivienda())));
			contratoAlquiler.setExpedienteVivienda(expedienteVivienda);
			//Vivienda
			Vivienda vivienda = new Vivienda(expedienteViviendaDao.findIdVivienda(expedienteVivienda.getNumExpediente()));
			contratoAlquiler.setVivienda(viviendaDao.find(vivienda));
			//FEC_ENT_CONTRATO  -> Fecha entrada que se ha introducido al comienzo de la carga
			contratoAlquiler.setFecEntContrato(fechaEntradaContrato);
			//COD_TIPO_TRANS = 1 PRIMERA
			//contratoVivienda.setTipoTransmision(new TipoTransmision(TipoTransmision.PRIMERA));
			//FEC_INICIO
			SimpleDateFormat format = contratoXML.getFecInicioAlquiler().length()>10?DateTimeManager.getTimestampFormat(AppConstantes.ES_LOCALE):DateTimeManager.getDateTimeFormat(AppConstantes.ES_LOCALE);
			contratoAlquiler.setFecInicio(format.parse(contratoXML.getFecInicioAlquiler()));
			//FEC_ALQUILER
			format = contratoXML.getFecFinAlquiler().length()>10?DateTimeManager.getTimestampFormat(AppConstantes.ES_LOCALE):DateTimeManager.getDateTimeFormat(AppConstantes.ES_LOCALE);
			contratoAlquiler.setFecFin(format.parse(contratoXML.getFecFinAlquiler()));
			//IND_VIV_ADAPTADA
			//IND_VIV_ADAPTADA
			contratoAlquiler.setIndVivAdaptada(new TipoSiNo(contratoAlquiler.getVivienda().getIndVivAdaptada()));
			
			BigDecimal numInquilino=contratoAlquilerDao.findNumInquilinoMaxMasUno(vivienda.getNumVivienda());
			contratoAlquiler=contratoAlquilerDao.add(contratoAlquiler);
			for (com.ejie.m62fb.model.jaxb.solicitudCalifProv.SolicitudCalificacionProvisional.ContratosAlquiler.ContratoAlquiler.Titular 
					titular : contratoXML.getTitular()) {
				Inquilino inquilino=new Inquilino(numInquilino);
				Persona persona=cargaFicherosService.addPersonaIfNoExists(titular.getDNI(),titular.getNombre(),titular.getApellido1(),titular.getApellido2());

				inquilino.setVivienda(vivienda);
				inquilino.setExpedienteVivienda(expedienteVivienda);
				inquilino.setPersona(persona);
				inquilinoDao.add(inquilino);
			}
		}
	}
//	private Alojamiento getDatosAlojamiento(SolicitudCalificacionProvisional solicitudCalificacionProvisional, String numVivienda){
//		for (AlojamientoGeneral alojamiento : solicitudCalificacionProvisional.getViviendas().getAlojamientos().getAlojamientoGeneral()) {
//			if (alojamiento.getNumVivienda().equalsIgnoreCase(numVivienda)){
//				return alojamiento.getAlojamiento();
//			}
//		}
//		return null;
//	}
}

	