package com.mx.dla.dda.contrato.fees.bos;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

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

import com.mx.dla.dda.contrato.fees.daos.FeesContratoDAO;
import com.mx.dla.dda.contrato.fees.dtos.FeesContratoPagoBD;
import com.mx.dla.dda.contrato.fees.dtos.FeesContratoPagoDTO;
import com.mx.dla.dda.contrato.fees.dtos.FeesPagoCostoDTO;
import com.mx.dla.dda.contrato.fees.dtos.FeesPagoRangoDTO;
import com.mx.dla.dda.contrato.fees.dtos.FeesSuscriptorBD;
import com.mx.dla.dda.contrato.minimoseleccion.bos.MinimoSeleccionBO;
import com.mx.dla.global.bos.BaseBO;

@Service
public class FeesSuscriptorBO extends BaseBO{

	@Autowired
	private FeesContratoDAO feesContratoDAO;
	
	@Autowired
	private MinimoSeleccionBO minimoSeleccionBO;
	
	public FeesContratoPagoDTO crearSuscriptor(FeesContratoPagoBD pagoBD, List<FeesSuscriptorBD> feeBD){
		   FeesContratoPagoDTO fee = null;
		   int numRangos = 1;
		   
		   if(feeBD == null)
		   {			    
			   List<FeesPagoCostoDTO> pagos = new ArrayList<FeesPagoCostoDTO>();
			   
			   FeesPagoCostoDTO pago = new FeesPagoCostoDTO(0L, "", numRangos);
			   pagos.add(pago);			   	   			   			 
			   
			   fee = new FeesContratoPagoDTO(0L, 0L, 0L, "",  "",  "", "", "nuevo", pagos, null);
			   fee.setMaxRangos(numRangos);		
		   }
		   else
		   {
			   logger.debug(feeBD.toString());
			   List<FeesPagoCostoDTO> pagos = new ArrayList<FeesPagoCostoDTO>();			   
			   for(FeesSuscriptorBD itemBD : feeBD)
			   {   
				   boolean existente = false;
				   for(FeesPagoCostoDTO item: pagos)
				   {
					   if(item.getIdCategoria().longValue() == itemBD.getIdCategoria().longValue())
					   {
						   item.getRangos().add(new FeesPagoRangoDTO(itemBD.getIdPagoRango(), itemBD.getDesde(), itemBD.getHasta(), itemBD.getCosto()));
						   existente = true;
					   }					   						 
				   }
				   if(!existente)
				   {						   
					   FeesPagoCostoDTO pago = new FeesPagoCostoDTO(itemBD.getIdCategoria(), itemBD.getDesCategoria(), 0);
					   pago.getRangos().add(new FeesPagoRangoDTO(itemBD.getIdPagoRango(), itemBD.getDesde(), itemBD.getHasta(), itemBD.getCosto()));					   
					   pagos.add(pago);
				   }
			   }			   			   			   					   	   			   			
			   
			   numRangos = pagos.get(0).getRangos().size();
			   fee = new FeesContratoPagoDTO(pagoBD.getIdContratoPago(), pagoBD.getIdContrato(), pagoBD.getIdTipoSuscriptor(), 
					   						 this.getFecha(pagoBD.getFechaInicio()), this.getFecha(pagoBD.getFechaFin()), 
					   						 pagoBD.getTipoAnio(),  pagoBD.getTipoPago(), "editar", pagos, null);
			   fee.setAnioContrato(pagoBD.getAnioContrato());
			   fee.setMaxRangos(numRangos);
		   }		   
		   return fee;
	}
	
	public void guardarSuscriptor(FeesContratoPagoDTO  periodo, Long idContrato) throws ParseException, Exception{				
		List<FeesSuscriptorBD> minSelCat  = new ArrayList<FeesSuscriptorBD>();
		Integer str = null;
		logger.debug("periodo a guardar."+periodo.toString());
		FeesContratoPagoBD contratoPago = new FeesContratoPagoBD(0L, idContrato, periodo.getIdSuscriptor(),
				        		              periodo.getTipoPago(), periodo.getTipoAnio(), 
				                              this.crearFecha(periodo.getFechaInicio()), this.crearFecha(periodo.getFechaFin()));
		contratoPago.setAnioContrato(periodo.getAnioContrato());
		feesContratoDAO.guardarContratoPago(contratoPago);
		minimoSeleccionBO.guardarMinSeleccion(contratoPago.getIdContratoPago(), null, null);  //Se guarda el minimo de seleccion por periodo																											
		this.guardarRangoPagoCosto(periodo, contratoPago);
		
		for(FeesPagoCostoDTO categoria : periodo.getCategorias())
			minSelCat.add(new FeesSuscriptorBD(contratoPago.getIdContratoPago(), str, categoria.getIdCategoria()));
		
		minimoSeleccionBO.guardarMinSeleccionXCatAnio(minSelCat); //Se guarda el minimo de seleccion por categoria				
		logger.debug("guardar msle. "+minSelCat.toString());
	}
	
	public void guardarRangoPagoCosto(FeesContratoPagoDTO  periodo, FeesContratoPagoBD contratoPago){
		List<Long>             idRangos = new ArrayList<Long>();
		List<FeesSuscriptorBD> costos   = new ArrayList<FeesSuscriptorBD>();
		
		for(FeesPagoRangoDTO rango : periodo.getCategorias().get(0).getRangos())              //Se guardan los rangos
		{			
			feesContratoDAO.guardarPagoRango(rango, contratoPago.getIdContratoPago());
			idRangos.add(rango.getIdRango());
		}
						
		for(FeesPagoCostoDTO categoria : periodo.getCategorias())		
			for(int i=0; i < categoria.getRangos().size(); i++)			
				costos.add(new FeesSuscriptorBD(idRangos.get(i), categoria.getRangos().get(i).getMonto(), categoria.getIdCategoria()));			
		
		feesContratoDAO.guardarPagoCostoALL(costos);
		logger.info("Se guarda los costos. "+costos.toString() + "del periodo "+ periodo.getIdContratoPago());				
	}
	
	public void editarSuscriptor(FeesContratoPagoDTO  periodo)throws ParseException, Exception{
		logger.info("periodo a actualizar."+periodo.toString());
		FeesContratoPagoBD contratoPago = new FeesContratoPagoBD(periodo.getIdContratoPago(), periodo.getIdContrato(), periodo.getIdSuscriptor(),
	                                                             periodo.getTipoPago(), periodo.getTipoAnio(), 
                                                                 this.crearFecha(periodo.getFechaInicio()), this.crearFecha(periodo.getFechaFin()));
		contratoPago.setAnioContrato(periodo.getAnioContrato());
		feesContratoDAO.actualizarContratoPago(contratoPago);		
		this.guardarRangoPagoCosto(periodo, contratoPago);		
		logger.info("Se ha terminado de editar el periodo. id["+periodo.getIdContratoPago()+"]");
	}
	
	public void eliminarSuscriptores(Long idContrato) throws ParseException, Exception{				
		minimoSeleccionBO.eliminarMinSeleccionXCto(idContrato); 
		this.eliminarRangosCostoSuscriptor(idContrato);																
		feesContratoDAO.eliminarContratoPagoXCto(idContrato);
	}
	
	public void eliminarSuscriptor(FeesContratoPagoDTO  periodo){		
		minimoSeleccionBO.eliminarMinSeleccion(periodo.getIdContratoPago(), null); //Se elimina minimum seleccion																			
		for(FeesPagoCostoDTO categoria : periodo.getCategorias())                  //Se elimina los costos asociados rangos-categ		
			for(FeesPagoRangoDTO rango : categoria.getRangos())
				feesContratoDAO.eliminarPagoCosto(categoria.getIdCategoria(), rango.getIdRango());			
		feesContratoDAO.eliminarPagoRango(periodo.getIdContratoPago());            //Se eliminan los rangos						
		feesContratoDAO.eliminarContratoPago(periodo.getIdContratoPago());
	}
	
	public void eliminarRangosCostoSuscriptor(Long  idContrato)throws ParseException, Exception{						
		feesContratoDAO.eliminarPagoCostoXCto(idContrato);            //Se elimina los costos asociados rangos-categ					
		feesContratoDAO.eliminarPagoRangoXCto(idContrato);            //Se eliminan los rangos
		logger.info("Se han eliminado los rangos y valores de los rangos");
	}
	
	public List<FeesContratoPagoDTO> eliminarCategoriaSuscriptor(Long idCategoria, List<FeesContratoPagoDTO> periodos){
		  //se eliminan los valores por rango y categoria						
		  feesContratoDAO.eliminarPagoCostoXCategoria(idCategoria);		
		  		  		  		  		  
		  for(FeesContratoPagoDTO periodo: periodos)
		  {
			  //se elimina la categoria insertada para el minimo de seleccion
			  minimoSeleccionBO.eliminarMinSeleccion(periodo.getIdContratoPago(), idCategoria);
			  int index = -1;
			  for(int i=0; i<periodo.getCategorias().size(); i++)			  
				 if(periodo.getCategorias().get(i).getIdCategoria().longValue() == idCategoria.longValue())
					 index = i;
			  
			  if(index != -1)
			     periodo.getCategorias().remove(index);
		  }		  		  
		  feesContratoDAO.actualizarTitulosTCateg(idCategoria); //Se elimina la relacion de la categoria con los titulos
		  feesContratoDAO.actualizarTitulosMCateg(idCategoria);		  		  		  
		  feesContratoDAO.eliminarPagoCategoria(idCategoria);   //Se elimina la categoria		  
		  return periodos;
	}
	
	public Date crearFecha(String valor) throws ParseException{	
		DateFormat formatter1 = new SimpleDateFormat("MM/dd/yyyy");
		Date fecha = formatter1.parse(valor);
        return fecha;
	}
		
	public String getFecha(Date fecha){		
		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");		
		return sdf.format(fecha);
	}
}
