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 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.math.BigDecimal;
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.utils.error.UFException;
import com.ejie.m62fb.dao.registroVPP.ElementosDao;
import com.ejie.m62fb.dao.registroVPP.InformacionSueloDao;
import com.ejie.m62fb.model.Elemento;
import com.ejie.m62fb.model.ElementoActMasiva;
import com.ejie.m62fb.model.direccion.Direccion;
import com.ejie.m62fb.model.tipos.TipoSiNo;
import com.ejie.m62fb.util.Errores;
import com.ejie.m62fb.utils.sql.BDUtils;
import com.ejie.t17i.model.Portal;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * ElementoServiceImpl generated by UDA, 04-sep-2015 12:03:48.
XXXX
 */

@Service(value = "elementoService")
public class ElementosServiceImpl implements ElementosService {

	@Autowired
	private ElementosDao elementosDao;
	@Autowired
	private InformacionSueloDao informacionSueloDao;
	
	/**
	 * <p>Comprobar si el anejo tiene contratos</p>
	 * @param elemento
	 * @return
	 */
	public boolean existenContratos(final Elemento elemento) {
		if (elementosDao.existenContratos(elemento)){
			return true;			
		}
		return false;
	}
	
	/**
     * <p>Vincular un elemento a una vivienda</p>
     *
     * @param ideElemento BigDecimal
     * @param numVivienda BigDecimal
     * @return boolean
     */
	public boolean vincularElemento(BigDecimal ideElemento,BigDecimal numVivienda) {
		if (elementosDao.vincularElemento(ideElemento,numVivienda)){
			return true;			
		}
		return false;
	}
	/**
     * <p>Desvincular un elemento a una vivienda</p>
     *
     * @param ideElemento BigDecimal
     * @return boolean
     */
	public boolean desvincularElemento(BigDecimal  ideElemento,BigDecimal  numVivienda) {
		if (elementosDao.desvincularElemento(ideElemento,numVivienda)){
			return true;			
		}
		return false;
	}
	
	/**
	 * <p>Comprobar que el anejo no esté dado de alta ya en el sistema</p>
	 * @param elemento
	 * @return
	 */
	private boolean hayElementoMismoEmplazamiento(final Elemento elemento){
		/**SELECT COUNT(1) FROM elemento WHERE COD_TIPO_ELEM = ? AND COD_ELEMENTO = ? AND COD_PROVINCIA = ? 
		 * AND COD_MUNICIPIO = ? AND COD_CALLE = ? AND COD_PORTAL = ? AND DEC_SIT_ELEM = ?
		 */
		Elemento elementoAux = new Elemento();
		elementoAux.setIdeElemento(elemento.getIdeElemento());
		elementoAux.setTipoElemento(elemento.getTipoElemento());
		elementoAux.setCodElemento(elemento.getCodElemento());
		elementoAux.setDireccion(elemento.getDireccion());
		
		if (elementosDao.hayElementoMismoEmplazamiento(elemento)){
			return true;			
		}
		return false;
		
	}
	/**
	 * Inserts a single row in the Elemento table.
	 *
	 * @param elemento Elemento
	 * @return Elemento
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Elemento add(Elemento elemento) {
		//Validar que no haya otro ELEMENTO con el mismo emplazamiento
		if(hayElementoMismoEmplazamiento(elemento)){
			throw new UFException(Errores.ERROR_ANEJO_EXISTE);
		}
		return this.elementosDao.add(elemento);
	}
	/**
	 * Updates a single row in the Elemento table.
	 *
	 * @param elemento Elemento
	 * @return Elemento
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Elemento updateDireccion(ElementoActMasiva elemento) {
		Elemento elementoBD = null;
		Direccion direccionBD;
		Portal portalBD = null;
		String[] rowIds=elemento.getRowIds().split(",");
		for(String row : rowIds){
			elementoBD = new Elemento(new BigDecimal(row));
			elementoBD = elementosDao.find(elementoBD);
			direccionBD= elementoBD.getDireccion();
			direccionBD.setProvincia(elemento.getDireccion().getProvincia());
			direccionBD.setMunicipio(elemento.getDireccion().getMunicipio());
			direccionBD.setLocalidad(elemento.getDireccion().getLocalidad());
			direccionBD.setCalle(elemento.getDireccion().getCalle());
			
			if(elemento.getDireccion().getPortal()!=null && elemento.getDireccion().getPortal().getCodigoPostal()!=null){
				portalBD = direccionBD.getPortal();
				portalBD.setCodigoPostal(elemento.getDireccion().getPortal().getCodigoPostal());
			}
			direccionBD.setPortal(portalBD);
			elementoBD.setDireccion(direccionBD);
			this.elementosDao.update(elementoBD);
		}

		return elementoBD;
	}
	
	/**
	 * Updates a single row in the Elemento table.
	 *
	 * @param elemento Elemento
	 * @return Elemento
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Elemento updatePortal(ElementoActMasiva elemento) {
		Elemento elementoBD = null;
		Direccion direccionBD;
		Portal portalBD = null;
		String[] rowIds=elemento.getRowIds().split(",");
		for(String row : rowIds){
			elementoBD = new Elemento(new BigDecimal(row));
			elementoBD = elementosDao.find(elementoBD);
			direccionBD = elementoBD.getDireccion();
			
			if(elemento.getDireccion().getPortal()!=null && elemento.getDireccion().getPortal().getNumero()!=null){
				portalBD = direccionBD.getPortal();
				portalBD.setNumero(elemento.getDireccion().getPortal().getNumero());
			}
			direccionBD.setPortal(portalBD);
			elementoBD.setDireccion(direccionBD);
			this.elementosDao.update(elementoBD);
		}

		return elementoBD;
	}
	/**
	 * Updates a single row in the Elemento table.
	 *
	 * @param elemento Elemento
	 * @return Elemento
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Elemento update(Elemento elemento) {
		Elemento elementoBD=elementosDao.findForUpdate(elemento);
		setFieldsEditables(elemento,elementoBD);
		elementoBD.setDireccion(elemento.getDireccion());
		//Validar que no haya otro ELEMENTO con el mismo emplazamiento
		if(hayElementoMismoEmplazamiento(elementoBD)){
			throw new UFException(Errores.ERROR_ANEJO_EXISTE);
		}
		
		//Información suelo
		if(elementoBD.getInformacionSuelo()!=null && elemento.getInformacionSuelo()!=null){
			if (((elementoBD.getInformacionSuelo().getCuotaParticipacion()!=null && 
					elemento.getInformacionSuelo().getCuotaParticipacion()==null)||
					(elementoBD.getInformacionSuelo().getCuotaParticipacion()==null && 
							elemento.getInformacionSuelo().getCuotaParticipacion()!=null))||
					((elementoBD.getInformacionSuelo().getCuotaParticipacion()!=null && 
							elemento.getInformacionSuelo().getCuotaParticipacion()!=null)&&
					elementoBD.getInformacionSuelo().getCuotaParticipacion().doubleValue()!=
						elemento.getInformacionSuelo().getCuotaParticipacion().doubleValue())){
				//
				elementoBD.getInformacionSuelo().setCuotaParticipacion(elemento.getInformacionSuelo().getCuotaParticipacion());
				informacionSueloDao.update(elementoBD.getInformacionSuelo());
			}
		}
		
		return this.elementosDao.update(elementoBD);
	 }
	private void setFieldsEditables(Elemento elemento,Elemento elementoBD){

//		COD_TIPO_ELEM
		elementoBD.setTipoElemento(elemento.getTipoElemento());
//		COD_ELEMENTO
		elementoBD.setCodElemento(elemento.getCodElemento());
//		NUM_FIJO_IBI_ELEM
		elementoBD.setNumFijoIbiElem(elemento.getNumFijoIbiElem());
//		SUP_UTIL_ELEM
		elementoBD.setSuperficieUtil(elemento.getSuperficieUtil());
//		IND_USO_INDIV
		if(elemento.getIndUsoIndiv()==null || !elemento.getIndUsoIndiv().getCodTabla().equalsIgnoreCase(BDUtils.TRUE)){
			elementoBD.setIndUsoIndiv(new TipoSiNo(BDUtils.FALSE));
		}else{
			elementoBD.setIndUsoIndiv(new TipoSiNo(BDUtils.TRUE));
		}		
//		COD_VINCUL_ELEM
		elementoBD.setTipoVinculacion(elemento.getTipoVinculacion());
//		NUM_EXPEDIENTE
		elementoBD.setNumExpediente(elemento.getNumExpediente());
		//REGISTRo pROPIedad
		elementoBD.setRegistroPropiedad(elemento.getRegistroPropiedad());
//		FEC_ESCRITURA_SUEL
		elementoBD.setFechaEscriturasSuelo(elemento.getFechaEscriturasSuelo());
		
	}
	/**
	 * Finds a single row in the Elemento table.
	 *
	 * @param elemento Elemento
	 * @return Elemento
	 */
	public Elemento find(Elemento elemento) {
		return (Elemento) this.elementosDao.find(elemento);
	}
	
	/**
	 * Deletes a single row in the Elemento table.
	 *
	 * @param elemento Elemento
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void remove(Elemento elemento) {
		this.elementosDao.remove(elemento);
	}

	/**
	 * Finds a list of rows in the Elemento table.
	 *
	 * @param elemento Elemento
	 * @param jqGridRequestDto JQGridRequestDto
	 * @return List<Elemento>
	 */
	public List<Elemento> findAll(Elemento elemento, JQGridRequestDto jqGridRequestDto){
		return (List<Elemento>) this.elementosDao.findAll(elemento, jqGridRequestDto);
	}
    
	/**
	 * Finds rows in the Elemento table using like.
	 *
	 * @param elemento Elemento
	 * @param jqGridRequestDto JQGridRequestDto
     * @param startsWith Boolean	 
	 * @return List<Elemento>
	 */
	public List<Elemento> findAllLike(Elemento elemento, JQGridRequestDto jqGridRequestDto, Boolean startsWith){
		return (List<Elemento>) this.elementosDao.findAllLike(elemento, jqGridRequestDto, startsWith);
	}

        
	/**
	 * Filter method in the Elemento table.
	 *
	 * @param filterElemento Elemento
	 * @param jqGridRequestDto JQGridRequestDto
	 * @param startsWith Boolean
	 * @return JQGridResponseDto<Elemento>
	 */	
	public JQGridResponseDto< Elemento> filter(Elemento filterElemento, JQGridRequestDto jqGridRequestDto,  Boolean startsWith){
		List<Elemento> listaElemento =  this.elementosDao.findAllLike(filterElemento, jqGridRequestDto, false);
		Long recordNum =  this.elementosDao.findAllLikeCount(filterElemento != null ? filterElemento: new Elemento (),false);
		if (jqGridRequestDto.getMultiselection().getSelectedIds()!=null){
			List< TableRowDto< Elemento>> reorderSelection = this.elementosDao.reorderSelection(filterElemento, jqGridRequestDto, startsWith);
			return new JQGridResponseDto<Elemento>(jqGridRequestDto, recordNum, listaElemento, reorderSelection);
		}
		return new JQGridResponseDto<Elemento>(jqGridRequestDto, recordNum, listaElemento);   
	}
    
    
    /**
	 * Reorder the selection made in Elemento table.
	 *
	 * @param filterElemento Elemento
	 * @param jqGridRequestDto JQGridRequestDto
	 * @param startsWith Boolean
	 * @return Object
	 */	
    public Object reorderSelection(Elemento filterElemento, JQGridRequestDto jqGridRequestDto, Boolean startsWith){
		return this.elementosDao.reorderSelection(filterElemento, jqGridRequestDto, startsWith);
	}
    
    /*
	 * OPERACIONES RUP_TABLE JERARQUIA
	 */
	 
	/**
	 * Finder method in the hierarchical the Elemento table.
	 *
	 * @param filterElemento Elemento
	 * @param jqGridRequestDto JQGridRequestDto
	 * @param startsWith Boolean
	 * @return JQGridResponseDto<JerarquiaDto<Elemento>>
	 */	
//	public JQGridResponseDto<JerarquiaDto<Elemento>> jerarquia(Elemento filterElemento, JQGridRequestDto jqGridRequestDto, Boolean startsWith){
//		List<JerarquiaDto<Elemento>> listaElemento =  this.elementosDao.findAllLikeJerarquia(filterElemento, jqGridRequestDto);
//		Long recordNum = this.elementosDao.findAllLikeCountJerarquia(filterElemento, jqGridRequestDto);
//		return new JQGridResponseDto<JerarquiaDto<Elemento>>(jqGridRequestDto, recordNum, listaElemento);
//	}
	
	/**
	 * Finder method for siblings rows in the hierarchical the Elemento table.
	 *
	 * @param filterElemento Elemento
	 * @param jqGridRequestDto JQGridRequestDto
	 * @return JQGridResponseDto<JerarquiaDto<Elemento>>
	 */	
//	public JQGridResponseDto<JerarquiaDto<Elemento>> jerarquiaChildren(Elemento filterElemento, JQGridRequestDto jqGridRequestDto){
//		JQGridResponseDto<JerarquiaDto<Elemento>> jqGridResponseDto = new JQGridResponseDto<JerarquiaDto<Elemento>>();
//		jqGridResponseDto.addAdditionalParam(JQGridResponseDto.CHILDREN, this.elementosDao.findAllChild(filterElemento, jqGridRequestDto));
//		return jqGridResponseDto;
//	}
	
	
}

