package com.ejie.ab63.service.generarPublicacion;

import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ejie.ab63.comun.Constantes;
import com.ejie.ab63.comun.utilidades.config.Config;
import com.ejie.ab63.model.Establecimiento;
import com.ejie.ab63.model.TercerosEstablecimiento;
import com.ejie.ab63.service.EstablecimientoDataService;
import com.ejie.ab63.service.EstablecimientoService;
import com.ejie.ab63.service.TercerosEstablecimientoService;
import com.ejie.ab63.util.GenerarPublicacion;
import com.ejie.ab63.util.UtilDate;

@Service(value = "generarPublicacionService")
public class GenerarPublicacionServiceImpl implements GenerarPublicacionService {

	@Autowired
	EstablecimientoService establecimientoService;
	@Autowired
	EstablecimientoDataService establecimientoDataService;
	@Autowired
	TercerosEstablecimientoService tercerosEstablecimientoService;

	private static final Log logger = LogFactory.getLog(GenerarPublicacionServiceImpl.class);

	@Override
	public int generarPublicacion(Integer idEstablecimiento) throws Exception {
		Establecimiento establecimientoFind = new Establecimiento(idEstablecimiento);
		// Establecimiento establecimientoDetalle =
		// establecimientoService.find(establecimientoFind);

		Establecimiento establecimientoResumen = establecimientoService.find(establecimientoFind);
		establecimientoDataService.completeEstablecimientoData(establecimientoResumen,
				Constantes.TIPO_REGISTRO_RESUMEN);

		// establecimientoDataService.completeEstablecimientoData(establecimientoDetalle,
		// Constantes.TIPO_REGISTRO_DETALLE);

		List<TercerosEstablecimiento> listTercerosEstablecimiento = tercerosEstablecimientoService
				.findAllByEstablecimientoConDireccion(establecimientoFind);
		establecimientoResumen.setListTercerosEstablecimiento(listTercerosEstablecimiento);

		return validarPublicacion(establecimientoResumen);
	}

	private int publicacion(boolean isBaja, Establecimiento establecimiento) throws Exception {
		boolean isNewBaja = isBaja || (null != establecimiento.getEliminado()
				&& Constantes.SI_INT == Integer.parseInt(establecimiento.getEliminado()));
		// En caso de eliminar, solo se envía a S41 cuando ya estaba dado de
		// alta previamente.
		int resultado = 0;
		if (!isNewBaja || (isNewBaja && establecimiento.getIdPortalS41() != null)) {
			GenerarPublicacion generarPublicacion = new GenerarPublicacion(establecimiento.getIdPortalS41(), isNewBaja,
					establecimiento);
			resultado = PublicarMensaje.envioMensajeJMS(generarPublicacion.getRecursoS41Doc(),
					generarPublicacion.getTipologia(), generarPublicacion.getEvento());

			// Actualizar la fecha de control de S41

			establecimiento.setFechaControlS41(new Date());

			// if (Constantes.TipoEstablecimiento.ESTABLECIMIENTO_AGENC_VIAJE
			// .equalsIgnoreCase(establecimiento.getTipoEstablecimiento().getIdTipoEstablecimiento())
			// &&
			// establecimiento.getModalidad().equals(Constantes.ModalidadFijos.AAVV_SUCURSAL))
			// {
			//
			// establecimiento.setPubliAutomatismoS41(Y85nbConstantes.Y85nbISINO.ABREV_NO);
			// }

			this.establecimientoService.update(establecimiento);
		}
		return resultado;
	}

	public int validarPublicacion(Establecimiento establecimiento) throws Exception {

		boolean pasaValidaciones = false;

		pasaValidaciones = this.validarDatosObligatorios(establecimiento);

		boolean isBaja = null != establecimiento.getFechaBaja();
		Long idPortalS41 = establecimiento.getIdPortalS41();

		if (Constantes.NO_ELIMINADO.equals(establecimiento.getEliminado())) {
			if (isBaja && idPortalS41 == null) {
				// Si se va a eliminar y no se ha dado de alta previamente no se
				// da de baja en S41 porque no existe
				GenerarPublicacionServiceImpl.logger.error("El establecimiento "
						+ establecimiento.getIdentificadorEstablecimiento() + " no esta dado de alta en S41");
				pasaValidaciones = false;
			}
		}
		isBaja = isBaja || (Constantes.SI_ELIMINADO.equals(establecimiento.getEliminado()));

		if (pasaValidaciones) {
			this.publicacion(isBaja, establecimiento);

			// TRATAMIENTO SUCURSALES, EN LOS CASOS QUE LA INSTALACION A
			// PUBLICAR
			// SEA AGENCIA DE VIAJES Y DE TIPO OFICINA PRINCIPAL
			// recogemos aqui las sucursales (si es agencia de viajes y oficina
			// principal) que tengan algún cambio propagado desde la oficina
			// principal, para validarlas antes de hacer nignuna públicación al
			// S41
			if (Constantes.TipoEstablecimiento.ESTABLECIMIENTO_AGENC_VIAJE
					.equalsIgnoreCase(establecimiento.getTipoEstablecimiento().getIdTipoEstablecimiento())
					&& establecimiento.getModalidad().equals(Constantes.ModalidadFijos.AAVV_PRINCIPAL)) {
				List<Establecimiento> sucursales = establecimientoService
						.findSucursalesOficinaPrincipal(establecimiento.getIdEstablecimiento());
				if (!sucursales.isEmpty()) {
					for (Establecimiento sucursal : sucursales) {
						pasaValidaciones = this.validarDatosObligatorios(sucursal);
						// publicamos las sucursales
						if (pasaValidaciones) {
							this.publicacion(isBaja, sucursal);
						}
					}
				} else {
					pasaValidaciones = false;
				}
			}
		}
		GenerarPublicacionServiceImpl.logger.error("Validaciones s41 --> " + pasaValidaciones);
		return pasaValidaciones ? 0 : 1;
	}

	protected boolean validarDatosObligatorios(Establecimiento establecimiento) throws Exception {
		// comprobar que se puede publicar (web activo)
		boolean pasaValidaciones = true;
		if (!String.valueOf(Constantes.SI_INT).equalsIgnoreCase(establecimiento.getVisibleweb())) {
			pasaValidaciones = false;
		}
		if (pasaValidaciones && null != this.validarPlazoS41(establecimiento)) {
			pasaValidaciones = false;
		}
		// Comprobar que la signatura no sea temporal
		if (pasaValidaciones
				&& !Constantes.TIPO_REGISTRO_DEFINITIVO.equalsIgnoreCase(establecimiento.getTipoRegistro())) {
			pasaValidaciones = false;
		}
		if (pasaValidaciones && null == establecimiento.getTipoEstablecimiento()
				|| null == establecimiento.getTipoEstablecimiento().getIdTipoEstablecimiento()) {
			pasaValidaciones = false;
		}
		if (pasaValidaciones) {
			pasaValidaciones = tieneTitular(establecimiento);
		}
		// if (pasaValidaciones && null == establecimiento.getFechaBaja()) {
		// pasaValidaciones = false;
		// }
		if (pasaValidaciones && null == establecimiento.getDescrNombre()) {
			pasaValidaciones = false;
		}
		if (pasaValidaciones) {
			pasaValidaciones = tieneDireccion(establecimiento);
		}

		return pasaValidaciones;
	}

	private boolean tieneTitular(Establecimiento establecimiento) {
		boolean blnEncontrado = false;
		if (null != establecimiento.getDatosTerceros()) {
			blnEncontrado = true;
		}
		return blnEncontrado;
	}

	private boolean tieneDireccion(Establecimiento establecimiento) {
		boolean blnEncontrado = false;
		if (null != establecimiento.getDatosDirecciones()) {
			blnEncontrado = true;
		}
		return blnEncontrado;
	}

	public String validarPlazoS41(Establecimiento establecimiento) throws Exception {
		// comprobar la fecha de control para ver si se puede realizar
		// la
		// llamada
		String fechaControl = null;
		if (null != establecimiento.getFechaControlS41()) {
			fechaControl = String.valueOf(establecimiento.getFechaControlS41().getTime());
			if (null != fechaControl) {
				// Si no es nulo significa que se ha realizado ya una
				// llamada
				// sin respuesta, por lo que hay que mirar los dias que han
				// pasado
				int plazo = this.getPlazoS41();
				if (plazo == 0) {
					// Eliminar la fecha de control para permitir llamar
					fechaControl = null;
				} else {
					// Si hay plazo, comprobar que la fecha mas el plazo es
					// anterior a hoy para permitir realizar la llamada
					long fechaS41 = Long.parseLong(fechaControl);
					long fechaS41Plazo = fechaS41 + (plazo * Constantes.MILIS_MINUTO);

					if (fechaS41Plazo <= UtilDate.fechaHoy().getTime()) {
						// Eliminar la fecha de control para permitir llamar
						fechaControl = null;
					}
				}
			}
		}
		return fechaControl;
	}

	public int getPlazoS41() throws Exception {
		Properties prop = Config.loadProperties(Constantes.COD_APPL_CONFIG);
		return Integer.parseInt(prop.getProperty("PLAZO_S41"));
	}
}