package com.mx.dla.dda.contrato.license.titulo.bos;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.mx.dla.dda.catalogos.daos.CatalogosDAO;
import com.mx.dla.dda.catalogos.dtos.CatalogoDTO;
import com.mx.dla.dda.contrato.common.bos.CommonRestBO;
import com.mx.dla.dda.contrato.generales.dtos.ContratoDTO;
import com.mx.dla.dda.contrato.license.titulo.daos.TituloFeeDAO;
import com.mx.dla.dda.contrato.license.titulo.daos.TituloFeeDmDAO;
import com.mx.dla.dda.contrato.license.titulo.rules.TituloFeeRules;
import com.mx.dla.dda.contrato.titulo.constants.TipoCambioTitulo;
import com.mx.dla.dda.contrato.titulo.daos.ListaDAO;
import com.mx.dla.dda.contrato.titulo.dtos.Lista;
import com.mx.dla.dda.contrato.titulo.dtos.Titulo;
import com.mx.dla.dda.contrato.titulo.exception.TituloException;
import com.mx.dla.dda.contrato.titulos.dtos.CatTitulo;
import com.mx.dla.global.bos.BaseBO;

@Component
public class TituloFeeGridBO extends BaseBO{
	
	@Autowired
	protected CommonRestBO commonRestBO;

	@Autowired
	protected ListaDAO listaDAO;
	
	@Autowired
	protected CatalogosDAO catalogosDAO;
	
	@Autowired
	protected TituloFeeRules tituloRules;

	@Autowired
	protected TituloFeeBussinesBO titulosBussinesBO;
		
	@Autowired
	private TituloFeeDmDAO tituloDmDAO;

	@Autowired
	protected TituloFeeDAO tituloDAO;
	
	@Autowired
	protected TituloFeeUtilBO tituloFeeUtilBO;
					
	
	public String alta(ContratoDTO c,Lista l , Titulo t) throws TituloException
	{
		logger.debug("Alta. Titulo [{}]", t);		
		String serie = null;		
		if(tituloRules.verificarSerieNueva(t))
			serie = "El sistema generará automáticamente"+ t.getEpisodio() +" los episodios de "+t.getDescTitulo();
		else
		{			
			this.guardaTitulo(c, l, t);
			titulosBussinesBO.actualizaCostoTodosLosTitulos(c);	
		}	
		return serie;
	}
	
	public Titulo guardaTitulo(ContratoDTO c, Lista l, Titulo t) throws TituloException
	{
		t.setIdLista(l.getIdLista());				
		tituloRules.validaEntrada(t, titulosBussinesBO.calculaFechasInicioFinValidacion(c));
		
		CatTitulo cat = titulosBussinesBO.actualizaCatalogoTitulos(t.getDescTitulo(), c);
		t = tituloFeeUtilBO.getTituloGuardar(cat, t, c);
		
		t.setCosto(titulosBussinesBO.obtieneCostoTitulo(c.getIdContrato()));
		tituloDmDAO.insertarTitulo(t);
		return t;
	}

	public void cambio(ContratoDTO c,Lista l, Titulo t) throws TituloException
	{
		logger.debug("Cambio. Titulo [{}]",t);	
		tituloRules.validaEntrada(t, titulosBussinesBO.calculaFechasInicioFinValidacion(c));
		
		Titulo destino =  tituloDmDAO.buscarTitulo(t.getIdTituloCnt());
				
		if(!destino.getDescTitulo().equals(t.getDescTitulo()))     //Logica para el concepto de cambio de titulos. A un titulo se le cambia descTitulo (Nombre del titulo)				
			destino = this.llenaCambioTitulo(t, destino,c);		
		else
			destino = this.guardarEdicionTitulo(t, destino,c);
			
		titulosBussinesBO.actualizaCostoTodosLosTitulos(c);
		titulosBussinesBO.actualizarBanderasContratosAnteriores(destino, "M");
	}

	public void cambioMultiple(ContratoDTO c,Lista l , Titulo origen ,  String tipoCambio, String idsTipoCambio)throws TituloException
	{
		logger.debug("cambioMultiple. Titulo [{}]",origen);		
		logger.debug("Contrato [{}]",c);
		logger.debug("tipocambio [{}]",tipoCambio);
		logger.debug("Contrato [{}]",idsTipoCambio);
		
		List<Long> ids = new ArrayList<Long>();
		String indexes [] = idsTipoCambio.split(",") ;
		for(String index : indexes)
		{
			if(!"".equals(index))
			{
				origen.setIdTituloCnt(Long.parseLong(index));
				Titulo destino =  tituloDmDAO.buscarTitulo(origen.getIdTituloCnt());
				if(TipoCambioTitulo.CATEGORIA.name().equals(tipoCambio))
				{
					CatalogoDTO cat = null;
					if(origen.getPagoCateg() != null){
						cat = catalogosDAO.buscarCategoriaPagoPorDesc(c.getIdContrato() ,origen.getPagoCateg().getDesc() );
					}
					destino.setPagoCateg(cat);
					destino.setPrecioAnual(null);
				}else // VENTANA
				{
					destino.setFechaInicio(origen.getFechaInicio());
					destino.setFechaFin(origen.getFechaFin());
					destino.setVidaUtil(tituloFeeUtilBO.calcularVidaUtil(origen.getFechaInicio(),origen.getFechaFin()));
					destino.setMesesvu(tituloFeeUtilBO.calculaMesesVidaUtil(origen.getFechaInicio(),origen.getFechaFin()));
					CatalogoDTO cat = null;
					if(destino.getPagoCateg() != null){
						cat = catalogosDAO.buscarCategoriaPagoPorDesc(c.getIdContrato(),destino.getPagoCateg().getDesc() );
					}
					destino.setPagoCateg(cat);
				}
				tituloDmDAO.actualizarTitulo(destino);
				titulosBussinesBO.actualizarBanderasContratosAnteriores(destino,"M");
				ids.add(origen.getIdTituloCnt());
			}
		}
		titulosBussinesBO.actualizaCostoTodosLosTitulos(c);
	}

	/**
	 * @see Metodo que realiza logica necesaria cuando se modifica un titulo en una enmienda. Verificar diagrama modificacion titulos
	 */
	public Titulo llenaCambioTitulo(Titulo origen, Titulo bd, ContratoDTO contrato) throws TituloException
	{
		if(bd.getIdSap()!= null)
		{
			if(bd.getFechaNotifsap() != null)
			{
				origen.setEstatus      ("ACTIVO");
				origen.setIdSap        ("PDTE");
				origen.setAjustoTitulo (1L);
				origen.setFechaNotifsap(bd.getFechaNotifsap());								
				origen.setIdContrato   (contrato.getIdContrato());
				
				CatTitulo c = titulosBussinesBO.actualizaCatalogoTitulos(origen.getDescTitulo(), contrato);
				origen.setIdTitulo(c.getIdTitulo());
				origen.setVidaUtil(tituloFeeUtilBO.calcularVidaUtil(origen.getFechaInicio(),origen.getFechaFin()));
				origen.setMesesvu(tituloFeeUtilBO.calculaMesesVidaUtil(origen.getFechaInicio(),origen.getFechaFin()));
				origen.setEstatus("ACTIVO");
				
				tituloDmDAO.insertarTitulo(origen);
				
				Titulo nuevo =  tituloDmDAO.buscarTitulo(origen.getIdTituloCnt());
				
				if(bd.getIdSapAnt() != null)
				{
					nuevo.setIdSapAnt(bd.getIdSapAnt());
					nuevo.setIdTituloCntant(bd.getIdTituloCntant());
					nuevo.setIdTituloCntorig(bd.getIdTituloCntorig());
					tituloDmDAO.actualizarTitulo(nuevo);
					tituloDmDAO.borrarTitulo(bd.getIdTituloCnt());
				}
				else
				{
					nuevo.setIdSapAnt(bd.getIdSap());
					nuevo.setIdTituloCntant(bd.getIdTituloCnt());
					nuevo.setIdTituloCntorig(bd.getIdTituloCntorig());
					tituloDmDAO.actualizarTitulo(nuevo);
					
					bd.setEstatus("ELIMINADO");
					bd.setIdTituloCntnvo(nuevo.getIdTituloCnt());
					tituloDmDAO.actualizarTitulo(bd);
				}
				bd = nuevo;
			}
			else
			{
				bd.setAjustoTitulo(1L);
				bd = guardarEdicionTitulo(origen, bd, contrato);
			}
		}
		else
		{
			bd = guardarEdicionTitulo(origen, bd, contrato);
		}
		return bd;
	}
	
	public Titulo guardarEdicionTitulo(Titulo origen, Titulo bd,ContratoDTO contrato) throws TituloException
	{
		bd = tituloFeeUtilBO.getTituloByTitulo(origen, bd);		
		CatTitulo c = titulosBussinesBO.actualizaCatalogoTitulos(origen.getDescTitulo(),contrato);
		bd.setIdTitulo(c.getIdTitulo());		
		tituloDmDAO.actualizarTitulo(bd);
		return bd;
	}
	
	public void altaSeriesAuto(ContratoDTO c,Lista l , Titulo t) throws TituloException
	{		
		logger.debug("Alta Serie. Titulo [{}]", t);		
		int numEpisodios = Integer.parseInt(t.getEpisodio());		
		String nombre    = t.getDescTitulo() + ": Episodio # ";
		
		for(int i=1; i<=numEpisodios; i++)
		{
			String name = nombre + i;							
			guardaTitulo(c, l, TituloFeeUtilBO.getTituloSerieAuto(t, name, String.valueOf(i)));
		}												    	
		titulosBussinesBO.actualizaCostoTodosLosTitulos(c);			
	}
	
	public void baja(ContratoDTO c, Titulo t)
	{
		logger.debug("baja. Titulo [{}]",t);		
		Titulo tbd =  tituloDmDAO.buscarTitulo(t.getIdTituloCnt());		
		if(tbd.getIdSap() == null || "".equals(tbd.getIdSap()))
		{
			tituloDmDAO.borrarTitulo(t.getIdTituloCnt());
		}
		else
		{
			tbd.setEstatus("ELIMINADO");
			if(tbd.getFechaNotifsap() != null)
			{
				tbd.setBajaPerdida(t.getBajaPerdida());
				if(t.getBajaPerdida() == 0)				
				   tbd.setNotaCredito(1);				
			}
			else
			{
				tbd.setBajaPerdida(0L);
			}
			tituloDmDAO.actualizarTitulo(tbd);
		}
	}
		
	public List<Titulo> busqueda( Titulo t, boolean calculaAmortizacion, String prefix)throws TituloException
	{
		List<Titulo> titulos = new ArrayList<Titulo>();
		
		titulos.addAll(tituloDmDAO.buscaTotalesLista(t.getIdLista(), prefix));
		titulos.addAll(tituloDmDAO.buscaDetallePeliculas(t.getIdLista(), prefix));
		
		List<Titulo> nombresUnicos = tituloDmDAO.buscaSerie1Capitulo(t.getIdLista(), prefix);
		List<Titulo> series        = tituloDmDAO.buscaTotalesSerie(t.getIdLista(),t.getNombreUnico(),prefix);
		
		for(Titulo s : nombresUnicos)
		{
			int i=0;
			for(Titulo tt : series)
			{   				
				if(tt.getNombreUnico().equals(s.getNombreUnico()))
				{							
					series.remove(i);
					break;
				}
				i++;
			}
		}													
		
		titulos.addAll(nombresUnicos);
		titulos.addAll(series);
		
		//Se quita transformacion de amortizaiciones de lista a mapa		
		if(calculaAmortizacion)
		{
			for(Titulo tam : titulos)
			{				
			    HashMap<String , String> h = new HashMap<String,String>();
			    if(tam.getAmortizaciones() != null)
			    {
					for (CatalogoDTO cat : tam.getAmortizaciones()) 
					{
				        h.put(cat.getValue(),cat.getDesc());
				    }
			    }
			    tam.setAmortizacionesH(h);
			}
		}		
		return titulos;
	}
	
	public List<Titulo> busquedaDetalle( Titulo t, boolean calcularAmort, String prefix)throws TituloException
	{
		List<Titulo> titulos = new ArrayList<Titulo>();
		                           
		titulos.addAll(tituloDmDAO.buscaTotalesSerie(t.getIdLista(),t.getNombreUnico(), prefix));
		titulos.addAll(tituloDmDAO.buscaDetalleSerie(t.getIdLista(),t.getNombreUnico(), prefix));
		
		titulos.get(0).setAgrupable(0);
		
		if(calcularAmort)
		{
			for(Titulo tam : titulos)
			{
				HashMap<String , String> h = new HashMap<String,String>();
			    if(tam.getAmortizaciones() != null)
			    {
					for (CatalogoDTO cat : tam.getAmortizaciones()) 
					{
				        h.put(cat.getValue(),cat.getDesc());
				    }
			    }
			    tam.setAmortizacionesH(h);
			}	
		}				
		return titulos;
	}
													
}