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

import java.io.IOException;
import java.net.URLDecoder;
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 org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.mx.dla.dda.contrato.materiales.daos.MaterialesDAO;
import com.mx.dla.dda.contrato.terminos.daos.TerminosDAO;
import com.mx.dla.dda.contrato.terminos.dtos.ContratoConsultaDTO;
import com.mx.dla.dda.contrato.terminos.dtos.PagoTerminoDTO;
import com.mx.dla.dda.contrato.terminos.dtos.TerminoBD;
import com.mx.dla.dda.contrato.terminos.dtos.TerminoDTO;
import com.mx.dla.dda.contrato.terminos.dtos.TerminoServicioBD;
import com.mx.dla.dda.contrato.terminos.dtos.TituloTerminoDTO;
import com.mx.dla.dda.contrato.titulo.daos.TituloDAO;
import com.mx.dla.global.bos.BaseBO;

@Service
public class TerminosBO extends BaseBO{
		
	@Autowired
	private TerminosDAO terminosDAO;
	
	@Autowired
	private MaterialesDAO materialesDAO;
	
	@Autowired
	private TituloDAO tituloDAO;
		
	public TerminoDTO getTerminos(Long idContrato){
		TerminoDTO termino = new TerminoDTO();
		
		TerminoBD term = terminosDAO.getTermino(idContrato);						
		
		if(term == null)
			termino.setVacio(true);
		else
		{
			if(term.getAnticipoMonto() != null)
			{
				PagoTerminoDTO pago = new PagoTerminoDTO(Double.parseDouble(term.getAnticipoMonto()), term.getAnticipoComentario(), getFecha(term.getAnticipoFecha()));
				termino.setPagoAnticipado(pago);				
			}
									
			if(term.getTipoPago() != null && term.getTipoPago().compareTo("MENSUAL") == 0)
			{
				termino.setPagoMensual(true);				
			}
			   		
			if(term.getTipoPago() != null && term.getTipoPago().compareTo("PREDEFINIDO") == 0 && 
			   term.getTipoPredefinido().compareTo("EXHIBICION") == 0)
			{
				termino.setPagoInicioExhibicion(true);				
			}
						
			if(term.getTipoPago() != null && term.getTipoPago().compareTo("PREDEFINIDO") == 0 && 
			   term.getTipoPredefinido().compareTo("PERIODICO") == 0)
			{
				List<TerminoBD> periodicos = terminosDAO.getTerminoPeriodicos(idContrato);
				List<PagoTerminoDTO> pagoPeriodicos = new ArrayList<PagoTerminoDTO>();
				
				for(TerminoBD pago : periodicos)
				{
					PagoTerminoDTO pagoT = new PagoTerminoDTO(Double.parseDouble(pago.getMonto()), pago.getComentario(), getFecha(pago.getFecha()));
					pagoPeriodicos.add(pagoT);
				}
				termino.setPagoPeriodicos(pagoPeriodicos);				
			}			
			termino.setComentario(term.getComentarioGeneral());						
		}
		
		termino.setNumeroTitulos(terminosDAO.getNumTitulos(idContrato));
						
		List<TituloTerminoDTO> serviTitulos = this.getServiciosTitulos(idContrato);
		termino.setTitulos(serviTitulos);
		return termino;
	}
	
	private List<TituloTerminoDTO> getServiciosTitulos(Long idContrato){
		List<TituloTerminoDTO> serviTitulos = new ArrayList<TituloTerminoDTO>();
				
		List<TerminoServicioBD> terminoServicio = terminosDAO.getTerminoTitulos(idContrato);		
		
		for(TerminoServicioBD servicio : terminoServicio)
		{
			logger.debug(servicio.toString());
			Double cantidad    = servicio.getCantidadTitulos()   != null ? Double.parseDouble(servicio.getCantidadTitulos())     : null;
			Integer porcentaje = servicio.getPorcentajeTitulos() != null ? Integer.parseInt(servicio.getPorcentajeTitulos()) : null;
			TituloTerminoDTO tituloServicio =  new TituloTerminoDTO(servicio.getIdServicio(), cantidad, porcentaje, servicio.getDescripcion());
			serviTitulos.add(tituloServicio);				
		}
		
		return serviTitulos; 
	}
	
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void guardarTerminos(TerminoDTO termino, Long idContrato) throws ParseException, IOException{
		logger.debug("termino:" + termino.toString());
		TerminoBD terminobd = new TerminoBD();
		terminobd.setIdContrato(idContrato);
		
		this.eliminarTerminos(idContrato);
		
		if(termino.getPagoAnticipado() != null)
		{			
			terminobd.setAnticipoComentario(URLDecoder.decode(termino.getPagoAnticipado().getDescripcion(), "UTF-8"));
			terminobd.setAnticipoFecha(crearFecha(termino.getPagoAnticipado().getFecha()));
			terminobd.setAnticipoMonto(String.valueOf(termino.getPagoAnticipado().getMonto()));						
		}
								
		if(termino.getPagoMensual() != null && termino.getPagoMensual())
		{
			terminobd.setTipoPago("MENSUAL");					
		}
		   		
		if(termino.getPagoInicioExhibicion() != null && termino.getPagoInicioExhibicion())
		{
			terminobd.setTipoPago("PREDEFINIDO");			
			terminobd.setTipoPredefinido("EXHIBICION");								
		}
					
		if(termino.getPagoPeriodicos() != null)
		{
			terminobd.setTipoPago("PREDEFINIDO");
			terminobd.setTipoPredefinido("PERIODICO");									
		}
		
		terminobd.setComentarioGeneral(URLDecoder.decode(termino.getComentario(), "UTF-8"));
		String numTitulos = termino.getNumeroTitulos() == null ? null : String.valueOf(termino.getNumeroTitulos());
		terminobd.setTotalTitulos(numTitulos);
		terminosDAO.guardarTermino(terminobd);		
		
		if(termino.getPagoPeriodicos() != null)
		{			
			List<TerminoBD> pagoPeriodicos = new ArrayList<TerminoBD>();			
			for(PagoTerminoDTO pago : termino.getPagoPeriodicos())
			{
				TerminoBD pagoT = new TerminoBD();				
				pagoT.setMonto(String.valueOf(pago.getMonto()));				
				pagoT.setFecha(crearFecha(pago.getFecha()));
				pagoT.setComentario(URLDecoder.decode(pago.getDescripcion(), "UTF-8"));
				pagoT.setIdContrato(idContrato);
				pagoPeriodicos.add(pagoT);
			}						
			terminosDAO.guardarTerminoPago(pagoPeriodicos);
		}
		
		List<TerminoServicioBD> serviTitulos = new ArrayList<TerminoServicioBD>();
		
		for(TituloTerminoDTO servicio : termino.getTitulos())
		{
			logger.debug(servicio.toString());
			TerminoServicioBD tituloServicio =  new TerminoServicioBD();
			tituloServicio.setIdServicio(servicio.getId());
			
			String ser = servicio.getCantidad() == -1  ? null : String.valueOf(servicio.getCantidad());
			tituloServicio.setCantidadTitulos(ser);
						
			String por = servicio.getPorcentaje() == -1.0 ? null : String.valueOf(servicio.getPorcentaje()); 
			tituloServicio.setPorcentajeTitulos(por);			
			serviTitulos.add(tituloServicio);
		}				
		terminosDAO.guardarServicioTitulo(serviTitulos, idContrato);
	}
		
	private void eliminarTerminos(Long idContrato){
		terminosDAO.eliminarTerminoPago(idContrato);
		terminosDAO.eliminarTermino(idContrato);
		terminosDAO.eliminarServicio(idContrato);
	}
	
	public ContratoConsultaDTO getInformacionContrato(Long idContrato, TerminoDTO termino){
		//Tipo contrato, fecha inicio, costo contrato, costo materiales,
		Double costoLicencia         = tituloDAO.buscarTotalCostoTitulos(idContrato);
		Double materialesCosto       = materialesDAO.buscarCostoTotalMateriales(idContrato);
		ContratoConsultaDTO contrato = terminosDAO.consultaContrato(new ContratoConsultaDTO(idContrato));
		
		termino.setCostoContrato(costoLicencia);
		termino.setCostoMateriales(materialesCosto);
		
		return contrato;
	}	

	private Date crearFecha(String valor) throws ParseException{	
		DateFormat formatter1 = new SimpleDateFormat("MM/dd/yyyy");
		Date fecha = formatter1.parse(valor);
        return fecha;
	}
	
	private String getFecha(Date fecha){		
		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");		
		return sdf.format(fecha);
	}
}