package com.ejie.ab04b.info;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

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

import com.ejie.ab04b.model.Tablones;
import com.ejie.ab04b.service.TablonesService;
import com.ejie.ab04b.service.platea.FDCDPFacadeService;
import com.ejie.ab04b.util.PropertiesUtil;
import com.ejie.platea.generic.xml.DepartmentName;
import com.ejie.platea.generic.xml.Description;
import com.ejie.platea.generic.xml.EntityName;
import com.ejie.platea.generic.xml.FamilyName;
import com.ejie.platea.generic.xml.Language;
import com.ejie.platea.generic.xml.ManagingUnitName;
import com.ejie.platea.generic.xml.ProcedureName;
import com.ejie.sc.xml.ConsultationContext;
import com.ejie.sc.xml.OrganInfo;

/**
 * 
 * @author GFI
 * 
 */
@Service()
public class InfoProcedureFDCDP implements java.io.Serializable {

	private static final long serialVersionUID = 1L;
	private static final Logger LOGGER = LoggerFactory
			.getLogger(InfoProcedureFDCDP.class);

	private Map<String, ConsultationContext> procedureInfoMap;

	@Autowired()
	private FDCDPFacadeService service;

	@Autowired()
	private Properties appConfiguration;

	@Autowired()
	private TablonesService tablonesService;

	/**
	 * Carga en un mapa las informaciones que hay en el FDCDP de los procedureId
	 * definidos en el properties.
	 */
	public void cargarInfoProcedures() {

		List<String> idProcedureList = new ArrayList<String>();
		String sProp = null;
		for (Object prop : this.appConfiguration.keySet()) {
			sProp = (String) prop;
			if (sProp.startsWith(PropertiesUtil.PROCEDURE_ID_PREFIX)) {
				idProcedureList.add(this.appConfiguration.getProperty(sProp));
			}
		}

		if (idProcedureList.size() > 0) {
			this.procedureInfoMap = new HashMap<String, ConsultationContext>();
			List<Tablones> lista = tablonesService
					.findAll(new Tablones(null, "PROCEDURE.INFO"), null);

			String procedure_info_department_id = "";
			String procedure_info_department_desc_es = "";
			String procedure_info_department_desc_eu = "";
			String procedure_info_entity_id = "";
			String procedure_info_entity_desc_es = "";

			String procedure_info_entity_desc_eu = "";

			String procedure_info_family_id = "";
			String procedure_info_family_desc_es = "";

			String procedure_info_family_desc_eu = "";

			String procedure_info_manageUnit_id = "";
			String procedure_info_manageUnit_desc_es = "";

			String procedure_info_manageUnit_desc_eu = "";

			for (Tablones tablones : lista) {
				if (tablones.getCodigo088().equalsIgnoreCase("DEPARTMENT.ID")) {
					procedure_info_department_id = tablones.getDescripcionEs();
				}
				if (tablones.getCodigo088()
						.equalsIgnoreCase("DEPARTMENT.DESC")) {
					procedure_info_department_desc_es = tablones
							.getDescripcionEs();
					procedure_info_department_desc_eu = tablones
							.getDescripcionEu();
				}
				if (tablones.getCodigo088().equalsIgnoreCase("ENTITY.ID")) {
					procedure_info_entity_id = tablones.getDescripcionEs();
				}
				if (tablones.getCodigo088().equalsIgnoreCase("ENTITY.DESC")) {
					procedure_info_entity_desc_es = tablones.getDescripcionEs();
					procedure_info_entity_desc_eu = tablones.getDescripcionEu();
				}
				if (tablones.getCodigo088().equalsIgnoreCase("FAMILY.ID")) {
					procedure_info_family_id = tablones.getDescripcionEs();
				}
				if (tablones.getCodigo088().equalsIgnoreCase("FAMILY.DESC")) {
					procedure_info_family_desc_es = tablones.getDescripcionEs();
					procedure_info_family_desc_eu = tablones.getDescripcionEu();
				}
				if (tablones.getCodigo088().equalsIgnoreCase("MANAGEUNIT.ID")) {
					procedure_info_manageUnit_id = tablones.getDescripcionEs();
				}
				if (tablones.getCodigo088()
						.equalsIgnoreCase("MANAGEUNIT.DESC")) {
					procedure_info_manageUnit_desc_es = tablones
							.getDescripcionEs();
					procedure_info_manageUnit_desc_eu = tablones
							.getDescripcionEu();
				}
			}
			ConsultationContext infoProcedure = null;
			String procInfoLoadProperties = PropertiesUtil
					.getProperty(PropertiesUtil.PROC_INFO_LOAD_PROPERTIES);
			for (String idProcedure : idProcedureList) {
				if (procInfoLoadProperties != null && Boolean
						.valueOf(procInfoLoadProperties).booleanValue()) {

					// Lo cargamos de properties
					infoProcedure = new ConsultationContext();

					// IDs
					infoProcedure.setDepartmentId(procedure_info_department_id);
					infoProcedure.setEntityID(procedure_info_entity_id);
					infoProcedure.setFamilyId(procedure_info_family_id);
					infoProcedure.setOrganInfo(new OrganInfo());
					infoProcedure.getOrganInfo()
							.setManagingUnitId(procedure_info_manageUnit_id);
					infoProcedure.setProcedureId(idProcedure);

					DepartmentName departmentName = new DepartmentName();
					Language langEsDepartment = new Language();
					langEsDepartment.setLocale("es");
					langEsDepartment
							.setValue(procedure_info_department_desc_es);
					Language langEuDepartment = new Language();
					langEuDepartment.setLocale("eu");
					langEuDepartment
							.setValue(procedure_info_department_desc_eu);
					Description descDepartment = new Description();
					descDepartment.getLanguage().add(langEsDepartment);
					descDepartment.getLanguage().add(langEuDepartment);
					departmentName.setDescription(descDepartment);
					infoProcedure.setDepartmentName(departmentName);

					ManagingUnitName managingUnitName = new ManagingUnitName();
					Language langEsManageUnit = new Language();
					langEsManageUnit.setLocale("es");
					langEsManageUnit
							.setValue(procedure_info_manageUnit_desc_es);
					Language langEuManageUnit = new Language();
					langEuManageUnit.setLocale("eu");
					langEuManageUnit
							.setValue(procedure_info_manageUnit_desc_eu);
					Description descManageUnit = new Description();
					descManageUnit.getLanguage().add(langEsManageUnit);
					descManageUnit.getLanguage().add(langEuManageUnit);
					managingUnitName.setDescription(descManageUnit);
					infoProcedure.getOrganInfo()
							.setManagingUnitName(managingUnitName);

					ProcedureName procedureName = new ProcedureName();
					Language langEsProcedure = new Language();
					langEsProcedure.setLocale("es");
					Language langEuProcedure = new Language();
					langEuProcedure.setLocale("eu");
					langEsProcedure.setValue(
							appConfiguration.getProperty(new StringBuilder(
									PropertiesUtil.PROC_INFO_PROC_DESC_ES_PREFIX)
											.append(idProcedure).toString()));
					langEuProcedure.setValue(
							appConfiguration.getProperty(new StringBuilder(
									PropertiesUtil.PROC_INFO_PROC_DESC_EU_PREFIX)
											.append(idProcedure).toString()));

					Description descProcedure = new Description();
					descProcedure.getLanguage().add(langEsProcedure);
					descProcedure.getLanguage().add(langEuProcedure);
					procedureName.setDescription(descProcedure);
					infoProcedure.setProcedureName(procedureName);

					EntityName entityName = new EntityName();
					Language langEsEntity = new Language();
					langEsEntity.setLocale("es");
					langEsEntity.setValue(procedure_info_entity_desc_es);
					Language langEuEntity = new Language();
					langEuEntity.setLocale("eu");
					langEuEntity.setValue(procedure_info_entity_desc_eu);
					Description descEntity = new Description();
					descEntity.getLanguage().add(langEsEntity);
					descEntity.getLanguage().add(langEuEntity);
					entityName.setDescription(descEntity);
					infoProcedure.setEntityName(entityName);

					FamilyName familyName = new FamilyName();
					Language langEsFamily = new Language();
					langEsFamily.setLocale("es");
					langEsFamily.setValue(procedure_info_family_desc_es);
					Language langEuFamily = new Language();
					langEuFamily.setLocale("eu");
					langEuFamily.setValue(procedure_info_family_desc_eu);
					Description descFamily = new Description();
					descFamily.getLanguage().add(langEsFamily);
					descFamily.getLanguage().add(langEuFamily);
					familyName.setDescription(descFamily);
					infoProcedure.setFamilyName(familyName);
				} else {
					try {
						infoProcedure = this.service
								.getSoftConsultationContext(idProcedure);
					} catch (Exception e) {
						InfoProcedureFDCDP.LOGGER.error(
								"cargarInfoProcedures: error al cargarInfoProcedures ",
								e);
					}
				}
				this.procedureInfoMap.put(idProcedure, infoProcedure);
			}

		}
	}

	/**
	 * Devuelve el mapa de informaciones de procedimientos.
	 * 
	 *  Map<String, ConsultationContext>
	 *
	 * @return the procedure info map
	 */
	public Map<String, ConsultationContext> getProcedureInfoMap() {
		if (this.procedureInfoMap == null || this.procedureInfoMap.isEmpty()) {
			try {

				this.cargarInfoProcedures();
			} catch (Exception e) {
				InfoProcedureFDCDP.LOGGER.error(
						"getProcedureInfoMap: error al cargarInfoProcedures ",
						e);
			}
		}

		return this.procedureInfoMap;
	}

	/**
	 * Write procedure info map.
	 * 
	 *  String
	 *
	 * @return the string
	 */
	public String writeProcedureInfoMap() {
		StringBuilder infoProcedures = new StringBuilder();

		if (this.procedureInfoMap != null && this.procedureInfoMap.size() > 0) {
			infoProcedures.append("Informacion de los procedimientos: \n");
			for (String idProcedure : this.procedureInfoMap.keySet()) {
				infoProcedures.append("ID PROCEDURE=").append(idProcedure)
						.append("\n");
				infoProcedures.append("INFO PROCEDURE=").append(
						this.procedureInfoMap.get(idProcedure).toString())
						.append("\n");
			}
		}
		InfoProcedureFDCDP.LOGGER.info(infoProcedures.toString());

		return infoProcedures.toString();
	}

	/**
	 * Devuelve el objeto ConsultationContext con la informacion asociada el
	 * procedimiento cuyo ID se passa como parametro.
	 * 
	 *  procedureId            String
	 *  ConsultationContext
	 *
	 * @param procedureId the procedure id
	 * @return the info procedure
	 */
	public ConsultationContext getInfoProcedure(String procedureId) {
		return this.procedureInfoMap.get(procedureId);
	}
}
