package com.ejie.ab79.service;

import java.util.List;

import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.ejie.ab79.clientesWS.ab61WebService.Ab61Exception;
import com.ejie.ab79.clientesWS.ab61WebService.DocumentoWS;
import com.ejie.ab79.clientesWS.ab61WebService.IdentificadoresPid;
import com.ejie.ab79.clientesWS.ab61WebService.Usuario;
import com.ejie.ab79.comun.Constantes;
import com.ejie.ab79.dao.DocumentosSubidosDao;
import com.ejie.ab79.dao.actuaciones.RelActDocDao;
import com.ejie.ab79.model.DocumentosSubidos;
import com.ejie.ab79.model.actuaciones.Actuaciones;
import com.ejie.ab79.model.actuaciones.RelActDoc;
import com.ejie.ab79.webservice.adaptadores.PIFAdaptador;
import com.ejie.ab79.webservice.adaptadores.ab61WebServiceAdaptador;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * DocumentosSubidosServiceImpl  
 * 
 *  
 */

@Service(value = "documentosSubidosService")
public class DocumentosSubidosServiceImpl implements DocumentosSubidosService {

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

	@Autowired
	private DocumentosSubidosDao documentosSubidosDao;

	@Autowired
	private PIFAdaptador pifAdapterService;

	@Autowired
	private ab61WebServiceAdaptador ab61WebServiceAdaptadorService;

	@Autowired
	private RelActDocDao relActDocDao;

	/**
	 * Inserts a single row in the DocumentosSubidos table.
	 *
	 * @param documentosSubidos
	 *            DocumentosSubidos
	 * @return DocumentosSubidos
	 */
	@Transactional(rollbackFor = Throwable.class)
	public DocumentosSubidos add(DocumentosSubidos documentosSubidos) {
		return this.documentosSubidosDao.add(documentosSubidos);
	}

	/**
	 * Updates a single row in the DocumentosSubidos table.
	 *
	 * @param documentosSubidos
	 *            DocumentosSubidos
	 * @return DocumentosSubidos
	 */
	@Transactional(rollbackFor = Throwable.class)
	public DocumentosSubidos update(DocumentosSubidos documentosSubidos) {
		return this.documentosSubidosDao.update(documentosSubidos);
	}

	/**
	 * Finds a single row in the DocumentosSubidos table.
	 *
	 * @param documentosSubidos
	 *            DocumentosSubidos
	 * @return DocumentosSubidos
	 */
	public DocumentosSubidos find(DocumentosSubidos documentosSubidos) {
		return this.documentosSubidosDao.find(documentosSubidos);
	}

	/**
	 * Deletes a single row in the DocumentosSubidos table.
	 *
	 * @param documentosSubidos
	 *            DocumentosSubidos
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void remove(DocumentosSubidos documentosSubidos) {
		this.documentosSubidosDao.remove(documentosSubidos);
	}

	public List<DocumentosSubidos> findAll(DocumentosSubidos documentosSubidos, TableRequestDto tableRequestDto) {
		return this.documentosSubidosDao.findAll(documentosSubidos, tableRequestDto);
	}

	public List<DocumentosSubidos> findAllLike(DocumentosSubidos documentosSubidos, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.documentosSubidosDao.findAllLike(documentosSubidos, tableRequestDto, startsWith);
	}

	public void removeMultiple(DocumentosSubidos filterDocumentosSubidos, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		this.documentosSubidosDao.removeMultiple(filterDocumentosSubidos, tableRequestDto, startsWith);
	}

	public TableResponseDto<DocumentosSubidos> filter(DocumentosSubidos filterDocumentosSubidos,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		List<DocumentosSubidos> listaDocumentosSubidos = this.documentosSubidosDao.findAllLike(filterDocumentosSubidos,
				tableRequestDto, false);
		Long recordNum = this.documentosSubidosDao.findAllLikeCount(
				filterDocumentosSubidos != null ? filterDocumentosSubidos : new DocumentosSubidos(), false);

		TableResponseDto<DocumentosSubidos> usuarioDto = new TableResponseDto<DocumentosSubidos>(tableRequestDto,
				recordNum, listaDocumentosSubidos);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<DocumentosSubidos>> reorderSelection = this.documentosSubidosDao
					.reorderSelection(filterDocumentosSubidos, tableRequestDto, startsWith);
			usuarioDto.setReorderedSelection(reorderSelection);
			usuarioDto.addAdditionalParam("reorderedSelection", reorderSelection);
			usuarioDto.addAdditionalParam("selectedAll", tableRequestDto.getMultiselection().getSelectedAll());
		}
		if (tableRequestDto.getSeeker().getSelectedIds() != null) {
			tableRequestDto.setMultiselection(tableRequestDto.getSeeker());
			List<TableRowDto<DocumentosSubidos>> reorderSeeker = this.documentosSubidosDao
					.reorderSelection(filterDocumentosSubidos, tableRequestDto, startsWith);
			usuarioDto.setReorderedSeeker(reorderSeeker);
			usuarioDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return usuarioDto;
	}

	@Override
	public TableResponseDto<DocumentosSubidos> filterDocumentacionInspeccion(DocumentosSubidos filterDocumentosSubidos,
			TableRequestDto tableRequestDto, boolean startsWith) {
		List<DocumentosSubidos> listaDocumentosSubidos = this.documentosSubidosDao
				.findDocumentacionInspeccion(filterDocumentosSubidos, tableRequestDto);

		for (DocumentosSubidos documentoSubido : listaDocumentosSubidos) {
			if (documentoSubido.getOidDokusi() != null) {
				documentoSubido.setOidDocumento(documentoSubido.getOidDokusi());
				documentoSubido.setOrigenDocumento(Constantes.ORIGEN_DOKUSI);
			} else {
				documentoSubido.setOidDocumento(documentoSubido.getOidPid());
				documentoSubido.setOrigenDocumento(Constantes.ORIGEN_PID);
			}
		}

		Long recordNum = this.documentosSubidosDao.findDocumentacionInspeccionCount(
				filterDocumentosSubidos != null ? filterDocumentosSubidos : new DocumentosSubidos());

		TableResponseDto<DocumentosSubidos> usuarioDto = new TableResponseDto<DocumentosSubidos>(tableRequestDto,
				recordNum, listaDocumentosSubidos);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<DocumentosSubidos>> reorderSelection = this.documentosSubidosDao
					.reorderSelection(filterDocumentosSubidos, tableRequestDto, startsWith);
			usuarioDto.setReorderedSelection(reorderSelection);
			usuarioDto.addAdditionalParam("reorderedSelection", reorderSelection);
			usuarioDto.addAdditionalParam("selectedAll", tableRequestDto.getMultiselection().getSelectedAll());
		}
		if (tableRequestDto.getSeeker().getSelectedIds() != null) {
			tableRequestDto.setMultiselection(tableRequestDto.getSeeker());
			List<TableRowDto<DocumentosSubidos>> reorderSeeker = this.documentosSubidosDao
					.reorderSelection(filterDocumentosSubidos, tableRequestDto, startsWith);
			usuarioDto.setReorderedSeeker(reorderSeeker);
			usuarioDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return usuarioDto;
	}

	public List<TableRowDto<DocumentosSubidos>> search(DocumentosSubidos filterDocumentosSubidos,
			DocumentosSubidos searchDocumentosSubidos, TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.documentosSubidosDao.search(filterDocumentosSubidos, searchDocumentosSubidos, tableRequestDto,
				startsWith);
	}

	public Object reorderSelection(DocumentosSubidos filterDocumentosSubidos, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.documentosSubidosDao.reorderSelection(filterDocumentosSubidos, tableRequestDto, startsWith);
	}

	public TableResponseDto<JerarquiaDto<DocumentosSubidos>> jerarquia(DocumentosSubidos filterDocumentosSubidos,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		List<JerarquiaDto<DocumentosSubidos>> listaDocumentosSubidos = this.documentosSubidosDao
				.findAllLikeJerarquia(filterDocumentosSubidos, tableRequestDto);
		Long recordNum = this.documentosSubidosDao.findAllLikeCountJerarquia(filterDocumentosSubidos, tableRequestDto);
		return new TableResponseDto<JerarquiaDto<DocumentosSubidos>>(tableRequestDto, recordNum,
				listaDocumentosSubidos);
	}

	public TableResponseDto<JerarquiaDto<DocumentosSubidos>> jerarquiaChildren(
			DocumentosSubidos filterDocumentosSubidos, TableRequestDto tableRequestDto) {
		TableResponseDto<JerarquiaDto<DocumentosSubidos>> tableResponseDto = new TableResponseDto<JerarquiaDto<DocumentosSubidos>>();
		tableResponseDto.addAdditionalParam(TableResponseDto.CHILDREN,
				this.documentosSubidosDao.findAllChild(filterDocumentosSubidos, tableRequestDto));
		return tableResponseDto;
	}

	public List<DocumentosSubidos> getMultiple(DocumentosSubidos filterDocumentosSubidos,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.documentosSubidosDao.getMultiple(filterDocumentosSubidos, tableRequestDto, startsWith);
	}

	@Transactional
	@Override
	public void subidaPidInsertar(DocumentosSubidos documentoSubido, MultipartFile file, Usuario usuario)
			throws Ab61Exception {

		IdentificadoresPid identificadoresPid;
		Integer aportadoExpediente;

		if (documentoSubido.isNoSubirExpediente()) {
			aportadoExpediente = Constantes.APORTADO_EXPEDIENTE_NO_SUBIR;
		} else {
			aportadoExpediente = Constantes.APORTADO_EXPEDIENTE_NO;
		}

		try {
			String pathPif = pifAdapterService.putFileToPID(file.getInputStream(),
					FilenameUtils.getName(file.getOriginalFilename()));

			identificadoresPid = this.ab61WebServiceAdaptadorService.insertarDocumentoPid(pathPif,
					file.getOriginalFilename(), documentoSubido.getPlantilla().getIdPlantilla(),
					file.getOriginalFilename(), aportadoExpediente, Constantes.CODIGO_APLICACION, usuario.getUsuario());
		} catch (Exception e) {
			DocumentosSubidosServiceImpl.logger.error("insertarDocumentoPid - " + e.getMessage(), e);
			throw new Ab61Exception("Ha ocurrido un problema al guardar el documento en el PID.", null);
		}
		DocumentosSubidosServiceImpl.logger.info("Subimos documento al PID - " + identificadoresPid.getOidPid());

		DocumentosSubidosServiceImpl.logger.info("Insertamos RelActDoc");
		RelActDoc relActDoc = new RelActDoc();
		relActDoc.setActuacion(new Actuaciones(documentoSubido.getIdActuacion()));
		relActDoc.setEnviadoProSan(Constantes.ENVIADO_PRO_SAN_NO);
		relActDoc.setUsuarioRegistro(usuario.getUsuario());
		relActDoc.setIdDocumentoSubido(identificadoresPid.getIdDocumentoPid());
		this.relActDocDao.add(relActDoc);
	}

	@Transactional
	@Override
	public String aportarDocumentoActuaciones(List<DocumentoWS> documentosWS, String folderId, String procedureId,
			Usuario usuario) throws Ab61Exception {

		DocumentosSubidosServiceImpl.logger.info("Entrada a aportarDocumentosPlatea");
		try {
			this.ab61WebServiceAdaptadorService.aportarDocumentosPlatea(documentosWS, folderId, procedureId, usuario);
		} catch (Ab61Exception e) {
			String locale = LocaleContextHolder.getLocale().getLanguage();
			if (locale.equalsIgnoreCase(Constantes.CASTELLANO)) {
				return e.getFaultInfo().getMensajeCastellano();
			} else if (locale.equalsIgnoreCase(Constantes.EUSKERA)) {
				return e.getFaultInfo().getMensajeEuskera();
			}

		}
		DocumentosSubidosServiceImpl.logger.info("Fin aportarDocumentosPlatea");

		return "ok";
	}

	public RelActDoc updateEnviadoProSan(RelActDoc relActDoc) {
		return this.relActDocDao.updateEnviadoProSan(relActDoc);
	}

}
