package com.ejie.ab04b.service.toolkit;

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.ab04b.constantes.Constantes;
import com.ejie.ab04b.constantes.ConstantesFdCdP;
import com.ejie.ab04b.constantes.GrupoBuzon;
import com.ejie.ab04b.model.ApartadoAnexoI;
import com.ejie.ab04b.model.ApartadoAnexoII;
import com.ejie.ab04b.model.Buzon;
import com.ejie.ab04b.model.ClaseCentroTrabajo;
import com.ejie.ab04b.model.CnaeJ73;
import com.ejie.ab04b.model.EmpresaAuditora;
import com.ejie.ab04b.model.EmpresaServicioPrevencion;
import com.ejie.ab04b.model.EntidadGestoraColaboradora;
import com.ejie.ab04b.model.ModalidadOrganizacionPreventiva;
import com.ejie.ab04b.model.SeccionJ73;
import com.ejie.ab04b.model.TipoObra;
import com.ejie.ab04b.model.nora.Calle;
import com.ejie.ab04b.model.nora.Localidad;
import com.ejie.ab04b.model.nora.Municipio;
import com.ejie.ab04b.model.nora.Pais;
import com.ejie.ab04b.model.nora.Provincia;
import com.ejie.ab04b.service.ApartadoAnexoIIService;
import com.ejie.ab04b.service.ApartadoAnexoIService;
import com.ejie.ab04b.service.BuzonService;
import com.ejie.ab04b.service.ClaseCentroTrabajoService;
import com.ejie.ab04b.service.CnaeJ73Service;
import com.ejie.ab04b.service.EmpresaAuditoraService;
import com.ejie.ab04b.service.EmpresaServicioPrevencionService;
import com.ejie.ab04b.service.EntidadGestoraColaboradoraService;
import com.ejie.ab04b.service.ModalidadOrganizacionPreventivaService;
import com.ejie.ab04b.service.SeccionJ73Service;
import com.ejie.ab04b.service.TipoObraService;
import com.ejie.ab04b.service.nora.CalleService;
import com.ejie.ab04b.service.nora.LocalidadService;
import com.ejie.ab04b.service.nora.MunicipioService;
import com.ejie.ab04b.service.nora.PaisService;
import com.ejie.ab04b.service.nora.ProvinciaService;
import com.ejie.ab04b.util.ToolkitParameterUtils;
import com.ejie.ab04b.util.ToolkitUtils;
import com.ejie.ab04b.util.Utilities;
import com.ejie.ab04b.webservice.client.toolkit.X43KWebService;
import com.ejie.r02s.xml.Parameters;
import com.ejie.x43k.xml.Documento;

/**
 * @author GFI-NORTE
 *
 */
@Service(value = "toolkitService")
public class ToolkitService {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(ToolkitService.class);

	@Autowired()
	private TipoObraService tipoObraService;
	@Autowired()
	private ApartadoAnexoIService apartadoAnexoIService;
	@Autowired()
	private ApartadoAnexoIIService apartadoAnexoIIService;
	@Autowired()
	private ClaseCentroTrabajoService claseCentroTrabajoService;
	@Autowired()
	private EntidadGestoraColaboradoraService entidadGestoraColaboradoraService;
	@Autowired()
	private ModalidadOrganizacionPreventivaService modalidadOrganizacionPreventivaService;
	@Autowired()
	private EmpresaAuditoraService empresaAuditoraService;
	@Autowired()
	private EmpresaServicioPrevencionService empresaServicioPrevencionService;
	@Autowired()
	private PaisService paisService;
	@Autowired()
	private ProvinciaService provinciaService;
	@Autowired()
	private MunicipioService municipioService;
	@Autowired()
	private LocalidadService localidadService;
	@Autowired()
	private CalleService calleService;
	@Autowired()
	private BuzonService buzonService;
	@Autowired()
	private SeccionJ73Service seccionJ73Service;
	@Autowired()
	private CnaeJ73Service cnaeJ73Service;

	@Autowired()
	private X43KWebService x43kWebServicePort;

	/**
	 * Devuelve un XML con un objeto Parameters con todos los TipoObra
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaTipoObra() {

		List<TipoObra> listaTipoObra = this.tipoObraService
				.findAll(new TipoObra(), null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaTipoObra(listaTipoObra);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los ApartadoAnexoI
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaApartadoAnexoI() {

		List<ApartadoAnexoI> listaApartadoAnexoI = this.apartadoAnexoIService
				.findAll(new ApartadoAnexoI(), null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaApartadoAnexoI(listaApartadoAnexoI);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los ApartadoAnexoII
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaApartadoAnexoII() {

		List<ApartadoAnexoII> listaApartadoAnexoII = this.apartadoAnexoIIService
				.findAll(new ApartadoAnexoII(), null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaApartadoAnexoII(listaApartadoAnexoII);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los ClaseCentroTrabajo
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaClaseCentroTrabajo() {

		List<ClaseCentroTrabajo> listaClaseCentroTrabajo = this.claseCentroTrabajoService
				.findAll(new ClaseCentroTrabajo(), null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaClaseCentroTrabajo(
						listaClaseCentroTrabajo);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los
	 * EntidadGestoraColaboradora
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaEntidadGestoraColaboradora() {

		List<EntidadGestoraColaboradora> listaEntidadGestoraColaboradora = this.entidadGestoraColaboradoraService
				.findAll(new EntidadGestoraColaboradora(), null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaEntidadGestoraColaboradora(
						listaEntidadGestoraColaboradora);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve la descripción de una EntidadGestoraColaboradora
	 * 
	 *  codEntidad
	 *            String
	 *  idioma
	 *            String
	 *  String.
	 *
	 * @param codEntidad the cod entidad
	 * @param idioma the idioma
	 * @return the string
	 */
	public String obtenerDescripcionEntidadGestoraColaboradora(
			String codEntidad, String idioma) {

		ToolkitService.LOGGER.info("CODENTIDAD1111 {}", codEntidad);

		EntidadGestoraColaboradora entidad = null;
		if (!Utilities.getInstance().isEmpty(codEntidad)) {
			entidad = this.entidadGestoraColaboradoraService
					.find(new EntidadGestoraColaboradora(codEntidad));
		}

		if (entidad == null) {
			return "";
		} else if (Constantes.EU.equals(idioma)) {
			return entidad.getDesentiatEu078();
		} else {
			return entidad.getDesentiatEs078();
		}
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los
	 * ModalidadOrganizacionPreventiva
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaModalidadOrganizacionPreventiva() {

		List<ModalidadOrganizacionPreventiva> listaModalidadOrganizacionPreventiva = this.modalidadOrganizacionPreventivaService
				.findAll(new ModalidadOrganizacionPreventiva(), null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaModalidadOrganizacionPreventiva(
						listaModalidadOrganizacionPreventiva);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los EmpresaAuditora
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaEmpresaAuditora() {

		List<EmpresaAuditora> listaEmpresaAuditora = this.empresaAuditoraService
				.findAll(new EmpresaAuditora(), null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaEmpresaAuditora(listaEmpresaAuditora);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve la descripción de una EmpresaAuditora
	 * 
	 *  codEmpresa
	 *            String
	 *  idioma
	 *            String
	 *  String.
	 *
	 * @param codEmpresa the cod empresa
	 * @param idioma the idioma
	 * @return the string
	 */
	public String obtenerDescripcionEmpresaAuditora(String codEmpresa,
			String idioma) {

		EmpresaAuditora empresa = this.empresaAuditoraService
				.find(new EmpresaAuditora(codEmpresa));

		if (Constantes.EU.equals(idioma)) {
			return empresa.getDesempaudEu079();
		} else {
			return empresa.getDesempaudEs079();
		}
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los
	 * EmpresaServicioPrevencion
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaEmpresaServicioPrevencion() {

		List<EmpresaServicioPrevencion> listaEmpresaServicioPrevencion = this.empresaServicioPrevencionService
				.findAll(new EmpresaServicioPrevencion(), null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaEmpresaServicioPrevencion(
						listaEmpresaServicioPrevencion);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve la descripción de una EmpresaServicioPrevencion
	 * 
	 *  codEmpresa
	 *            String
	 *  idioma
	 *            String
	 *  String.
	 *
	 * @param codEmpresa the cod empresa
	 * @param idioma the idioma
	 * @return the string
	 */
	public String obtenerDescripcionEmpresaServicioPrevencion(String codEmpresa,
			String idioma) {

		EmpresaServicioPrevencion empresa = this.empresaServicioPrevencionService
				.find(new EmpresaServicioPrevencion(codEmpresa));

		if (Constantes.EU.equals(idioma)) {
			return empresa.getDesprevEu080();
		} else {
			return empresa.getDesprevEs080();
		}
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los Pais
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaPais() {

		List<Pais> listaPais = this.paisService.findAll(new Pais(), null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaPais(listaPais);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los Provincia
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaProvincia() {

		List<Provincia> listaProvincia = this.provinciaService
				.findAll(new Provincia());

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaProvincia(listaProvincia);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con los Municipios de una
	 * Provincia
	 * 
	 *  codProvincia
	 *            String
	 *  String.
	 *
	 * @param codProvincia the cod provincia
	 * @return the string
	 */
	public String obtenerListaMunicipioDeProvincia(String codProvincia) {

		Municipio filterMunicipio = new Municipio();
		filterMunicipio.setCodProvincia(codProvincia);
		List<Municipio> listaMunicipio = this.municipioService
				.findAll(filterMunicipio);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaMunicipio(listaMunicipio);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con las Localidades de un
	 * Municipio
	 * 
	 *  codMunicipio
	 *            String
	 *  codProvincia
	 *            String
	 *  String.
	 *
	 * @param codMunicipio the cod municipio
	 * @param codProvincia the cod provincia
	 * @return the string
	 */
	public String obtenerListaLocalidadDeMunicipio(String codMunicipio,
			String codProvincia) {

		Localidad filterLocalidad = new Localidad();
		filterLocalidad.setCodMunicipio(codMunicipio);
		filterLocalidad.setCodProvincia(codProvincia);
		List<Localidad> listaLocalidad = this.localidadService
				.findAll(filterLocalidad);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaLocalidad(listaLocalidad);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con las Calles de una Localidad
	 * 
	 *  codLocalidad
	 *            String
	 *  String.
	 *
	 * @param codLocalidad the cod localidad
	 * @return the string
	 */
	public String obtenerListaCalleDeLocalidad(String codLocalidad) {

		Calle filterCalle = new Calle();
		filterCalle.setCodLocalidad(codLocalidad);
		List<Calle> listaCalle = this.calleService.findAll(filterCalle);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaCalle(listaCalle);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los Seccion
	 * 
	 *  String.
	 *
	 * @return the string
	 */
	public String obtenerListaSeccion() {

		List<SeccionJ73> listaSecciones = this.seccionJ73Service
				.findAll(new SeccionJ73(), null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaSeccion(listaSecciones);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los CNAEs principales
	 * de división
	 * 
	 *  codSector
	 *            String
	 *  String.
	 *
	 * @param codSector the cod sector
	 * @return the string
	 */
	public String obtenerListaDivision(String codSector) {

		CnaeJ73 filterCnae = new CnaeJ73();
		filterCnae.setSecc003(codSector);
		List<CnaeJ73> listaDivisiones = this.cnaeJ73Service
				.findAllNivelSuperior(filterCnae);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaCnae(listaDivisiones);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los CNAE
	 * 
	 *  codSector
	 *            String
	 *  codDivision
	 *            String
	 *  String.
	 *
	 * @param codSector the cod sector
	 * @param codDivision the cod division
	 * @return the string
	 */
	public String obtenerListaCnae(String codSector, String codDivision) {

		CnaeJ73 filterCnae = new CnaeJ73();
		filterCnae.setSecc003(codSector);
		filterCnae.setDivi003(codDivision);
		List<CnaeJ73> listaDivisiones = this.cnaeJ73Service.findAll(filterCnae,
				null);

		Parameters parameters = ToolkitParameterUtils.getInstance()
				.construirParametersListaCnae(listaDivisiones);

		return ToolkitParameterUtils.getInstance()
				.unparseParametersToString(parameters);
	}

	/**
	 * Devuelve un XML con un objeto Parameters con todos los CNAE
	 * 
	 *  cnae
	 *            String
	 *  String.
	 *
	 * @param cnae the cnae
	 * @return the string
	 */
	public String obtenerListaCnae(String cnae) {

		CnaeJ73 filterCnae = new CnaeJ73();
		filterCnae.setCnae003(cnae);
		CnaeJ73 cnaeJ73 = this.cnaeJ73Service.findByCnae(filterCnae);

		if (cnaeJ73 != null) {
			// El cnae introducido existe
			return this.obtenerListaCnae(cnaeJ73.getSecc003(),
					cnaeJ73.getDivi003());
		} else {
			// El cnae introducido NO existe
			return ToolkitParameterUtils.getInstance()
					.construirParametersListaVacia();
		}
	}

	/**
	 * Devuelve un XML con el código de CNAE si este existe
	 * 
	 *  cnae
	 *            String
	 *  String.
	 *
	 * @param cnae the cnae
	 * @return the string
	 */
	public String autocompletarCnae(String cnae) {

		CnaeJ73 filterCnae = new CnaeJ73();
		filterCnae.setCnae003(cnae);
		CnaeJ73 cnaeJ73 = this.cnaeJ73Service.findByCnae(filterCnae);

		if (cnaeJ73 != null) {
			// El cnae introducido existe
			return cnaeJ73.getCnae003();
		} else {
			// El cnae introducido NO existe
			return null;
		}
	}

	/**
	 * Devuelve un XML con un objeto ManagingUnit con el órgano gestor y el
	 * buzón
	 * 
	 *  codProvincia
	 *            String
	 *  procedureId
	 *            String
	 *  String.
	 *
	 * @param codProvincia the cod provincia
	 * @param procedureId the procedure id
	 * @return the string
	 */
	public String obtenerOrganoGestorYBuzon(String codProvincia,
			String procedureId) {

		String organoGestor = Utilities.getInstance().obtenerManagingunitId();
		GrupoBuzon grupoBuzon = null;

		if (Utilities.getInstance().obtenerProcedureIdApertura()
				.equals(procedureId)) {
			grupoBuzon = GrupoBuzon.RESP_TAREA;
		} else if (Utilities.getInstance().obtenerProcedureIdOs2()
				.equals(procedureId)
				|| Utilities.getInstance().obtenerProcedureIdOs3()
						.equals(procedureId)) {
			grupoBuzon = GrupoBuzon.RESP_TAREA_OSALAN;
		}

		Buzon filterBuzon = new Buzon();
		filterBuzon.setCodTerrit076(codProvincia);
		filterBuzon.setGrupo(grupoBuzon);
		filterBuzon = this.buzonService.find(filterBuzon);

		StringBuilder xmlOrganoGestor = new StringBuilder();
		xmlOrganoGestor.append(ConstantesFdCdP.TAG_MANAGINGUNIT_OPEN);

		xmlOrganoGestor.append(ConstantesFdCdP.TAG_MANAGINGUNIT_ID_OPEN);
		xmlOrganoGestor.append(organoGestor);
		xmlOrganoGestor.append(ConstantesFdCdP.TAG_MANAGINGUNIT_ID_CLOSE);
		xmlOrganoGestor.append(ConstantesFdCdP.TAG_MANAGINGUNIT_INBOXID_OPEN);
		xmlOrganoGestor.append(filterBuzon.getMailbox076());
		xmlOrganoGestor.append(ConstantesFdCdP.TAG_MANAGINGUNIT_INBOXID_CLOSE);

		xmlOrganoGestor.append(ConstantesFdCdP.TAG_MANAGINGUNIT_CLOSE);

		return xmlOrganoGestor.toString();
	}

	/**
	 *  procedureId
	 *            String
	 *  documento
	 *            String
	 *  String.
	 *
	 * @param procedureId the procedure id
	 * @param documento the documento
	 * @return the string
	 */
	public String guardarDatosPrecargaToolkit(String procedureId,
			Documento documento) {

		ToolkitService.LOGGER.info(
				"Entra en guardarDatosPrecargaToolkit: procedureId {}",
				procedureId);

		try {
			String xmlDatos = "";
			if (documento != null) {
				xmlDatos = ToolkitUtils.getInstance()
						.getDocumentoAsString(documento);
			}
			xmlDatos = xmlDatos
					.replaceAll(
							"<\\?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"yes\"\\?>",
							"")
					.replace(" xmlns=\"http://ejie.com/x43k/xml\"", "")
					.replaceAll("<ApplicantInfo/>",
							"<ApplicantInfo></ApplicantInfo>")
					.replaceAll("<sender/>", "<sender></sender>");
			ToolkitService.LOGGER.info("xmlDatos: {}", xmlDatos);

			return this.x43kWebServicePort.saveDataPreload(procedureId,
					xmlDatos);
		} catch (Exception e) {
			ToolkitService.LOGGER.info(
					"Entra en la llamada x43kWebServicePort.saveDataPreload",
					e);

			return null;
		}
	}

}
