package com.ejie.ab39a.service;

import com.ejie.ab39a.dao.TecnicosEntidadDao;
import com.ejie.ab39a.exceptions.ErrorField;
import com.ejie.ab39a.exceptions.ErrorGenericoException;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.ejie.x38.dto.TableRowDto;

import java.util.ArrayList;
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.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.ab39a.model.Entidades;
import com.ejie.ab39a.model.TecnicosEntidad;

/**
 * TecnicosEntidad.
 * 
 *  
 */
@Service(value = "tecnicosEntidadService")
public class TecnicosEntidadServiceImpl implements TecnicosEntidadService {

    private static final Logger logger = LoggerFactory.getLogger(TecnicosEntidadServiceImpl.class);

    @Autowired
    private TecnicosEntidadDao tecnicosEntidadDao;

    /**
     * Inserts a single row in the TecnicosEntidad table.
     *
     * @param tecnicosEntidad
     *            TecnicosEntidad
     * @return TecnicosEntidad
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class)
    public TecnicosEntidad add(TecnicosEntidad tecnicosEntidad) {

        // Validamos que el dni/nif no exista ya en BBDD
        TecnicosEntidad tecnicosEntidadFilter = new TecnicosEntidad();
        tecnicosEntidadFilter.setDocidentificacion(tecnicosEntidad.getDocidentificacion());
        List<TecnicosEntidad> lista = this.tecnicosEntidadDao.findAll(tecnicosEntidadFilter, null);
        if (lista != null && !lista.isEmpty()) {
            List<ErrorField> errores = new ArrayList<ErrorField>();
            errores.add(new ErrorField("validacion.existeDNI"));
            throw new ErrorGenericoException(errores);
        }

        return this.tecnicosEntidadDao.add(tecnicosEntidad);
    }

    /**
     * Inserts a single row in the TecnicosEntidad table.
     *
     * @param tecnicosEntidad
     *            TecnicosEntidad
     * @return TecnicosEntidad
     */

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class)
    public TecnicosEntidad addTecnicoRelacion(TecnicosEntidad tecnicosEntidad) {

        // Validamos que el dni/nif no exista ya en BBDD
        TecnicosEntidad tecnicosEntidadFilter = new TecnicosEntidad();
        tecnicosEntidadFilter.setDocidentificacion(tecnicosEntidad.getDocidentificacion());
        List<TecnicosEntidad> lista = this.tecnicosEntidadDao.findAll(tecnicosEntidadFilter, null);
        if (lista != null && !lista.isEmpty()) {
            List<ErrorField> errores = new ArrayList<ErrorField>();
            errores.add(new ErrorField("validacion.existeDNI"));
            throw new ErrorGenericoException(errores);
        }

        TecnicosEntidad tecnicoAux = this.tecnicosEntidadDao.add(tecnicosEntidad);

        for (Entidades entidad : tecnicosEntidad.getEntidadeses()) {
            entidad.setTecnicosEntidad(tecnicosEntidad);
            this.tecnicosEntidadDao.guardarEntidadesTecnico(entidad);
        }

        return tecnicoAux;
    }

    /**
     * Updates a single row in the TecnicosEntidad table.
     *
     * @param tecnicosEntidad
     *            TecnicosEntidad
     * @return TecnicosEntidad
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class)
    public TecnicosEntidad update(TecnicosEntidad tecnicosEntidad) {

        // Validamos que el dni/nif no exista ya en BBDD
        TecnicosEntidad aux = new TecnicosEntidad();
        aux.setDocidentificacion(tecnicosEntidad.getDocidentificacion());
        List<TecnicosEntidad> lista = this.tecnicosEntidadDao.findAll(aux, null);
        List<ErrorField> errores = new ArrayList<ErrorField>();
        if (lista != null && lista.size() > 1) {
            TecnicosEntidadServiceImpl.logger
                    .debug("TecnicosEntidadServiceImpl - edit - Existe 0 mas de 1 tecnico con ese nif");
            errores.add(new ErrorField("error.aplicacion"));
            throw new ErrorGenericoException(errores);
        } else if (lista != null && lista.size() == 1) {
            aux = lista.get(0);
            if (aux != null && aux.getCodtecnico() != null && tecnicosEntidad != null
                    && tecnicosEntidad.getCodtecnico() != null
                    && aux.getCodtecnico().intValue() != tecnicosEntidad.getCodtecnico().intValue()) {
                errores.add(new ErrorField("validacion.existeDNI"));
                throw new ErrorGenericoException(errores);
            }
        }

        return this.tecnicosEntidadDao.update(tecnicosEntidad);
    }

    /**
     * Guardar entidades del tecnico
     *
     * @param tecnicosEntidad
     *            TecnicosEntidad
     * @return TecnicosEntidad
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class)
    public TecnicosEntidad guardarEntidadesTecnico(TecnicosEntidad tecnicosEntidad) {
        for (Entidades entidad : tecnicosEntidad.getEntidadeses()) {
            entidad.setTecnicosEntidad(tecnicosEntidad);
            this.tecnicosEntidadDao.guardarEntidadesTecnico(entidad);
        }

        return tecnicosEntidad;
    }

    /**
     * Finds a single row in the TecnicosEntidad table.
     *
     * @param tecnicosEntidad
     *            TecnicosEntidad
     * @return TecnicosEntidad
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, isolation = Isolation.READ_COMMITTED)
    public TecnicosEntidad find(TecnicosEntidad tecnicosEntidad) {
        return this.tecnicosEntidadDao.find(tecnicosEntidad);
    }

    /**
     * Deletes a single row in the TecnicosEntidad table.
     *
     * @param tecnicosEntidad
     *            TecnicosEntidad
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class)
    public void remove(TecnicosEntidad tecnicosEntidad) {
        this.tecnicosEntidadDao.remove(tecnicosEntidad);
    }

    /**
     * 
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class)
    public void borrarEntidadTecnico(Integer codtecnico, Integer codentidad) {
        this.tecnicosEntidadDao.borrarEntidadTecnico(codtecnico, codentidad);
    }

    /**
     * Finds a list of rows in the TecnicosEntidad table.
     *
     * @param tecnicosEntidad
     *            TecnicosEntidad
     * @param jqGridRequestDto
     *            JQGridRequestDto
     * @return List<TecnicosEntidad>
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, isolation = Isolation.READ_COMMITTED)
    public List<TecnicosEntidad> findAll(TecnicosEntidad tecnicosEntidad, JQGridRequestDto jqGridRequestDto) {
        return this.tecnicosEntidadDao.findAll(tecnicosEntidad, jqGridRequestDto);
    }

    /**
     * Finds rows in the TecnicosEntidad table using like.
     *
     * @param tecnicosEntidad
     *            TecnicosEntidad
     * @param jqGridRequestDto
     *            JQGridRequestDto
     * @param startsWith
     *            Boolean
     * @return List<TecnicosEntidad>
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, isolation = Isolation.READ_COMMITTED)
    public List<TecnicosEntidad> findAllLike(TecnicosEntidad tecnicosEntidad, JQGridRequestDto jqGridRequestDto,
            Boolean startsWith) {
        return this.tecnicosEntidadDao.findAllLike(tecnicosEntidad, jqGridRequestDto, startsWith);
    }

    /*
     * OPERACIONES RUP_TABLE
     */

    /**
     * Removes rows from the TecnicosEntidad table.
     *
     * @param filterTecnicosEntidad
     *            TecnicosEntidad
     * @param jqGridRequestDto
     *            JQGridRequestDto
     * @param startsWith
     *            Boolean
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class)
    public void removeMultiple(TecnicosEntidad filterTecnicosEntidad, JQGridRequestDto jqGridRequestDto,
            Boolean startsWith) {
        this.tecnicosEntidadDao.removeMultiple(filterTecnicosEntidad, jqGridRequestDto, startsWith);
    }

    /**
     * Removes rows from the TecnicosEntidad table.
     *
     * @param tecnicosEntidad
     *            TecnicosEntidad tecnicosEntidad
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class)
    public void asociarTecnico(TecnicosEntidad tecnicosEntidad) {
        this.tecnicosEntidadDao.asociarTecnico(tecnicosEntidad);
    }

    /**
     * Removes rows from the TecnicosEntidad table.
     *
     * @param tecnicosEntidad
     *            TecnicosEntidad tecnicosEntidad
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class)
    public void desasociarTecnico(TecnicosEntidad tecnicosEntidad) {
        this.tecnicosEntidadDao.desasociarTecnico(tecnicosEntidad);
    }

    /**
     * Filter method in the TecnicosEntidad table.
     *
     * @param filterTecnicosEntidad
     *            TecnicosEntidad
     * @param jqGridRequestDto
     *            JQGridRequestDto
     * @param startsWith
     *            Boolean
     * @return JQGridResponseDto<TecnicosEntidad>
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, isolation = Isolation.READ_COMMITTED)
    public JQGridResponseDto<TecnicosEntidad> filter(TecnicosEntidad filterTecnicosEntidad,
            JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
        List<TecnicosEntidad> listaTecnicosEntidad = this.tecnicosEntidadDao.findAllLike(filterTecnicosEntidad,
                jqGridRequestDto, false);
        Long recordNum = this.tecnicosEntidadDao
                .findAllLikeCount(filterTecnicosEntidad != null ? filterTecnicosEntidad : new TecnicosEntidad(), false);
        if (jqGridRequestDto.getMultiselection().getSelectedIds() != null) {
            List<TableRowDto<TecnicosEntidad>> reorderSelection = this.tecnicosEntidadDao
                    .reorderSelection(filterTecnicosEntidad, jqGridRequestDto, startsWith);
            return new JQGridResponseDto<TecnicosEntidad>(jqGridRequestDto, recordNum, listaTecnicosEntidad,
                    reorderSelection);
        }
        return new JQGridResponseDto<TecnicosEntidad>(jqGridRequestDto, recordNum, listaTecnicosEntidad);
    }

    /**
     * Reorder the selection made in TecnicosEntidad table.
     *
     * @param filterTecnicosEntidad
     *            TecnicosEntidad
     * @param jqGridRequestDto
     *            JQGridRequestDto
     * @param startsWith
     *            Boolean
     * @return Object
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, isolation = Isolation.READ_COMMITTED)
    public Object reorderSelection(TecnicosEntidad filterTecnicosEntidad, JQGridRequestDto jqGridRequestDto,
            Boolean startsWith) {
        return this.tecnicosEntidadDao.reorderSelection(filterTecnicosEntidad, jqGridRequestDto, startsWith);
    }

}
