package com.ejie.ad74a.service.impl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

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

import com.ejie.ad74a.dao.SolicitantesDao;
import com.ejie.ad74a.model.Ad74aBeneficiarioDFBBean;
import com.ejie.ad74a.service.BenDiputacionesService;
import com.ejie.ad74a.util.Ad74aUtilPif;
import com.ejie.ad74a.util.UtilDates;
import com.ejie.ad74a.util.UtilProperties;
import com.ejie.ad74a.util.constantes.ConstantesBatch;

/**
 * 
 * @author IHERNANG
 */

@Service(value = "benDiputacionesService")
public class BenDiputacionesServiceImpl implements BenDiputacionesService {

	private static final String DATEFORMAT_YYYY_MM_DD_HH_MM_SS_S = "yyyy-MM-dd HH:mm:ss.S";

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

	@Autowired
	private SolicitantesDao solicitantesDao;

	public void generarXMLBeneficiarios(String provincia) throws Exception {


		StringBuilder xmlGVtoDF = new StringBuilder();

		// METEMOS CABECERA
		xmlGVtoDF.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n");
		xmlGVtoDF.append("<" + ConstantesBatch.TAG_ANIDA_GV_TO_DFB + ">\n");
		// BENEFICIARIOS
		xmlGVtoDF.append("<" + ConstantesBatch.TAG_BENEFICIARIOS_GV_TO_DFB + ">\n");
		xmlGVtoDF.append(this.obtenerBeneficiariosTodas(provincia));

		// Procesar los beneficiarios para ir generando el xml correspondiente

		xmlGVtoDF.append("</" + ConstantesBatch.TAG_BENEFICIARIOS_GV_TO_DFB + ">\n");
		xmlGVtoDF.append("</" + ConstantesBatch.TAG_ANIDA_GV_TO_DFB + ">\n");

		String rutaEnvio = "";
		String rutaPif = "";
		if (ConstantesBatch.PROV_ALAVA.equals(provincia)) {
			Files.createDirectories(Paths.get(UtilProperties.Props.RUTA_DFA_ENVIO.val()));
			rutaEnvio = UtilProperties.Props.RUTA_DFA_ENVIO.val();
			rutaPif = UtilProperties.Props.RUTA_DFA_PIF.val();
		} else if (ConstantesBatch.PROV_VIZCAYA.equals(provincia)) {
			Files.createDirectories(Paths.get(UtilProperties.Props.RUTA_DFB_ENVIO.val()));
			rutaEnvio = UtilProperties.Props.RUTA_DFB_ENVIO.val();
			rutaPif = UtilProperties.Props.RUTA_DFB_PIF.val();
		} else if (ConstantesBatch.PROV_GUIPUZCOA.equals(provincia)) {
			Files.createDirectories(Paths.get(UtilProperties.Props.RUTA_DFG_ENVIO.val()));
			rutaEnvio = UtilProperties.Props.RUTA_DFG_ENVIO.val();
			rutaPif = UtilProperties.Props.RUTA_DFG_PIF.val();
		}
		// Se deja el archivo generado en /envio
		String nombre = "beneficiarios" + UtilDates.formatLocalDateToString(LocalDate.now(), "yyyyMMdd");
		this.crearFichero(xmlGVtoDF.toString(), rutaEnvio, nombre);

		String nombreFich = rutaEnvio + nombre;
		//Se comenta el proceso de comprimido porque es necesario que el fichero se deje en formato XML para su proceso
		//Mantis 0274564
		//this.comprime(nombreFich+".xml",nombreFich + ".zip" );		
		// Subir a pif
		// Primero se inicia
		Ad74aUtilPif.init(UtilProperties.Props.PIF_API_COMMAND.val());

		// Se sube el fichero comprimido al PIF
		//Ad74aUtilPif.put(UtilProperties.Props.LOGIN_PIF.val(), nombreFich + ".zip", rutaPif + nombre + ".zip");
		Ad74aUtilPif.put(UtilProperties.Props.LOGIN_PIF.val(), nombreFich+ ".xml", rutaPif+nombre+ ".xml");

		// una vez que hemos enviado el xml lo borramos
		//this.eliminarFichero(nombreFich + ".xml");
		logger.info("fin del proceso");

	}

	/**
	 * Crear fichero inf beneficiario.
	 *
	 * @param contenido     the contenido
	 * @param nombreFichero the nombre fichero
	 */
	private void crearFichero(String contenido, String ruta, String nombreFichero) {
		File fOtros = null;
		String sourcePathFich = ruta + nombreFichero + ".xml";
		logger.info("Fichero:  {}", sourcePathFich);
		fOtros = new File(sourcePathFich);
		try (OutputStream outFich = new FileOutputStream(fOtros, true)) {
			outFich.write(contenido.getBytes());
		} catch (Exception e) {
			logger.error("Se ha producido un error al crear el fichero", e);
		}
	}

	private void comprime(String ficheroAComprimir, String ficheroComprimido) throws IOException {
		final int BUFFER = 2048;
		// obtenemos la lista de los archivos del directorio actual
		File f = new File(ficheroAComprimir);
		if (f.exists()) {
			String pathFichero = f.getAbsolutePath();
			String nombreFichero = f.getName();

			try (FileOutputStream dest = new FileOutputStream(ficheroComprimido);
					ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
					FileInputStream fi = new FileInputStream(pathFichero);
					BufferedInputStream origin = new BufferedInputStream(fi, BUFFER)) {
				byte[] data = new byte[BUFFER];
				ZipEntry entry = new ZipEntry(nombreFichero);
				out.putNextEntry(entry);
				int count;
				while ((count = origin.read(data, 0, BUFFER)) != -1) {
					out.write(data, 0, count);
				}
			}
		}

	}

	/**
	 * eliminarFichero fichero inf beneficiario.
	 *
	 * @param nombreFichero the nombre fichero
	 */
	private void eliminarFichero(String nombreFichero) {
		try {
			logger.info("eliminar fichero: {}", nombreFichero);
			File fichero = new File(nombreFichero);
			Files.delete(fichero.toPath());
			logger.info("fichero eliminado: {}", nombreFichero);
		} catch (Exception e) {
			logger.info("Se ha producido un error al eliminar el fichero ", e);
		}
	}

	/**
	 * Devuelve un XML con los beneficiarios para la DFA.
	 * 
	 * @return the result xml response
	 */
	public String obtenerBeneficiariosTodas(String provincia) {
		logger.info("BenDiputacionesServiceImpl -> obtenerBeneficiariosTodas: Entramos en obtenerBeneficiariosTodas()");
		StringBuilder xmlBeneficiarios = new StringBuilder();
		try {
			List<Ad74aBeneficiarioDFBBean> listBeneBean = this.solicitantesDao.findBeneficiariosDDFF(provincia);
			for (int i = 0; i < listBeneBean.size(); i++) {
				xmlBeneficiarios.append(beneBeanToXML(listBeneBean.get(i)));
			}
		} catch (Exception e) {
			logger.error("Error en obtenerBeneficiariosTodas", e);
		}

		return xmlBeneficiarios.toString();
	}

	private String beneBeanToXML(Ad74aBeneficiarioDFBBean beneBean) {

		StringBuilder xmlBeneficiario = new StringBuilder();
		String fechaApertura = UtilDates.formatDateToString(beneBean.getFapertura(), DATEFORMAT_YYYY_MM_DD_HH_MM_SS_S);
		String fechaBeneficiario = UtilDates.formatDateToString(beneBean.getFbeneficiario(),
				DATEFORMAT_YYYY_MM_DD_HH_MM_SS_S);
		String fechaBaja = UtilDates.formatDateToString(beneBean.getFbaja(), DATEFORMAT_YYYY_MM_DD_HH_MM_SS_S);

		xmlBeneficiario.append("<" + ConstantesBatch.TAG_BENEFICIARIO_GV_TO_DFB + ">");
		xmlBeneficiario.append("<" + ConstantesBatch.TAG_DNI_NIE_GV_TO_DFB + ">" + beneBean.getIdentificador() + "</"
				+ ConstantesBatch.TAG_DNI_NIE_GV_TO_DFB + ">\n");
		xmlBeneficiario.append("<" + ConstantesBatch.TAG_NOMBRE_GV_TO_DFB + ">" + beneBean.getNombre() + "</"
				+ ConstantesBatch.TAG_NOMBRE_GV_TO_DFB + ">\n");
		xmlBeneficiario.append("<" + ConstantesBatch.TAG_APEL1_GV_TO_DFB + ">" + beneBean.getApellido1() + "</"
				+ ConstantesBatch.TAG_APEL1_GV_TO_DFB + ">\n");
		xmlBeneficiario.append("<" + ConstantesBatch.TAG_APEL2_GV_TO_DFB + ">" + beneBean.getApellido2() + "</"
				+ ConstantesBatch.TAG_APEL2_GV_TO_DFB + ">\n");

		if (fechaApertura != null) {
			xmlBeneficiario.append("<" + ConstantesBatch.TAG_FECHSOL_GV_TO_DFB + ">" + fechaApertura + "</"
					+ ConstantesBatch.TAG_FECHSOL_GV_TO_DFB + ">\n");
		} else {
			xmlBeneficiario.append("<" + ConstantesBatch.TAG_FECHSOL_GV_TO_DFB + "/>\n");
		}

		if (fechaBeneficiario != null) {
			xmlBeneficiario.append("<" + ConstantesBatch.TAG_FECHALTA_GV_TO_DFB + ">" + fechaBeneficiario + "</"
					+ ConstantesBatch.TAG_FECHALTA_GV_TO_DFB + ">\n");
		} else {
			xmlBeneficiario.append("<" + ConstantesBatch.TAG_FECHALTA_GV_TO_DFB + "/>\n");
		}

		if (fechaBaja != null) {
			xmlBeneficiario.append("<" + ConstantesBatch.TAG_FECHBAJA_GV_TO_DFB + ">" + fechaBaja + "</"
					+ ConstantesBatch.TAG_FECHBAJA_GV_TO_DFB + ">\n");
		}

		if (beneBean.getIdMotivoBaja() != null) {
			xmlBeneficiario.append("<" + ConstantesBatch.TAG_MOTBAJA_GV_TO_DFB + ">" + beneBean.getIdMotivoBaja() + "</"
					+ ConstantesBatch.TAG_MOTBAJA_GV_TO_DFB + ">\n");
		}
		xmlBeneficiario.append("<" + ConstantesBatch.TAG_COPAGO_TO_DFB + ">" + beneBean.getPrecioPublico() + "</"
				+ ConstantesBatch.TAG_COPAGO_TO_DFB + ">\n");
		xmlBeneficiario.append(
				"<" + ConstantesBatch.TAG_AVANZADA_TO_DFB + ">false</" + ConstantesBatch.TAG_AVANZADA_TO_DFB + ">\n");
		xmlBeneficiario.append("</" + ConstantesBatch.TAG_BENEFICIARIO_GV_TO_DFB + ">\n");

		return xmlBeneficiario.toString();
	}
}
