package com.ejie.ab63.service;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.ab63.comun.Constantes;
import com.ejie.ab63.dao.EstablecimientoDataDao;
import com.ejie.ab63.model.AgenciaData;
import com.ejie.ab63.model.Alojamiento;
import com.ejie.ab63.model.Aseo;
import com.ejie.ab63.model.Establecimiento;
import com.ejie.ab63.model.EstablecimientoData;
import com.ejie.ab63.model.Habitacion;
import com.ejie.ab63.model.HabitacionVivienda;
import com.ejie.ab63.model.OtrasDependenciasVivienda;
import com.ejie.ab63.model.Parcela;
import com.ejie.ab63.model.SalonComedor;
import com.ejie.ab63.model.Suite;
import com.ejie.ab63.model.ZonaOcio;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * Ab6321s00ServiceImpl  
 * 
 *  
 */

@Service(value = "establecimientoDataService")
public class EstablecimientoDataServiceImpl implements EstablecimientoDataService {

	@Autowired
	private EstablecimientoDataDao establecimientoDataDao;

	@Autowired
	private HabitacionService habitacionService;

	@Autowired
	private HabitacionViviendaService habitacionViviendaService;

	@Autowired
	private AlojamientoService alojamientoService;

	@Autowired
	private AseoService aseoService;

	@Autowired
	private OtrasDependenciasViviendaService otrasDependenciasViviendaService;

	@Autowired
	private SalonComedorService salonComedorService;

	@Autowired
	private SuiteService suiteService;

	@Autowired
	private ParcelaService parcelaService;

	@Autowired
	private HabitacionAlojamientoService habitacionAlojamientoService;

	@Autowired
	private ZonaOcioService zonaOcioService;

	@Autowired
	private AgenciaDataService agenciaDataService;

	/**
	 * Inserts a single row in the Ab6321s00 table.
	 *
	 * @param ab6321s00
	 *            Ab6321s00
	 * @return Ab6321s00
	 */
	@Transactional(rollbackFor = Throwable.class)
	public EstablecimientoData add(EstablecimientoData ab6321s00) {
		return this.establecimientoDataDao.add(ab6321s00);
	}

	/**
	 * Updates a single row in the Ab6321s00 table.
	 *
	 * @param ab6321s00
	 *            Ab6321s00
	 * @return Ab6321s00
	 */
	@Transactional(rollbackFor = Throwable.class)
	public EstablecimientoData update(EstablecimientoData ab6321s00) {
		return this.establecimientoDataDao.update(ab6321s00);
	}

	/**
	 * Finds a single row in the Ab6321s00 table.
	 *
	 * @param ab6321s00
	 *            Ab6321s00
	 * @return Ab6321s00
	 */
	public EstablecimientoData find(EstablecimientoData ab6321s00) {
		return (EstablecimientoData) this.establecimientoDataDao.find(ab6321s00);
	}

	/**
	 * Deletes a single row in the Ab6321s00 table.
	 *
	 * @param ab6321s00
	 *            Ab6321s00
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void remove(EstablecimientoData ab6321s00) {
		this.establecimientoDataDao.remove(ab6321s00);
	}

	/**
	 * Finds a list of rows in the Ab6321s00 table.
	 *
	 * @param ab6321s00
	 *            Ab6321s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return List<Ab6321s00>
	 */
	public List<EstablecimientoData> findAll(EstablecimientoData ab6321s00, JQGridRequestDto jqGridRequestDto) {
		return (List<EstablecimientoData>) this.establecimientoDataDao.findAll(ab6321s00, jqGridRequestDto);
	}

	/**
	 * Finds rows in the Ab6321s00 table using like.
	 *
	 * @param ab6321s00
	 *            Ab6321s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<Ab6321s00>
	 */
	public List<EstablecimientoData> findAllLike(EstablecimientoData ab6321s00, JQGridRequestDto jqGridRequestDto,
			Boolean startsWith) {
		return (List<EstablecimientoData>) this.establecimientoDataDao.findAllLike(ab6321s00, jqGridRequestDto,
				startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Removes rows from the Ab6321s00 table.
	 *
	 * @param filterAb6321s00
	 *            Ab6321s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 */
	public void removeMultiple(EstablecimientoData filterAb6321s00, JQGridRequestDto jqGridRequestDto,
			Boolean startsWith) {
		this.establecimientoDataDao.removeMultiple(filterAb6321s00, jqGridRequestDto, startsWith);
	}

	/**
	 * Filter method in the Ab6321s00 table.
	 *
	 * @param filterAb6321s00
	 *            Ab6321s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return JQGridResponseDto<Ab6321s00>
	 */
	public JQGridResponseDto<EstablecimientoData> filter(EstablecimientoData filterAb6321s00,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		List<EstablecimientoData> listaAb6321s00 = this.establecimientoDataDao.findAllLike(filterAb6321s00,
				jqGridRequestDto, false);
		Long recordNum = this.establecimientoDataDao
				.findAllLikeCount(filterAb6321s00 != null ? filterAb6321s00 : new EstablecimientoData(), false);
		if (jqGridRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<EstablecimientoData>> reorderSelection = this.establecimientoDataDao
					.reorderSelection(filterAb6321s00, jqGridRequestDto, startsWith);
			return new JQGridResponseDto<EstablecimientoData>(jqGridRequestDto, recordNum, listaAb6321s00,
					reorderSelection);
		}
		return new JQGridResponseDto<EstablecimientoData>(jqGridRequestDto, recordNum, listaAb6321s00);
	}

	/**
	 * Searches rows in the Ab6321s00 table.
	 *
	 * @param filterAb6321s00
	 *            Ab6321s00
	 * @param searchAb6321s00
	 *            Ab6321s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<Ab6321s00>>
	 */
	public List<TableRowDto<EstablecimientoData>> search(EstablecimientoData filterAb6321s00,
			EstablecimientoData searchAb6321s00, JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		return this.establecimientoDataDao.search(filterAb6321s00, searchAb6321s00, jqGridRequestDto, startsWith);
	}

	/**
	 * Reorder the selection made in Ab6321s00 table.
	 *
	 * @param filterAb6321s00
	 *            Ab6321s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return Object
	 */
	public Object reorderSelection(EstablecimientoData filterAb6321s00, JQGridRequestDto jqGridRequestDto,
			Boolean startsWith) {
		return this.establecimientoDataDao.reorderSelection(filterAb6321s00, jqGridRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE JERARQUIA
	 */

	/**
	 * Finder method in the hierarchical the Ab6321s00 table.
	 *
	 * @param filterAb6321s00
	 *            Ab6321s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return JQGridResponseDto<JerarquiaDto<Ab6321s00>>
	 */
	public JQGridResponseDto<JerarquiaDto<EstablecimientoData>> jerarquia(EstablecimientoData filterAb6321s00,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		List<JerarquiaDto<EstablecimientoData>> listaAb6321s00 = this.establecimientoDataDao
				.findAllLikeJerarquia(filterAb6321s00, jqGridRequestDto);
		Long recordNum = this.establecimientoDataDao.findAllLikeCountJerarquia(filterAb6321s00, jqGridRequestDto);
		return new JQGridResponseDto<JerarquiaDto<EstablecimientoData>>(jqGridRequestDto, recordNum, listaAb6321s00);
	}

	/**
	 * Finder method for siblings rows in the hierarchical the Ab6321s00 table.
	 *
	 * @param filterAb6321s00
	 *            Ab6321s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return JQGridResponseDto<JerarquiaDto<Ab6321s00>>
	 */
	public JQGridResponseDto<JerarquiaDto<EstablecimientoData>> jerarquiaChildren(EstablecimientoData filterAb6321s00,
			JQGridRequestDto jqGridRequestDto) {
		JQGridResponseDto<JerarquiaDto<EstablecimientoData>> jqGridResponseDto = new JQGridResponseDto<JerarquiaDto<EstablecimientoData>>();
		jqGridResponseDto.addAdditionalParam(JQGridResponseDto.CHILDREN,
				this.establecimientoDataDao.findAllChild(filterAb6321s00, jqGridRequestDto));
		return jqGridResponseDto;
	}

	@Override
	public void completeEstablecimientoData(Establecimiento establecimiento, int tipoRegistro) {
		// cambios a hacer logica actual a un metodo aparte, si no es una aavv
		// llamar metodo nuevo sino llamar metodo nuevo con la logica que carga
		// la informacion.

		/*
		 * si A cargar AAVV data sino cargar establecimiento data
		 * 
		 */

		String tipoEstablecimiento = establecimiento.getTipoEstablecimiento().getIdTipoEstablecimiento();
		if (tipoEstablecimiento == Constantes.AGENCIA_VIAJE) {
			obtenerAgenciaData(establecimiento);
		} else {
			obtenerEstablecimientoData(establecimiento, tipoRegistro);
		}

	}

	private void obtenerAgenciaData(Establecimiento establecimiento) {

		Establecimiento establecimientoFilter = new Establecimiento(establecimiento.getIdEstablecimiento());

		AgenciaData filterAgenciaData = new AgenciaData();
		filterAgenciaData.setIdEstablecimiento(establecimientoFilter.getIdEstablecimiento());
		this.agenciaDataService.findAll(filterAgenciaData, null);
	}

	private void obtenerEstablecimientoData(Establecimiento establecimiento, int tipoRegistro) {

		EstablecimientoData establecimientoData = establecimiento.getEstablecimientoData();
		if (establecimientoData == null) {
			establecimientoData = new EstablecimientoData(establecimiento.getIdEstablecimiento());
		}
		EstablecimientoData filter = new EstablecimientoData(establecimiento.getIdEstablecimiento());

		Alojamiento filterAlojamiento = new Alojamiento();
		filterAlojamiento.setEstablecimientoData(filter);
		filterAlojamiento.setTipoRegistro(tipoRegistro);
		List<Alojamiento> alojamientos = this.alojamientoService.findAll(filterAlojamiento, null);
		this.alojamientoService.findHabitacionAlojamientos(alojamientos);
		this.alojamientoService.findAseosAlojamientos(alojamientos);

		Habitacion filterHabitacion = new Habitacion();
		filterHabitacion.setEstablecimientoData(filter);
		filterHabitacion.setTipoRegistro(tipoRegistro);
		List<Habitacion> habitaciones = this.habitacionService.findAll(filterHabitacion, null);

		HabitacionVivienda filterHabitacionVivienda = new HabitacionVivienda();
		filterHabitacionVivienda.setEstablecimientoData(filter);
		List<HabitacionVivienda> habitacionViviendas = this.habitacionViviendaService.findAll(filterHabitacionVivienda,
				null);

		Aseo filterAseo = new Aseo();
		filterAseo.setEstablecimientoData(filter);
		filterAseo.setTipoRegistro(tipoRegistro);
		List<Aseo> aseos = this.aseoService.findAll(filterAseo, null);

		Parcela filterParcela = new Parcela();
		filterParcela.setEstablecimientoData(filter);
		filterParcela.setTipoRegistro(tipoRegistro);
		List<Parcela> parcelas = this.parcelaService.findAll(filterParcela, null);

		OtrasDependenciasVivienda filterOtrasDependenciasVivienda = new OtrasDependenciasVivienda();
		filterOtrasDependenciasVivienda.setEstablecimientoData(filter);
		List<OtrasDependenciasVivienda> otrasDependenciasViviendas = this.otrasDependenciasViviendaService
				.findAll(filterOtrasDependenciasVivienda, null);

		Suite filterSuite = new Suite();
		filterSuite.setEstablecimientoData(filter);
		filterSuite.setTipoRegistro(tipoRegistro);
		List<Suite> suites = this.suiteService.findAll(filterSuite, null);

		SalonComedor filterSalonComedor = new SalonComedor();
		filterSalonComedor.setEstablecimientoData(filter);
		List<SalonComedor> salonComedors = this.salonComedorService.findAll(filterSalonComedor, null);

		// zona de ocio??
		ZonaOcio filterZonaOcio = new ZonaOcio();
		filterZonaOcio.setEstablecimientoData(filter);
		List<ZonaOcio> zonasOcio = this.zonaOcioService.findAll(filterZonaOcio, null);

		establecimientoData.setListAlojamiento(alojamientos);
		establecimientoData.setListAseo(aseos);
		establecimientoData.setListHabitacion(habitaciones);
		establecimientoData.setListHabitacionVivienda(habitacionViviendas);
		establecimientoData.setListOtrasDependenciasVivienda(otrasDependenciasViviendas);
		establecimientoData.setListParcela(parcelas);
		establecimientoData.setListSalonComedor(salonComedors);
		establecimientoData.setListSuite(suites);
		establecimientoData.setListZonaOcio(zonasOcio);
		establecimiento.setEstablecimientoData(establecimientoData);

	}

	@Transactional(rollbackFor = Throwable.class)
	public void updateComplete(EstablecimientoData establecimientoData, String usuario) {
		establecimientoData.setUsuarioUltmodificacion(usuario);
		establecimientoData.setFechaUltmodificacion(new Date());
		this.establecimientoDataDao.update(establecimientoData);
		List<Alojamiento> alojamientos = establecimientoData.getListAlojamiento();
		for (Iterator<Alojamiento> iterator = alojamientos.iterator(); iterator.hasNext();) {
			Alojamiento alojamiento = iterator.next();
			alojamiento.setUsuarioUltmodificacion(usuario);
			alojamiento.setFechaUltmodificacion(new Date());
			alojamientoService.update(alojamiento);
			alojamientoService.updateHabitacionesAlojamientos(alojamiento, usuario);
			alojamientoService.updatedAseosAlojamientos(alojamiento, usuario);
		}
		List<Habitacion> habitaciones = establecimientoData.getListHabitacion();
		for (Iterator<Habitacion> iterator = habitaciones.iterator(); iterator.hasNext();) {
			Habitacion habitacion = iterator.next();
			habitacion.setUsuarioUltmodificacion(usuario);
			habitacion.setFechaUltmodificacion(new Date());
			habitacionService.update(habitacion);
		}
		List<HabitacionVivienda> habitacionesVivienda = establecimientoData.getListHabitacionVivienda();
		for (Iterator<HabitacionVivienda> iterator = habitacionesVivienda.iterator(); iterator.hasNext();) {
			HabitacionVivienda habitacionVivienda = iterator.next();
			habitacionVivienda.setUsuarioUltmodificacion(usuario);
			habitacionVivienda.setFechaUltmodificacion(new Date());
			this.habitacionViviendaService.update(habitacionVivienda);
		}
		List<Aseo> aseos = establecimientoData.getListAseo();
		for (Iterator<Aseo> iterator = aseos.iterator(); iterator.hasNext();) {
			Aseo aseo = iterator.next();
			aseo.setUsuarioUltmodificacion(usuario);
			aseo.setFechaUltmodificacion(new Date());
			this.aseoService.update(aseo);
		}
		List<OtrasDependenciasVivienda> otrasDependenciasViviendas = establecimientoData
				.getListOtrasDependenciasVivienda();
		for (Iterator<OtrasDependenciasVivienda> iterator = otrasDependenciasViviendas.iterator(); iterator
				.hasNext();) {
			OtrasDependenciasVivienda otrasDependenciasVivienda = iterator.next();
			otrasDependenciasVivienda.setUsuarioUltmodificacion(usuario);
			otrasDependenciasVivienda.setFechaUltmodificacion(new Date());
			this.otrasDependenciasViviendaService.update(otrasDependenciasVivienda);
		}
		List<SalonComedor> salonesComedor = establecimientoData.getListSalonComedor();
		for (Iterator<SalonComedor> iterator = salonesComedor.iterator(); iterator.hasNext();) {
			SalonComedor salonComedor = iterator.next();
			salonComedor.setUsuarioUltmodificacion(usuario);
			salonComedor.setFechaUltmodificacion(new Date());
			this.salonComedorService.update(salonComedor);
		}
		List<Parcela> parcelas = establecimientoData.getListParcela();
		for (Iterator<Parcela> iterator = parcelas.iterator(); iterator.hasNext();) {
			Parcela parcela = iterator.next();
			parcela.setUsuarioUltmodificacion(usuario);
			parcela.setFechaUltmodificacion(new Date());
			this.parcelaService.update(parcela);
		}
		List<Suite> suites = establecimientoData.getListSuite();
		for (Iterator<Suite> iterator = suites.iterator(); iterator.hasNext();) {
			Suite suite = iterator.next();
			suite.setUsuarioUltmodificacion(usuario);
			suite.setFechaUltmodificacion(new Date());
			this.suiteService.update(suite);
		}
	}

	@Override
	public EstablecimientoData updateTotalesHoteles(EstablecimientoData ab6321s00) {

		Long numUnidades = this.suiteService.getTotalSuitesByIdEstablecimiento(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumSuites(numUnidades);

		numUnidades = this.alojamientoService.getTotalAlojAptosByIdEst(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumApartamentos(numUnidades);

		numUnidades = this.alojamientoService.getTotalAlojEstudiosByIdEst(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumEstudios(numUnidades);

		numUnidades = this.alojamientoService.getTotalAlojConjuntosByIdEst(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumConjuntos(numUnidades);

		numUnidades = this.habitacionService.getTotalHabDblByIdEst(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumHabDoble(numUnidades);

		numUnidades = this.habitacionService.getTotalHabDblCsByIdEst(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumHabDobleCs(numUnidades);

		numUnidades = this.habitacionService.getTotalHabIndByIdEst(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumHabIndividuales(numUnidades);

		numUnidades = this.habitacionService.getTotalHabMultiplesByIdEst(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumHabMas4(numUnidades);

		numUnidades = this.salonComedorService.getTotalComedoresByIdEst(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumComedores(numUnidades);

		numUnidades = this.salonComedorService.getTotalSalonesByIdEst(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumSalones(numUnidades);

		numUnidades = this.salonComedorService.getTotalSalonesComedorByIdEst(ab6321s00.getIdEstablecimiento());
		ab6321s00.setNumSalonesComedor(numUnidades);

		this.establecimientoDataDao.updateEstDataTotalHoteles(ab6321s00);

		return ab6321s00;
	}

	@Transactional(rollbackFor = Throwable.class)
	@Override
	public Map<String, String> comprobarResumenDetalle(Integer filterId, Integer tipoUnidadAlojativa,
			List<String> filter) {

		Map<String, String> resultado = new HashMap<String, String>();

		Long totalUnidadesResumen = null;
		Long totalUnidadesDetalle = null;
		Long totalPlazasResumen = null;
		Long totalPlazasDetalle = null;

		switch (tipoUnidadAlojativa) {

		case Constantes.PARCELAS_RESUMEN_DETALLE:

			totalUnidadesResumen = this.parcelaService.getTotalUnidadesResumen(filterId);
			totalUnidadesDetalle = this.parcelaService.getTotalUnidadesDetalle(filterId);

			totalPlazasResumen = this.parcelaService.getTotalPlazasResumen(filterId);
			totalPlazasDetalle = this.parcelaService.getTotalPlazasDetalle(filterId);

			break;

		case Constantes.ALOJAMIENTOS_RESUMEN_DETALLE:

			totalUnidadesResumen = this.alojamientoService.getTotalUnidadesResumen(filterId, filter);
			totalUnidadesDetalle = this.alojamientoService.getTotalUnidadesDetalle(filterId, filter);

			totalPlazasResumen = this.alojamientoService.getTotalPlazasResumen(filterId, filter);
			totalPlazasDetalle = this.alojamientoService.getTotalPlazasDetalle(filterId, filter);

			break;

		case Constantes.HABITACIONES_ALOJAMIENTO_RESUMEN_DETALLE:

			totalUnidadesResumen = this.habitacionAlojamientoService.getTotalUnidadesResumen(filterId);
			totalUnidadesDetalle = this.habitacionAlojamientoService.getTotalUnidadesDetalle(filterId);

			totalPlazasResumen = this.habitacionAlojamientoService.getTotalPlazasResumen(filterId);
			totalPlazasDetalle = this.habitacionAlojamientoService.getTotalPlazasDetalle(filterId);

			break;

		case Constantes.HABITACIONES_RESUMEN_DETALLE:

			totalUnidadesResumen = this.habitacionService.getTotalUnidadesResumen(filterId);
			totalUnidadesDetalle = this.habitacionService.getTotalUnidadesDetalle(filterId);

			totalPlazasResumen = this.habitacionService.getTotalPlazasResumen(filterId);
			totalPlazasDetalle = this.habitacionService.getTotalPlazasDetalle(filterId);

			break;

		case Constantes.SUITES_RESUMEN_DETALLE:

			totalUnidadesResumen = this.suiteService.getTotalUnidadesResumen(filterId);
			totalUnidadesDetalle = this.suiteService.getTotalUnidadesDetalle(filterId);

			totalPlazasResumen = this.suiteService.getTotalPlazasResumen(filterId);
			totalPlazasDetalle = this.suiteService.getTotalPlazasDetalle(filterId);

			break;

		case Constantes.ASEOS_RESUMEN_DETALLE:

			totalUnidadesResumen = this.aseoService.getTotalUnidadesResumen(filterId);
			totalUnidadesDetalle = this.aseoService.getTotalUnidadesDetalle(filterId);

			break;

		}

		if (null != totalUnidadesResumen && null != totalUnidadesDetalle) {

			if (totalUnidadesResumen.compareTo(totalUnidadesDetalle) == 0) {

				resultado.put("unidades", "ok");

			} else {

				resultado.put("unidades", "error");
			}

		}

		if (null != totalPlazasResumen && null != totalPlazasDetalle) {

			if (totalPlazasResumen.compareTo(totalPlazasDetalle) == 0) {

				resultado.put("plazas", "ok");

			} else {

				resultado.put("plazas", "error");

			}
		}

		return resultado;
	}
}
