package com.ejie.y42b.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

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

import com.ejie.x38.dto.Pagination;
import com.ejie.y42b.constantes.Y42bAgendaConstantes;
import com.ejie.y42b.dao.Y42bGruposDao;
import com.ejie.y42b.model.Entidad;
import com.ejie.y42b.model.Y42bGrupo;
import com.ejie.y42b.utils.Y42bUIDGenerator32;
import com.ejie.y42b.utils.Y42bUtils;

/**
 * GruposServiceImpl  
 * 
 *  
 */
@Service(value = "gruposService")
public class Y42bGruposServiceImpl implements Y42bGruposService {
    /**
     * Final static logger.
     */
    private static final Logger logger = LoggerFactory
	    .getLogger(Y42bGruposServiceImpl.class);

    @Autowired()
    private Y42bGruposDao gruposDao;

    /**
     * Inserts a single row in the Grupos table.
     * 
     * @param pGrupo
     *            Grupos
     * @return Grupos
     */
    @Transactional(rollbackFor = Throwable.class)
    public Y42bGrupo add(Y42bGrupo pGrupo) {

    Y42bGrupo grupo = pGrupo;
	Date fecultmod = new Date();
	grupo.setFecultmod(fecultmod);
	grupo.setGrupoId(Y42bAgendaConstantes.PREFIJO_GRUPO
		+ Y42bUIDGenerator32.getInstance().generateId());
	grupo.setNombreEs(Y42bUtils.filtroDB(grupo.getNombreEs()));
	grupo.setNombreEu(Y42bUtils.filtroDB(grupo.getNombreEu()));
	return this.gruposDao.add(grupo);
    }

    /**
     * Updates a single row in the Grupos table.
     * 
     * @param pGrupo
     *            Grupos
     * @return Grupos
     */
    @Transactional(rollbackFor = Throwable.class)
    public Y42bGrupo update(Y42bGrupo pGrupo) {
	
	Y42bGrupo grupo = pGrupo;
	Date fecultmod = new Date();
	grupo.setFecultmod(fecultmod);
	grupo.setNombreEs(Y42bUtils.filtroDB(grupo.getNombreEs()));
	grupo.setNombreEu(Y42bUtils.filtroDB(grupo.getNombreEu()));
	return this.gruposDao.update(grupo);

    }

    /**
     * Finds a single row in the Grupos table.
     * 
     * @param grupo
     *            Grupos
     * @return Grupos
     */
    public Y42bGrupo find(Y42bGrupo grupo) {
	return (Y42bGrupo) this.gruposDao.find(grupo);
    }

    /**
     * Finds a List of rows in the Grupos table.
     * 
     * @param grupos
     *            Grupos
     * @param pagination
     *            Pagination
     * @return List
     */
    public List<Y42bGrupo> findAll(Y42bGrupo grupos, Pagination pagination) {
	return (List<Y42bGrupo>) this.gruposDao.findAll(grupos, pagination);

    }

    /**
     * Counts rows in the Grupos table.
     * 
     * @param grupos
     *            Grupos
     * @return Long
     */
    public Long findAllCount(Y42bGrupo grupos) {
	return this.gruposDao.findAllCount(grupos);
    }

    /**
     * Finds rows in the Grupos table using like.
     * 
     * @param grupos
     *            Grupos
     * @param pagination
     *            Pagination
     * @param startsWith boolean           
     * @return List
     */
    public List<Y42bGrupo> findAllLike(Y42bGrupo grupos, Pagination pagination,
	    Boolean startsWith) {
	return (List<Y42bGrupo>) this.gruposDao.findAllLike(grupos, pagination,
		startsWith);
    }

    /**
     * Deletes a single row in the Grupos table. an children respuestas y
     * documentos
     * 
     * @param grupo
     *            Grupos
     */
    @Transactional(rollbackFor = Throwable.class)
    public void remove(Y42bGrupo grupo) {
	// Borra padre (logico) si no tiene hijos(entidades)
	this.gruposDao.remove(grupo);
    }

    @Override()
    public void removeMultiple(ArrayList<Y42bGrupo> gruposList) {
	for (Y42bGrupo grupoAux : gruposList) {
	    this.gruposDao.remove(grupoAux);
	}
    }

    /**
     * Finds Numero de entidades activas
     * 
     * @param grupos
     *            Grupos
     * @return Long
     */
    public int findEntidadesActivas(Y42bGrupo grupos) {
	  int total = this.gruposDao.findEntidadesActivas(grupos);
	  
	  //buscar los grupos
	  List<Y42bGrupo> listGrupos =  this.gruposDao.findAllChildren(grupos,null);
	  
	  if (listGrupos.size() > 0) {
			for (Y42bGrupo grupo : listGrupos) {
				grupo.setActiva(Y42bAgendaConstantes.SI);
				total += findEntidadesActivas(grupo);
			}
	  }
	  return total;	  
    }

    /**
     * Finds Numero de hijos
     * 
     * @param grupos
     *            Grupos
     * @return Long
     */
    public int findHijos(Y42bGrupo grupos) {
      //Buscar entidades hijas
	  int total = this.gruposDao.findEntidades(grupos);

	  Y42bGrupo grupoFiltro = new Y42bGrupo();
	  grupoFiltro.setGrupoPadreId(grupos.getGrupoId());
	  grupoFiltro.setActiva(Y42bAgendaConstantes.SI);
	  
      //Buscar grupos activos
	  total += this.gruposDao.findGruposActivos(grupoFiltro);
	  
	  return total;	  
    }
    
    /**
     * Finds Numero de hijos
     * 
     * @param grupos
     *            Grupos
     * @return Long
     */
    public int findEntidadesHijasTotales(Y42bGrupo grupos) {
      //Buscar entidades hijas
	  int total = this.gruposDao.findEntidadesTotales(grupos);

	 
	  return total;	  
    }
    
    /**
     * Finds Numero de hijos- cuenta el nº de grupos activos (inactivos son los eliminados) que tengan a ese grupo como padre
     * 
     * @param grupo
     *            Grupos
     * @return Long
     */
    public int countGruposHijo(Y42bGrupo grupo) {
		Y42bGrupo grupoFiltro = new Y42bGrupo();
		grupoFiltro.setGrupoPadreId(grupo.getGrupoId());
		grupoFiltro.setActiva(Y42bAgendaConstantes.SI);
		  
		//Buscar grupos activos
		long total = this.gruposDao.findGruposActivos(grupoFiltro);
		  
		return (int) total;	  
    }
        
    
    
    /**
     * Finds primer grupo activo para seleccionar por defecto
     * 
     * @return Y42bGrupo
     */
    public Y42bGrupo findPrimerGrupoActivo() {
	return this.gruposDao.findPrimerGrupoActivo();
    }

    @Override()
    public List<Y42bGrupo> findGruposPadreAll(Y42bGrupo grupo) {
	return (List<Y42bGrupo>) this.gruposDao.findGruposPadreAll(grupo);
    }

    /**
     * Inserts a single row in the GrupoEntidad table.
     * 
     * @param grupo
     *            Grupo
     * @return Grupo
     */
    @Transactional(rollbackFor = Throwable.class)
    public Y42bGrupo addGrupoEntidad(Y42bGrupo grupo) {
	return this.gruposDao.addGrupoEntidad(grupo);
    }

    /**
     * Deletes a single row in the GrupoEntidad table.
     * 
     * @param grupo
     *            Grupo
     */
    @Transactional(rollbackFor = Throwable.class)
    public void removeGrupoEntidad(Y42bGrupo grupo) {
	this.gruposDao.removeGrupoEntidad(grupo);
    }

    /**
     * Find a single row in the findGrupoEntidad Many To Many relationship.
     * 
     * @param grupo
     *            Grupo
     * @param entidad
     *            Entidad
     * @param pagination
     *            Pagination
     * @return Grupo
     */
    public Y42bGrupo findGrupoEntidad(Y42bGrupo grupo, Entidad entidad,
	    Pagination pagination) {
	return this.gruposDao.findGrupoEntidad(grupo, entidad, pagination);
    }

    /**
     * Counts rows in the GrupoEntidad table.
     * 
     * @param grupo
     *            Grupo
     * @param entidad
     *            Entidad
     * @return List
     */
    public Long findGrupoEntidadCount(Y42bGrupo grupo, Entidad entidad) {
	return this.gruposDao.findGrupoEntidadCount(grupo, entidad);
    }

    /**
     * Getter method for Y42bGrupoDao
     * 
     * @return Y42bGrupoDao
     */
    public Y42bGruposDao getGrupoDao() {
	return this.gruposDao;
    }

    /**
     * Setter method for Y42bGrupoDao.
     * 
     * @param grupoDao
     *            Y42bGrupoDao
     * @return
     */
    public void setGrupoDao(Y42bGruposDao grupoDao) {
	Y42bGruposServiceImpl.logger.info("Setting Dependency " + grupoDao);
	this.gruposDao = grupoDao;
    }

    /**
     * @param grupo Grupo
     * @return Y42bGrupo
     */
    @Override()
    public Y42bGrupo findJerarquia(Y42bGrupo grupo) {
	return this.gruposDao.findJerarquia(grupo);
    }

    
	/**
	 * Buscar grupo por su id
	 * @param grupo
	 *        Y42Grupo
	 * 
	 * 
	 * @return y42bGrupo
	 */
    public Y42bGrupo findGrupo(Y42bGrupo grupo){
    	return this.gruposDao.findGrupo(grupo);
    }
    

    /**
	 * Counts rows in the GrupoEntidad table with that entityId.
	 *
	 * @param entidadId String
	 * @return Long
	 */
    public Long countByEntidadId(String entidadId){
    	return this.gruposDao.countByEntidadId(entidadId);
    }
    
    
}
