package com.ejie.ab04b.service.platea;

import java.util.List;
import java.util.Locale;

import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;

import com.ejie.ab04b.constantes.Constantes;
import com.ejie.ab04b.constantes.ConstantesPlateaTramitacion;
import com.ejie.ab04b.model.Buzon;
import com.ejie.ab04b.model.ComunicacionProcedimiento;
import com.ejie.ab04b.model.DatosAviso;
import com.ejie.ab04b.model.DocumentoOS3;
import com.ejie.ab04b.model.OS3;
import com.ejie.ab04b.util.DokusiUtils;
import com.ejie.ab04b.util.PPSUtils;
import com.ejie.ab04b.util.ToolkitUtils;
import com.ejie.ab04b.util.Utilities;
import com.ejie.ab04b.util.ValidadorNifCifNie;
import com.ejie.ab04b.util.seguridad.UtilSeguridad;
import com.ejie.ctfm.xml.Addressee;
import com.ejie.ctfm.xml.ApplicantInfo;
import com.ejie.ctfm.xml.Channel;
import com.ejie.ctfm.xml.Contact;
import com.ejie.ctfm.xml.Contacts;
import com.ejie.ctfm.xml.ContextSubmission;
import com.ejie.ctfm.xml.Document;
import com.ejie.ctfm.xml.Documents;
import com.ejie.ctfm.xml.Notification;
import com.ejie.ctfm.xml.Person;
import com.ejie.ctfm.xml.Persons;
import com.ejie.platea.generic.xml.RoleName;
import com.ejie.platea.generic.xml.Value;

/**
 * @author GFI-NORTE
 * 
 */
@Service(value = "ppsAportacionOS3Service")
public class PPSAportacionOS3Service extends PPSService {

	/**
	 * esSubsanacion boolean os3 OS3 listaDocumentos List<DocumentoOS3>
	 * ContextSubmission.
	 * 
	 * @param esSubsanacion
	 *            the es subsanacion
	 * @param os3
	 *            the os 3
	 * @param listaDocumentos
	 *            the lista documentos
	 * @return the context submission
	 */
	public ContextSubmission crearContextSubmission(boolean esSubsanacion,
			OS3 os3, List<DocumentoOS3> listaDocumentos) {

		ContextSubmission ctxSubmission = null;

		String procedureId = Utilities.getInstance().obtenerProcedureIdOs2();

		ctxSubmission = this.crearContextSubmission(procedureId);

		// Buzón
		Buzon buzon = this.getBuzonService().obtenerBuzon(procedureId,
				os3.getTeros3061());
		ctxSubmission.setMailbox(buzon.getMailbox076());
		ctxSubmission.setProcedureInboxID(buzon.getMailbox076());
		ctxSubmission.setProcedureInboxName(buzon.getMailbox076());

		// datos de registro
		if (Constantes.VALUE_NO.equals(os3.getDeseaRegistrar061())) {
			ctxSubmission.setMustRegistry(Constantes.VALUE_NO);
			ctxSubmission.setRegistryNumber(os3.getNumReg061());
			ctxSubmission.setRegistryTimestamp(Utilities.getInstance()
					.dateToStringPPS(os3.getFecReg061()));
		}

		// sender y registrySender
		this.addContextSubmissionFromSolicitante(ctxSubmission, os3);

		if (esSubsanacion) {
			// submissionType y submissionTypeName
			ctxSubmission
					.setSubmissionType(ConstantesPlateaTramitacion.SUBMISSIONTYPE_APORT_SUBSANA);
		} else {
			// submissionType y submissionTypeName
			ctxSubmission
					.setSubmissionType(ConstantesPlateaTramitacion.SUBMISSIONTYPE_APORT_PRESEN);
		}
		ctxSubmission
				.setSubmissionTypeName(PPSUtils
						.getInstance()
						.construirPlateaDescription(
								this.getAppMessageSource()
										.getMessage(
												ConstantesPlateaTramitacion.SUBMISSIONTYPE_DESC_PREFIX
														.concat(ctxSubmission
																.getSubmissionType()),
												null, Constantes.LOCALE_ES),
								this.getAppMessageSource()
										.getMessage(
												ConstantesPlateaTramitacion.SUBMISSIONTYPE_DESC_PREFIX
														.concat(ctxSubmission
																.getSubmissionType()),
												null, Constantes.LOCALE_EU)));

		// applicantInfo
		ctxSubmission.setApplicantInfo(this.getApplicantInfoContextSubmission(
				os3, LocaleContextHolder.getLocale()));

		// documentos
		ctxSubmission.setDaDocumentalSeries(this.obtenerSerieDocumental(os3));
		ctxSubmission.setDocuments(this.getXmlDocumentsContextSubmission(
				listaDocumentos, os3));

		ctxSubmission.setFolderID(os3.getFolderId061());

		return ctxSubmission;

	}

	/**
	 * Agrega al objeto ContextSubmission la informacion de registrySenderid,
	 * registrySenderName, senderId y senderName. Esta informacion depende del
	 * solicitante
	 * 
	 * ctxSubmission ContextSubmission comunicacion ComunicacionProcedimiento
	 * 
	 * @param ctxSubmission
	 *            the ctx submission
	 * @param comunicacion
	 *            the comunicacion
	 */
	@Override()
	protected void addContextSubmissionFromSolicitante(
			ContextSubmission ctxSubmission,
			ComunicacionProcedimiento comunicacion) {

		OS3 os3 = (OS3) comunicacion;

		// TODO sacar bien los datos del solicitante
		ctxSubmission.setSenderID(os3.getNumdoc061());
		ctxSubmission.setSenderName(os3.getNomemp061());
		// ctxSubmission.setSenderType("1"); // 1-TITULAR 2-REPRESENTANTE
		ctxSubmission.setRegistrySenderID(UtilSeguridad.getInstance()
				.getUserCredentials().getPosition());
		ctxSubmission.setRegistrySenderName(UtilSeguridad.getInstance()
				.getNombre());
	}

	/**
	 * Crea el apartado applicantInfo del contextSubmission de una solicitud
	 * 
	 * comunicacion ComunicacionProcedimiento locale Locale con el idioma
	 * seleccionado en la aplicacion ApplicantInfo.
	 * 
	 * @param comunicacion
	 *            the comunicacion
	 * @param locale
	 *            the locale
	 * @return the applicant info context submission
	 */
	@Override()
	protected ApplicantInfo getApplicantInfoContextSubmission(
			ComunicacionProcedimiento comunicacion, Locale locale) {

		OS3 os3 = (OS3) comunicacion;

		ApplicantInfo appInfo = new ApplicantInfo();
		appInfo.setNotification(this.getNotificationApplicantInfo(os3));
		appInfo.setPersons(this.getPersonasContextSubmission(os3));
		// TODO obtener los datos reales del solicitante
		appInfo.setNotices(PPSUtils.getInstance().getNoticesApplicantInfo(
				os3.getNumdoc061(), os3.getNomemp061(),
				os3.getDatosNotificacion().getListaDatosAviso()));

		appInfo.setLanguage(locale.getLanguage());

		return appInfo;
	}

	/**
	 * Devuelve la informacion de Notification de la parte ApplicantInfo para
	 * una solicitud
	 * 
	 * os3 OS3
	 * 
	 * Notification.
	 * 
	 * @param os3
	 *            the os 3
	 * @return the notification applicant info
	 */

	private Notification getNotificationApplicantInfo(OS3 os3) {
		Notification notif = new Notification();

		Addressee addressee = new Addressee();

		// TODO obtener bien los datos del solicitante
		addressee.setAddresseeID(os3.getNumdoc061());
		addressee.setAddresseeName(os3.getNomemp061());

		notif.setAddressee(addressee);

		Channel channel = PPSUtils.getInstance().construirChannel(
				os3.getDatosNotificacion());
		if (channel.getChannelType() != null) {
			notif.setChannel(channel);
		} else {
			// Si no hay datos de notificación porque es una aportación,
			// ponemos
			// todo el objeto Notification a null
			notif = null;
		}

		return notif;
	}

	/**
	 * Devuelve un objeto Persons que representa la informacion de la/s
	 * persona/s de la solicitud
	 * 
	 * os3 OS3 Persons.
	 * 
	 * @param os3
	 *            the os 3
	 * @return the personas context submission
	 */
	private Persons getPersonasContextSubmission(OS3 os3) {

		Persons persons = new Persons();
		persons.getPerson().add(this.getPersona(os3));
		return persons;

	}

	/**
	 * Devuelve un objeto Person para el ContextSubmission
	 * 
	 * os3 OS3 Person.
	 * 
	 * @param os3
	 *            the os 3
	 * @return the persona
	 */
	private Person getPersona(OS3 os3) {

		Person person = new Person();

		if (null != os3) {
			// TODO obtener los datos reales del solicitante
			person.setId(os3.getNumdoc061());
			person.setName(os3.getNomemp061());

			String tipoPersona = null;
			if (os3 != null) {
				// TODO obtener los datos reales del solicitante
				if (ValidadorNifCifNie.checkCif(os3.getNumdoc061())) {
					tipoPersona = ConstantesPlateaTramitacion.CS_PERSONTYPE_JURIDICA;
				} else {
					tipoPersona = ConstantesPlateaTramitacion.CS_PERSONTYPE_FISICA;
				}
			}
			person.setPersonType(tipoPersona);

			person.setHolderShip(ConstantesPlateaTramitacion.CS_HOLDERSHIP_HOLDER);

			// se refiere a telefono o fax de una persona
			Contacts contacts = new Contacts();
			if (os3.getDatosNotificacion().getListaDatosAviso() != null) {
				com.ejie.platea.generic.xml.ObjectFactory of = new com.ejie.platea.generic.xml.ObjectFactory();
				for (DatosAviso datosAviso : os3.getDatosNotificacion()
						.getListaDatosAviso()) {
					Contact contact = new Contact();
					if (Constantes.CANAL_AVISO_SMS.equals(datosAviso
							.getTipo068())) {
						contact.setType(ConstantesPlateaTramitacion.CS_CONTACTTYPE_PHONE);
						Value value = new Value();
						value.getContent().add(
								of.createPhoneNumber(datosAviso.getValor068()));
						contact.setValue(value);
						contacts.getContact().add(contact);
					}
				}
			}
			person.setContacts(contacts);
		}

		return person;
	}

	/**
	 * Devuelve la parte documents que representa la informacion de una lista de
	 * documentos en el ConxtextSubmission. Uno de esos documentos siempre sera
	 * el propio ejgvDocument, del que viene la firma pasada como parametro.
	 * signerId y signerName son los datos del firmante del ejgvDocument, que
	 * son necesarios para la firma
	 * 
	 * listaDocumentos Lista de elementos SolicDocumentos os3 OS3
	 * 
	 * String con un trozo XML con la estructura deseada
	 * 
	 * @param listaDocumentos
	 *            the lista documentos
	 * @param os3
	 *            the os 3
	 * @return the xml documents context submission
	 */
	public Documents getXmlDocumentsContextSubmission(
			List<DocumentoOS3> listaDocumentos, OS3 os3) {

		Documents documents = new Documents();
		Document document = null;

		if (listaDocumentos != null && listaDocumentos.size() > 0) {
			RoleName roleName = null;
			DocumentoOS3 doc = null;
			for (int i = 0; i < listaDocumentos.size(); i++) {
				doc = listaDocumentos.get(i);
				if (doc.getRutaPif097() != null) {
					document = new Document(); // NOPMD hay que crear el objeto
					document.setDocumentType(ConstantesPlateaTramitacion.DOCUMENT_TYPE_YAEXISTE_DOKUSI);
					document.setFormat(ConstantesPlateaTramitacion.DOCUMENT_FORMAT_ELECTRONICO);
					document.setOid(doc.getOidDokusi097());
					document.setRoleId(doc.getTipoDocumento()
							.getTipoDocumentalCompleto());
					roleName = new RoleName(); // NOPMD hay que crear
												// el objeto
					roleName.setDescription(PPSUtils.getInstance()
							.construirPlateaDescription(
									doc.getTipoDocumento()
											.getDescripcionEs091(),
									doc.getTipoDocumento()
											.getDescripcionEu091()));
					document.setRoleName(roleName);
					document.setSourceName(doc.getNombreDoc097());
					document.setExtension(new StringBuilder(
							Constantes.SEPARADOR_PUNTO).append(
							Utilities.getInstance().obtenerExtensionFichero(
									doc.getNombreDoc097())).toString());
					// document.setOid(doc.getOidDokusi097());
					document.setLocation(doc.getOidDokusi097());
				}

				documents.getDocument().add(document);
			}

		}
		return documents;
	}

	/**
	 * os3 OS3 String.
	 * 
	 * @param os3
	 *            the os 3
	 * @return the string
	 */
	private String obtenerSerieDocumental(OS3 os3) {
		String codTerritorio = ToolkitUtils.getInstance()
				.obtenerTerritorioSolicitudOS3(os3);
		return DokusiUtils.getInstance()
				.obtenerSerieDocumentalOS(codTerritorio);
	}

}
