package com.ejie.ab79.service.expedientes;

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 com.ejie.ab79.clientesWS.ab61WebService.Ab61Exception;
import com.ejie.ab79.clientesWS.ab61WebService.DatosInicioOficio;
import com.ejie.ab79.clientesWS.ab61WebService.DatosLlamadaConsultaDatosInteresado;
import com.ejie.ab79.clientesWS.ab61WebService.DatosLlamadaGenerarExpedienteInicioOficio;
import com.ejie.ab79.clientesWS.ab61WebService.DatosRespuestaConsultaDatosInteresado;
import com.ejie.ab79.clientesWS.ab61WebService.EmisorInicioOficio;
import com.ejie.ab79.clientesWS.ab61WebService.Exception_Exception;
import com.ejie.ab79.clientesWS.ab61WebService.TipoDocumentoIdentidad;
import com.ejie.ab79.clientesWS.ab61WebService.Usuario;
import com.ejie.ab79.comun.Constantes;
import com.ejie.ab79.dao.RelEstInsDao;
import com.ejie.ab79.dao.expedientes.DatosDireccionesDao;
import com.ejie.ab79.dao.expedientes.DatosTercerosDao;
import com.ejie.ab79.dao.expedientes.ExpedientesDao;
import com.ejie.ab79.dao.inspecciones.CampainasInspeccionDao;
import com.ejie.ab79.dao.inspecciones.InspeccionesDao;
import com.ejie.ab79.dao.procedimientos.ProcedimientosDao;
import com.ejie.ab79.model.RelEstIns;
import com.ejie.ab79.model.expedientes.DatosDirecciones;
import com.ejie.ab79.model.expedientes.DatosTerceros;
import com.ejie.ab79.model.expedientes.Expedientes;
import com.ejie.ab79.model.inspecciones.CampainasInspeccion;
import com.ejie.ab79.model.inspecciones.Inspecciones;
import com.ejie.ab79.model.procedimientos.Procedimientos;
import com.ejie.ab79.service.inspecciones.InspeccionesService;
import com.ejie.ab79.webservice.adaptadores.ab61WebServiceAdaptador;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;

/**
 * ExpedientesServiceImpl  
 * 
 *  
 */

@Service(value = "expedientesService")
public class ExpedientesServiceImpl implements ExpedientesService {

	@Autowired
	private ExpedientesDao expedientesDao;
	@Autowired
	private DatosTercerosDao datosTercerosDao;
	@Autowired
	private DatosDireccionesDao datosDireccionesDao;
	@Autowired
	private RelEstInsDao relEstInsDao;
	@Autowired
	private CampainasInspeccionDao campainasInspeccionDao;
	@Autowired
	private InspeccionesDao inspeccionesDao;
	@Autowired
	private ProcedimientosDao procedimientosDao;
	@Autowired
	private ab61WebServiceAdaptador ab61WebServiceAdaptadorService;
	@Autowired
	private InspeccionesService inspeccionesService;

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

	@Override
	public Expedientes findIdExpediente(Expedientes expedientes) {
		return this.expedientesDao.findIdExpediente(expedientes);
	}

	@Override
	public Expedientes find(Expedientes expedientes) {
		return this.expedientesDao.find(expedientes);
	}

	@Override
	public Expedientes findByIdExpediente(Expedientes expedientes) {
		return this.expedientesDao.findByIdExpediente(expedientes);
	}

	@Override
	public Expedientes findByFolderId(Expedientes expedientes) {
		return this.expedientesDao.findByFolderId(expedientes);
	}

	@Override
	public Expedientes findByIdInspeccion(Expedientes expedientes) {
		return this.expedientesDao.findByIdInspeccion(expedientes);
	}

	@Override
	public Expedientes findByIdExpedienteOrigen(Expedientes expedientesOrigen) {
		return this.expedientesDao.findByIdExpedienteOrigen(expedientesOrigen);
	}

	@Override
	public DatosTerceros aniadirInteresado(DatosTerceros datosTercero, Integer idInspeccion, Usuario usuario) {

		datosTercero.setTipoParticipante(Constantes.PARTICIPANTE_TITULAR);
		if (datosTercero.getIdTercero() != null) {
			// Update
			ExpedientesServiceImpl.logger.info("[aniadirInteresado] - Update de datosDirecciones");
			datosTercero.setUsuarioUltmodificacion(usuario.getUsuario());
			datosTercero = this.datosTercerosDao.update(datosTercero);
		} else {
			// Insert
			ExpedientesServiceImpl.logger.info("[aniadirInteresado] - Insert de datosDirecciones");
			datosTercero.setUsuarioRegistro(usuario.getUsuario());
			datosTercero = this.datosTercerosDao.add(datosTercero);
		}

		Inspecciones inspeccion = new Inspecciones();
		inspeccion.setIdInspeccion(idInspeccion);
		inspeccion = this.inspeccionesDao.find(inspeccion);

		RelEstIns relEstIns = this.relEstInsDao.findByInspeccion(inspeccion);
		DatosDirecciones datosDireccion = new DatosDirecciones();

		if (relEstIns.getIdDireccion() != null) {
			datosDireccion.setIdDireccion(relEstIns.getIdDireccion());
			datosDireccion = this.datosDireccionesDao.find(datosDireccion);
		}

		// Generamos el título => (provincia) [identificadorCampaina] nombre
		// apellido1 apellido2
		CampainasInspeccion campaina = new CampainasInspeccion();
		campaina.setIdCampaina(inspeccion.getCampaina().getIdCampaina());
		campaina = this.campainasInspeccionDao.find(campaina);

		inspeccion.setCampaina(campaina);

		if (inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_CAMPAINA)
				|| inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_INSPECCION_OFICIO)
				|| inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_BUZON_FRAUDE)) {
			String titulo = this.inspeccionesService.crearTitulo(inspeccion, datosTercero, datosDireccion);
			relEstIns.setTitulo(titulo);
			ExpedientesServiceImpl.logger
					.info("[aniadirInteresado] - Generamos el título de la tabla relEstIns : " + titulo);
		}
		relEstIns.setIdTercero(datosTercero.getIdTercero());
		relEstIns.setUsuarioUltModificacion(usuario.getUsuario());
		// Actualizamos la relación con la inspección
		ExpedientesServiceImpl.logger.info("[aniadirInteresado] - Update de relEstIns");
		this.relEstInsDao.update(relEstIns);

		return null;
	}

	@Override
	public Expedientes findByExpedienteIdExpediente(Expedientes expedientes) {
		return this.expedientesDao.findByExpedienteIdExpediente(expedientes);
	}

	@Override
	public TableResponseDto<Expedientes> filterDocumentacionExpRel(Expedientes filterExpedientes,
			TableRequestDto tableRequestDto, String documentosTitular) {
		List<Expedientes> listaExpedientes = this.expedientesDao.findDocumentacionExpRel(filterExpedientes,
				tableRequestDto, documentosTitular);
		Long recordNum = this.expedientesDao.findDocumentacionExpRelCount(filterExpedientes, documentosTitular);

		return new TableResponseDto<Expedientes>(tableRequestDto, recordNum, listaExpedientes);
	}

	@Override
	public boolean actualizarParticipaciones(String folderId, String nombreUsuario) throws Exception_Exception {
		ExpedientesServiceImpl.logger.info("Entrada a actualizarParticipaciones");
		return this.ab61WebServiceAdaptadorService.actualizarParticipaciones(folderId, nombreUsuario);
	}

	@Override
	public void actualizarTituloTerritorioHistorico(Expedientes expediente) {
		this.expedientesDao.actualizarTituloTerritorioHistorico(expediente);
	}

	@Override
	public boolean findExpedienteCerrado(Expedientes expediente) {
		return this.expedientesDao.findExpedienteCerrado(expediente);
	}

	/**
	 * Consulta de los datos del interesado para despues geenrar el expeidente
	 * de inicio oficio
	 */
	@Override
	public List<DatosRespuestaConsultaDatosInteresado> consultaDatosInteresado(Integer idProcedimiento,
			List<Integer> listaIdTerceros) {

		logger.info("INICIO [consultaDatosInteresado]");
		Procedimientos procedimiento = this.procedimientosDao.find(new Procedimientos(idProcedimiento));

		logger.info("INICIO [consultaDatosInteresado] :: Asignamos los datos necesarios para la consulta");
		DatosLlamadaConsultaDatosInteresado elementoEnviar = new DatosLlamadaConsultaDatosInteresado();
		elementoEnviar.setProcedureId(procedimiento.getCodProcedureId());
		for (int i = 0; i < listaIdTerceros.size(); i++) {
			elementoEnviar.getListaTerceros().add(listaIdTerceros.get(i));
		}

		List<DatosRespuestaConsultaDatosInteresado> retornoPantalla = new java.util.ArrayList<DatosRespuestaConsultaDatosInteresado>();
		try {

			logger.info(
					"INICIO [consultaDatosInteresado] :: Llamada al servicio web para obtener los datos del interesado");
			retornoPantalla = ab61WebServiceAdaptadorService.obtenerDatosInteresado(elementoEnviar);
		} catch (Ab61Exception e) {
			logger.error("Excepcion obtenida ", e);
		}

		logger.info("FIN [consultaDatosInteresado]");
		return retornoPantalla;
	}

	@Override
	public DatosInicioOficio crearExpedienteInicioOficioDatosInteresado(Integer idProcedimiento, Usuario usuario,
			DatosLlamadaGenerarExpedienteInicioOficio datosLlamada) throws Ab61Exception, Exception {

		logger.info("INICIO [crearExpedienteInicioOficioDatosInteresado]");

		DatosInicioOficio datosInicioOficio = new DatosInicioOficio();

		try {

			logger.info("[crearExpedienteInicioOficioDatosInteresado] :: Se lee el procedimiento");
			Procedimientos procedimiento = new Procedimientos();
			procedimiento.setIdProcedimiento(idProcedimiento);
			procedimiento = this.procedimientosDao.find(procedimiento);

			logger.info("[crearExpedienteInicioOficioDatosInteresado] :: Se genera el EmisorInicioOficio");
			EmisorInicioOficio emisorInicioOficio = new EmisorInicioOficio();
			emisorInicioOficio.setIdEmsisor(usuario.getIdentificador());
			emisorInicioOficio.setTipoDocumentoIdentidad(TipoDocumentoIdentidad.NIF);
			emisorInicioOficio.setNombreEmisor(usuario.getNombreUsuario());
			emisorInicioOficio.setPrimerApellido(usuario.getPrimerApellido());
			emisorInicioOficio.setSegundoApellido(usuario.getSegundoApellido());

			datosLlamada.setEmisorInicioficio(emisorInicioOficio);
			datosLlamada.setProcedureId(procedimiento.getCodProcedureId());

			logger.info(
					"[crearExpedienteInicioOficioDatosInteresado] :: Llamada a generarExpedienteInicioOficioConDatosInteresado");
			datosInicioOficio = this.ab61WebServiceAdaptadorService
					.generarExpedienteInicioOficioConDatosInteresado(datosLlamada);

		} catch (Ab61Exception ab61) {
			logger.error("Ab61Exception [crearExpedienteInicioOficioDatosInteresado] " + ab61.getMessage(), ab61);
			throw ab61;
		} catch (Exception e) {
			logger.error("Exception [crearExpedienteInicioOficioDatosInteresado] " + e.getMessage(), e);
			throw e;
		}

		logger.info("FIN [crearExpedienteInicioOficioDatosInteresado]");
		return datosInicioOficio;
	}
}
