/**
 * 
 */
package com.ejie.ad74a.util.mappers;

import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ejie.ad74a.model.Ayuntamiento;
import com.ejie.ad74a.model.ConfigSipca;
import com.ejie.ad74a.model.FacturacionAyuntamiento;
import com.ejie.ad74a.model.Liquidacion;
import com.ejie.ad74a.model.Periodo;
import com.ejie.ad74a.model.Solicitante;
import com.ejie.ad74a.model.TipoIngreso;
import com.ejie.ad74a.util.UtilDates;
import com.ejie.ad74a.util.UtilLiquidaciones;

/**
 * Mapper liquidaciones
 * 
 * @author BICUGUAL
 *
 */
public class LiquidacionMapper {

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

	private int diasLimPag;
	private ConfigSipca confSipca;

	public static LiquidacionMapper getInstace(ConfigSipca confSipca, int diasLimPag) {
		return new LiquidacionMapper(confSipca, diasLimPag);
	}

	public LiquidacionMapper(ConfigSipca confSipca, int diasLimPag) {
		super();
		this.diasLimPag = diasLimPag;
		this.confSipca = confSipca;
	}

	/**
	 * Mapea los datos de los solicitantes con mensualidad a Liquidaciones.
	 * 
	 * @param lstSolicitantesConMensualidad
	 * @param cargoMensual
	 * @return
	 */
	public List<Liquidacion> lstSolicitantesToLiquidaciones(List<Solicitante> lstSolicitantesConMensualidad,
			boolean relanzamiento) {

		return lstSolicitantesConMensualidad.stream().map(solicitante -> {

			Periodo mensualidad = new Periodo(solicitante.getAnyoMesMensualidad());

			int anioActual = LocalDate.now().getYear();

			Liquidacion liquidacion = new Liquidacion();
			liquidacion.setEjercicio(anioActual);
			liquidacion.setIdTipoIngreso(TipoIngreso.TLCOP);
			/*
			 * [jbhg] Al generar en modo prueba los registros en la tabla espejo, el campo
			 * "idMensualidad" puede llegar a null. Se modifica el método ".toString()" por
			 * un "String.valueOf" que es null-safe...
			 */
			liquidacion.setCodOrigen(String.valueOf(solicitante.getIdMensualidad()));
			liquidacion.setImporte(solicitante.getImporte());
			liquidacion.setfEmision(UtilDates.getFechaSistema());
			liquidacion.setfLimitePago(UtilDates.formatLocalDateToDate(LocalDate.now().plusDays(diasLimPag)));
			liquidacion.setIdTerritorio(UtilLiquidaciones.getIdTerritorio(solicitante.getIdProvincia().toString()));
			liquidacion.setExpediente(solicitante.getNumAbonado());

			String mesStr = mensualidad.getfInicio().getMonth().getDisplayName(TextStyle.FULL, new Locale("es", "ES"));
			liquidacion.setConcepto("Teleasistencia " + mesStr + " " + mensualidad.getfInicio().getYear());
			liquidacion.setTipoTercero(UtilLiquidaciones.getTipoTercero(solicitante.getCodTipoIdenTitular()));
			liquidacion.setTercero(solicitante.getIdenTitular());
			liquidacion.setNomRacSoc(null != solicitante.getNombreTitCuenta()
					? StringUtils.substring(solicitante.getNombreTitCuenta(), 0, 40)
					: null);
			liquidacion.setApellido1(solicitante.getApellido1TitCuenta());
			liquidacion.setApellido2(solicitante.getApellido2TitCuenta());
			liquidacion.setIndDomic(1);
			liquidacion.setIban(solicitante.getNumCuenta());
			liquidacion.setfMandato(UtilDates.formatLocalDateToDate(solicitante.getfInicio()));
			liquidacion.setfCargo(UtilDates.formatLocalDateToDate(LocalDate.now().plusDays(confSipca.getDiasCargo())));
			liquidacion.setEstadoLiq(1);
			liquidacion.setMandato(
					null == solicitante.getMandato() ? liquidacion.getExpediente() + liquidacion.getTercero()
							: solicitante.getMandato());

			logger.debug("Liquidacion: {}", liquidacion);

			return liquidacion;
		}).collect(Collectors.toList());

	}

	public Liquidacion facturacionAytoToLiquidacion(FacturacionAyuntamiento factura, Ayuntamiento ayto,
			boolean relanzamiento) {
		Liquidacion liquidacion = new Liquidacion();

		liquidacion.setEjercicio(relanzamiento ? LocalDate.now().getYear() : factura.getAnyoHasta());
		liquidacion.setIdTipoIngreso(TipoIngreso.TLAYT);
		liquidacion.setCodOrigen(factura.getIdFacturacion().toString());
		liquidacion.setImporte(factura.getImporteFacturado());

		// Si el año hasta < año actual 31/diciembre
		Date fEmision = factura.getAnyoHasta().compareTo(LocalDate.now().getYear()) < 0 ? new Date()
				: UtilDates.formatLocalDateToDate(LocalDate.of(factura.getAnyoHasta(), 12, 31));

		liquidacion.setfEmision(fEmision);
		liquidacion.setfLimitePago(UtilDates.formatLocalDateToDate(LocalDate.now().plusDays(diasLimPag)));
		liquidacion.setIdTerritorio(Integer.valueOf(ayto.getIdProvincia()));
		liquidacion.setExpediente(factura.getReferenciaRecibo());
		liquidacion.setConcepto("Teleasistencia " + UtilDates.formatNMesToUpperCaseText(factura.getMesDesde()) + " - "
				+ UtilDates.formatNMesToUpperCaseText(factura.getMesHasta()) + " " + factura.getAnyoHasta().toString());
		liquidacion.setTipoTercero(Integer.valueOf(1));
		liquidacion.setTercero(ayto.getCif());
		liquidacion.setNomRacSoc(null != ayto.getDescEs() ? StringUtils.substring(ayto.getDescEs(), 0, 40) : "NULL");
		// Por ahora mandamos 1, cuando se desarrollo el tema de codigo de barras
		// cambiar
		liquidacion.setIndDomic(1);
		liquidacion.setIban(ayto.getNumCuenta());
		liquidacion.setfMandato(ayto.getfAutorizacion());
		liquidacion.setfCargo(Integer.valueOf(2).compareTo(ayto.getFormaPago()) == 0
				? UtilDates.formatLocalDateToDate(LocalDate.now().plusDays(confSipca.getDiasCargo()))
				: null);
		liquidacion.setEstadoLiq(1);
		// Dejamos vacio
		liquidacion.setMandato(null);

		// COD_PROVINCIA
		// COD_MUNICIPIO
		// CP_31 --> COD_COD_POSTAL_00
		// RESIDENTE_00 = 1
		// DIRECCION_31 --> NOMBRE_VIA_00 (CON Substring)
		// if FORMA_PAGO_31 == 2 ? NUM_CUENTA_31--> IBAN_00 : null
		// if FORMA_PAGO_31 == 2 ? F_AUTORIZACION_31 --> F_MANDATO_00 : null

		logger.debug("Liquidacion: {}", liquidacion);

		return liquidacion;
	}

}
