package com.ejie.m62fb.service.registroVPP;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;

import java.util.List;

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

import com.ejie.m62fb.dao.registroVPP.AlojamientoDotacionalDao;
import com.ejie.m62fb.dao.registroVPP.ElementoAdDao;
import com.ejie.m62fb.model.AlojamientoDotacional;
import com.ejie.m62fb.model.ElementoAd;
import com.ejie.m62fb.model.tipos.TipoElemento;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;

/**
 * AlojamientoDotacionalServiceImpl.
 * 
XXXX
 */
@Service(value = "alojamientoDotacionalService")
public class AlojamientoDotacionalServiceImpl implements
		AlojamientoDotacionalService {

	@Autowired
	private AlojamientoDotacionalDao alojamientoDotacionalDao;

	@Autowired
	private ElementoAdDao elementoAdDao;

	/**
	 * Inserts a single row in the AlojamientoDotacional table.
	 * 
	 * @param alojamientoDotacional
	 *            AlojamientoDotacional
	 * @return AlojamientoDotacional
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
@PreAuthorize("hasPermission('ALOJAMIENTO_DOTACIONAL_SERVICE','SecureService','create')")
	public AlojamientoDotacional add(AlojamientoDotacional alojamientoDotacional) {
		// Insertamos el alojamiento
		return this.alojamientoDotacionalDao.add(alojamientoDotacional);
	}

	/**
	 * Updates a single row in the AlojamientoDotacional table.
	 * 
	 * @param alojamientoDotacional
	 *            AlojamientoDotacional
	 * @return AlojamientoDotacional
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
@PreAuthorize("hasPermission('ALOJAMIENTO_DOTACIONAL_SERVICE','SecureService','write')")
	public AlojamientoDotacional update(AlojamientoDotacional alojDot) {

		// Comprobamos si se han realizado cambios
		this.alojamientoDotacionalDao.checkForUpdate(alojDot);

		// Recuperamos la Liquidacion de BBDD (Completa)
		AlojamientoDotacional alojDotBD = this.find(alojDot);

		// Realizamos el Update
		alojDot = this.alojamientoDotacionalDao.update(alojDot);

		// Comprobamos si hay que vincular un Garaje
		this.vincularDesvincularElementoAd(alojDot.getGaraje(),
				alojDotBD.getGaraje(), alojDot, TipoElemento.GARAJE);

		// Comprobamos si hay que vincular un Trastero
		this.vincularDesvincularElementoAd(alojDot.getTrastero(),
				alojDotBD.getTrastero(), alojDot, TipoElemento.TRASTERO);

		return alojDot;
	}

	/**
	 * Finds a single row in the AlojamientoDotacional table.
	 * 
	 * @param alojamientoDotacional
	 *            AlojamientoDotacional
	 * @return AlojamientoDotacional
	 */
	@Override
@PreAuthorize("hasPermission('ALOJAMIENTO_DOTACIONAL_SERVICE','SecureService','read')")
	public AlojamientoDotacional find(
			AlojamientoDotacional alojamientoDotacional) {

		AlojamientoDotacional alojDotBD = this.alojamientoDotacionalDao
				.find(alojamientoDotacional);

		if (alojDotBD != null) {
			// Recuperamos los datos del Garaje
			alojDotBD.setGaraje(this.elementoAdDao
					.findByIdAlojRegAndTipoElemento(alojDotBD.getIdAlojReg(),
							TipoElemento.GARAJE));
			// Recuperamos los datos del Trastero
			alojDotBD.setTrastero(this.elementoAdDao
					.findByIdAlojRegAndTipoElemento(alojDotBD.getIdAlojReg(),
							TipoElemento.TRASTERO));
		}

		return alojDotBD;
	}

	/**
	 * Deletes a single row in the AlojamientoDotacional table.
	 * 
	 * @param alojamientoDotacional
	 *            AlojamientoDotacional
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
@PreAuthorize("hasPermission('ALOJAMIENTO_DOTACIONAL_SERVICE','SecureService','delete')")
	public void remove(AlojamientoDotacional alojamientoDotacional) {
		this.alojamientoDotacionalDao.remove(alojamientoDotacional);
	}

	/**
	 * Finds a list of rows in the AlojamientoDotacional table.
	 * 
	 * @param alojamientoDotacional
	 *            AlojamientoDotacional
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return List<AlojamientoDotacional>
	 */
	@Override
@PreAuthorize("hasPermission('ALOJAMIENTO_DOTACIONAL_SERVICE','SecureService','read')")
	public List<AlojamientoDotacional> findAll(
			AlojamientoDotacional alojamientoDotacional,
			JQGridRequestDto jqGridRequestDto) {
		return this.alojamientoDotacionalDao.findAll(alojamientoDotacional,
				jqGridRequestDto);
	}

	/**
	 * Finds rows in the AlojamientoDotacional table using like.
	 * 
	 * @param alojamientoDotacional
	 *            AlojamientoDotacional
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<AlojamientoDotacional>
	 */
	@Override
@PreAuthorize("hasPermission('ALOJAMIENTO_DOTACIONAL_SERVICE','SecureService','read')")
	public List<AlojamientoDotacional> findAllLike(
			AlojamientoDotacional alojamientoDotacional,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		return this.alojamientoDotacionalDao.findAllLike(alojamientoDotacional,
				jqGridRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Filter method in the AlojamientoDotacional table.
	 * 
	 * @param filterAlojamientoDotacional
	 *            AlojamientoDotacional
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return JQGridResponseDto<AlojamientoDotacional>
	 */
	@Override
@PreAuthorize("hasPermission('ALOJAMIENTO_DOTACIONAL_SERVICE','SecureService','read')")
	public JQGridResponseDto<AlojamientoDotacional> filter(
			AlojamientoDotacional filterAlojamientoDotacional,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		List<AlojamientoDotacional> listaAlojamientoDotacional = this.alojamientoDotacionalDao
				.findAllLike(filterAlojamientoDotacional, jqGridRequestDto,
						false);
		Long recordNum = this.alojamientoDotacionalDao
				.findAllLikeCount(
						filterAlojamientoDotacional != null ? filterAlojamientoDotacional
								: new AlojamientoDotacional(), false);
		return new JQGridResponseDto<AlojamientoDotacional>(jqGridRequestDto,
				recordNum, listaAlojamientoDotacional);
	}

	/**
	 * Comprueba si tiene que vincular o desvincular el ElementoAd pasado al
	 * alojDot
	 * 
	 * @param elementoAd
	 *            ElementoAd, que hemos informado en pantalla
	 * @param elementoAdBD
	 *            ElementoAd, que esta ahora en BD
	 * @param alojDot
	 *            AlojamientoDotacional al que queremos vincular
	 * @param tipoElemento
	 *            String, G o T dependiendo del TipoElemento
	 */
	private void vincularDesvincularElementoAd(ElementoAd elementoAd,
			ElementoAd elementoAdBD, AlojamientoDotacional alojDot,
			String tipoElemento) {
		// Comprobamos si hay que vincular ElementoAd
		if (elementoAd != null && elementoAd.getIdElemReg() != null) {
			// Comprobamos si en BD tiene ElementoAd
			if (elementoAdBD != null && elementoAdBD.getIdElemReg() != null) {
				// Si en BD tiene ElementoAd y es diferente, desvincular
				if (!elementoAd.getIdElemReg().equals(
						elementoAdBD.getIdElemReg())) {
					// Desvincular
					this.elementoAdDao.desvincular(alojDot.getIdAlojReg(),
							tipoElemento);
					// Vincular
					this.elementoAdDao.vincular(elementoAd, alojDot);
				}
			} else {
				// Vincular
				this.elementoAdDao.vincular(elementoAd, alojDot);
			}
		} else {
			// Comprobamos si en BD tiene ElementoAd
			if (elementoAdBD != null && elementoAdBD.getIdElemReg() != null) {
				// Desvincular
				this.elementoAdDao.desvincular(alojDot.getIdAlojReg(),
						tipoElemento);
			}
		}
	}
}
