package com.dla.dda.transforms;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dla.dda.domain.contrato.FeesFlat;
import com.dla.dda.domain.contrato.FeesSuscriptor;
import com.dla.dda.domain.contrato.PeriodoFlat;
import com.dla.dda.domain.contrato.Rango;
import com.dla.dda.persistence.model.DdaTContratoPago;
import com.dla.dda.persistence.model.DdaTContratoPagoCateg;
import com.dla.dda.persistence.model.DdaTContratoPagoCosto;
import com.dla.dda.persistence.model.DdaTContratoPagoFlat;
import com.dla.dda.persistence.model.DdaTContratoPagoRango;

/**
 * @see Transforsm para los fees de suscriptores
 * @author montieln
 *
 */
public class FeesTransform {

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

	/**
	 * @see Transformador que entrega el mapa de los periodos de suscripcion,
	 *      revisar si se debe meter los ids
	 * @param pagoRango
	 * @param pagoCosto
	 * @param pagoCateg
	 * @return
	 */
	public static Map<String, Rango> transform(DdaTContratoPagoRango pagoRango, DdaTContratoPagoCosto pagoCosto,
			DdaTContratoPagoCateg pagoCateg) {

		// TODO revisar si se debe meter los ids para la parte de la migracion
		Map<String, Rango> periodo = new HashMap<>();

		String desde = pagoRango.getDesde();
		String hasta = pagoRango.getHasta();

		String costo = pagoCosto.getCosto();

		String categoria = pagoCateg.getDescCategoria();

		logger.info(" [{}] [{}] [{}] [{}]", categoria, desde, hasta, costo);

		Rango rango = new Rango();
		rango.setDesde(Integer.valueOf(desde));
		rango.setHasta(Integer.valueOf(hasta));
		rango.setValor(Double.valueOf(costo));

		// Agregamos al listado del mapa
		periodo.put(categoria, rango);

		return periodo;
	}

	/**
	 * @see transformacion de periodos de flat
	 * @param pagoRango
	 * @param pagoCosto
	 * @return
	 */
	public static Map<String, List<PeriodoFlat>> transform(DdaTContratoPagoFlat pagoRango,
			DdaTContratoPagoCateg pagoCosto) {

		// La llave valor de las categorias
		Map<String, List<PeriodoFlat>> categoria = new HashMap<>();

		// Obtenemos todos los periodos
		List<PeriodoFlat> periodos = new ArrayList<>();

		// este no se usa
		// Integer anio = (int) pagoRango.getAnnio();
		String costo = pagoRango.getCosto();

		String categoriaKey = pagoCosto.getDescCategoria();

		PeriodoFlat flat = new PeriodoFlat();

		if (costo != null)
			flat.setValor(Double.valueOf(costo));

		periodos.add(flat);

		categoria.put(categoriaKey, periodos);

		return categoria;
	}

	/**
	 * @see transformacion de los bonos de flat
	 * @param bono
	 * @param rango
	 * @return
	 */
/*	public static Map<String, List<Rango>> transform(DdaTContratoPagoBono bono, DdaTContratoBonoRango rango) {

		Map<String, List<Rango>> bonos = new HashMap<>();

		String periodoInicio = bono.getAnnioInicio();

		String bonoStr = rango.getBono();
		String desde = rango.getDesde();
		String hasta = rango.getHasta();

		Rango rangoDDA = new Rango();
		// Setters/getters
		rangoDDA.setDesde(Integer.valueOf(desde));
		rangoDDA.setHasta(Integer.valueOf(hasta));
		rangoDDA.setValor(Integer.valueOf(bonoStr));

		List<Rango> rangos = new ArrayList<>();
		rangos.add(rangoDDA);

		bonos.put(periodoInicio, rangos);

		return bonos;
	}*/

	/**
	 * @see abrega el nuevo periodo a la lista de categorias, verifica si existe
	 *      la categoria, si existe lo agrega a su lista, de lo contrario crea
	 *      una nueva lista
	 * @param periodo
	 * @param periodos
	 */
	public static void addPeriodoSuscripcion(Map<String, Rango> periodo, Map<String, List<Rango>> periodos) {

		// 1. revisamos si ya existe la categoria
		Set<String> keys = periodo.keySet();

		for (String categoriaKey : keys) {

			// Este es el total
			List<Rango> rangoPeriodos = periodos.get(categoriaKey);

			// es la entidad a agregar
			Rango rangoEntity = periodo.get(categoriaKey);

			// 1. Si existe se agrega el elemento nuevo
			if (rangoPeriodos != null) {
				// Lo agregamos al listado de rangos de la categoria
				rangoPeriodos.add(rangoEntity);
				// Lo agregamos a su mapa de la categoria
				periodos.put(categoriaKey, rangoPeriodos);
			} else {
				// Es nueva la categoria y creamos su listado de rangos
				List<Rango> rangoPeriodoNew = new ArrayList<>();
				rangoPeriodoNew.add(rangoEntity);
				// Agregamos la nueva categoria
				periodos.put(categoriaKey, rangoPeriodoNew);
			}

		}

	}

	public static FeesSuscriptor adapt(DdaTContratoPago pago, Map<String, List<Rango>> periodosSuscripcion) {

		FeesSuscriptor suscriptor = new FeesSuscriptor();

		suscriptor.setFechaFin(pago.getFechaFin());
		suscriptor.setFechaInicio(pago.getFechaInicio());
		suscriptor.setIdTipoSuscriptor(pago.getIdTipoSuscriptor());
		suscriptor.setPeriodos(periodosSuscripcion);

		return suscriptor;

	}

	public static void adaptPeriodosFlatFees(Map<String, List<PeriodoFlat>> periodosFlatCompletos,
			DdaTContratoPago pago, Map<String, List<PeriodoFlat>> periodosFlat) {

		if (periodosFlat != null)
			for (Map.Entry<String, List<PeriodoFlat>> entry : periodosFlat.entrySet()) {
				String categoria = entry.getKey();
				List<PeriodoFlat> periodosFlatFees = entry.getValue();

				for (PeriodoFlat periodo : periodosFlatFees) {
					periodo.setFechaFin(pago.getFechaFin());
					periodo.setFechaInicio(pago.getFechaInicio());
				}

				List<PeriodoFlat> periodoFlat = periodosFlatCompletos.get(categoria);

				if (periodoFlat == null)
					periodoFlat = new ArrayList<PeriodoFlat>();

				periodoFlat.addAll(periodosFlatFees);
				periodosFlatCompletos.put(categoria, periodoFlat);
			}

	}

	/**
	 * @see metodo que adapta los periodos del fees del flat
	 * @param pago
	 * @param periodos
	 * @return
	 */
	public static FeesFlat adaptPeridosFlatFees(DdaTContratoPago pago, Map<String, List<PeriodoFlat>> periodos) {

		FeesFlat flat = new FeesFlat();

		Date fechaFin = pago.getFechaFin();
		Date fechaInicio = pago.getFechaInicio();

		// Codigo que sirve para llenar los valores de fecha inicio y fin
		Set<String> keys = periodos.keySet();

		for (String key : keys) {

			// Actualizamos las listas de cada categoria (Se agrega las fechas
			// iniciales y finales)
			List<PeriodoFlat> periodosFlat = periodos.get(key);

			for (PeriodoFlat entity : periodosFlat) {

				// Obtenemos el indice para actualizar el objet
				int index = periodosFlat.indexOf(entity);

				entity.setFechaInicio(fechaInicio);
				entity.setFechaFin(fechaFin);

				// Actualizamos el dato en la list
				periodosFlat.set(index, entity);

			}

			// actualizamos la categoria
			periodos.put(key, periodosFlat);

		}

		flat.setPeriodos(periodos);

		return flat;

	}

	/**
	 * @see Metodo que agrega y normaliza el mapa de las caregorias
	 * @param categoria
	 * @param periodos
	 */
	public static void addPeriodoFlat(Map<String, List<PeriodoFlat>> categoria,
			Map<String, List<PeriodoFlat>> periodos) {

		// 1. revisamos si ya existe la categoria
		Set<String> keys = categoria.keySet();

		for (String categoriaKey : keys) {

			// Este es el total
			List<PeriodoFlat> rangoPeriodos = periodos.get(categoriaKey);
			// Este seria el agregar
			List<PeriodoFlat> periodoCat = categoria.get(categoriaKey);

			// es la entidad a agregar
			// Rango rangoEntity = categoria.get(categoriaKey);

			// 1. Si existe se agrega el elemento nuevo
			if (rangoPeriodos != null) {
				// Lo agregamos al listado de rangos de la categoria
				rangoPeriodos.addAll(periodoCat);
				// Lo agregamos a su mapa de la categoria
				periodos.put(categoriaKey, rangoPeriodos);
			} else {
				// Es nueva la categoria y creamos su listado de rangos

				// Agregamos la nueva categoria
				periodos.put(categoriaKey, periodoCat);
			}

		}

	}



}
