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

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.mx.dla.dda.contrato.transaccion.exceptions.dtos.TransaccionException;
import com.mx.dla.dda.contrato.transaccion.terminos.daos.TerminosTransaccionDAO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.ExcepcionesSeccionDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.MinimoGarantizadoDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.MoviesDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.PrecioRentaDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.RevenueBoxGloDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.SeccionesTerminos;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.TerminoPrecioDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.TerminosAuxiliarDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.TerminosPaisDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.TerminosPrecioDTO;
import com.mx.dla.dda.general.utilerias.ListaUtilerias;
import com.mx.dla.global.bos.BaseBO;

@Service
public class TerminosMovie extends BaseBO{

	
	@Autowired
	private TerminosMinimos minimos;
	
	@Autowired
	@Qualifier("precioMovies")
	private TerminosPrecio precio;
	
	@Autowired
	private TerminosRevenue revenue;
	
	@Autowired
	private TerminosTransaccionDAO dao;
				
	@Autowired
	private TerminosExcepciones excepciones;
	
	private List<TerminosPaisDTO>   paises;
	private List<TerminosPaisDTO>   categorias;
	private List<TerminosPaisDTO>   formatos;	
	
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public MoviesDTO obtenerMovies(Long idContrato)throws TransaccionException{
		MoviesDTO movies = new MoviesDTO();
		
		try
		{									
			MinimoGarantizadoDTO minimo = minimos.obtenerMinimos(idContrato, SeccionesTerminos.VentaMovies.getDesc());			
			                     movies = this.obtenerDatosDTOMovies(movies, idContrato, SeccionesTerminos.VentaMovies.getDesc());
			RevenueBoxGloDTO        rev = revenue.obtenerRevenueMovies(idContrato, SeccionesTerminos.VentaMovies.getDesc(), movies.getPrecio().getPrecio());
			ExcepcionesSeccionDTO excepcionesDTO = excepciones.obtenerExcepciones(idContrato, SeccionesTerminos.VentaMovies.getDesc());
			
			movies.setMinimos(minimo);								
			movies.setRevenue(rev);
			movies.setExcepciones(excepcionesDTO);
								
		}catch(Exception e){
			new TransaccionException("Error al obtener terminos movies.", e);
		}								
		return movies;		
	}	
	
	public MoviesDTO obtenerDatosDTOMovies(MoviesDTO terminos, Long idContrato, String seccion){												
		this.formatos   = dao.obtenerFormatos();											
		this.categorias = dao.obtenerTiers();
		
		Integer aplica = dao.obtenerAplicaPrecios(idContrato, seccion);
		Integer pagoPpe = dao.obtenerPagoPpe(idContrato, seccion);
		
		List<TerminosPaisDTO> paises = dao.obtenerPaises(idContrato);
		List<TerminosPaisDTO> impuestoEstatus = dao.obtenerPaisesImpuestoEstatus(idContrato, seccion);

		for (TerminosPaisDTO pais : paises) {
			if (pais.getAplicaImpuesto() == null)
				pais.setAplicaImpuesto(0);
			for (TerminosPaisDTO impuesto : impuestoEstatus)
				if (pais.getIdPais().equals(impuesto.getIdPais()))
					pais.setAplicaImpuesto(impuesto.getAplicaImpuesto());
		}
		
		this.paises   = paises;							
		
		PrecioRentaDTO price = new PrecioRentaDTO();
		String [][] datos = ListaUtilerias.safeArray(null, String.class, 1, (paises.size() * 2) + 2);
		
		String formatosS[] = new String[this.formatos.size()];
		for(int i=0; i<this.formatos.size(); i++)
			formatosS[i] = this.formatos.get(i).getDescripcion();
		
		String categoriasS[] = new String[this.categorias.size()];
		for(int i=0; i<this.categorias.size(); i++)
			categoriasS[i] = this.categorias.get(i).getDescripcion();
		
		List<TerminoPrecioDTO> precios = dao.obtenerPrecioMovies(idContrato);
		
		if(precios != null && !precios.isEmpty())
		   datos = precio.obtenerDatosPrecioMovSer(formatosS, this.paises, categoriasS, null, precios);

		price.setPrecio(datos);
		price.setAplica(aplica == null ? 1 : aplica);
		price.setPagoPPE(pagoPpe == null ? 0 : pagoPpe);
		price.setPaises(this.paises);
		
		terminos.setPrecio(price);
		terminos.setCategorias(categoriasS);
		
		return terminos;
	}
	
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void guardarPremium(MoviesDTO p, Long idContrato) throws JsonParseException, JsonMappingException, IOException, TransaccionException{
		
		try
		{
			logger.debug(p.toString());
			revenue.eliminarRevenueBoxMovies(idContrato);
			revenue.elimnarRevenueGlobal(idContrato, SeccionesTerminos.VentaMovies.getDesc());
			precio.eliminarPaisesImpuestoEstatus(idContrato, SeccionesTerminos.VentaMovies.getDesc());
			precio.eliminarPreciosMovies(idContrato); 
			excepciones.eliminarExcepcion(idContrato, SeccionesTerminos.VentaMovies.getDesc());

			minimos.guardarMinimos(p.getMinimos().getMinimosCateg(), p.getMinimos().getMinimosAnio(), p.getMinimos().getAnios(), p.getMinimos().getTipoMin(), SeccionesTerminos.VentaMovies.getDesc(), idContrato);											
		
			precio.actualizarPrecioAplica(idContrato, SeccionesTerminos.VentaMovies.getDesc(), p.getPrecio().getAplica());
			precio.actualizarPagoPpe(idContrato, SeccionesTerminos.VentaMovies.getDesc(), p.getPrecio().getPagoPPE());

			boolean aplicaPrecio = p.getPrecio().getAplica().intValue() == 1;
			boolean isGlobalRevenue = p.getRevenue().isRevenueGlobal();
			boolean isBoxOfficeRevenue = p.getRevenue().isRevenueBox();

			if(aplicaPrecio)
			    this.guardarDatosPreciosMovies(p.getPrecio(), idContrato, this.categorias, this.formatos, this.paises, SeccionesTerminos.VentaMovies.getDesc());						
			
			Long categoriasS[] = new Long[this.categorias.size()];
			for(int i=0; i<this.categorias.size(); i++)
				categoriasS[i] = this.categorias.get(i).getIdPais();
			
			if((isBoxOfficeRevenue && aplicaPrecio) || isGlobalRevenue)
			  revenue.guardarRevenueMovies(idContrato, SeccionesTerminos.VentaMovies.getDesc(), this.categorias, p.getRevenue());
			
			excepciones.guardarExcepciones(idContrato, SeccionesTerminos.VentaMovies.getDesc(), p.getExcepciones());

		
		}
		catch(Exception e){
			new TransaccionException("Error al obtener terminos premium.", e);
		}
		
	}

	public void guardarDatosPreciosMovies(PrecioRentaDTO precioMovies, Long idContrato, List<TerminosPaisDTO> categorias, List<TerminosPaisDTO> formatos, List<TerminosPaisDTO> paises, String seccion) throws TransaccionException{							
		try
		{																	
			List<TerminosPrecioDTO> precios = new ArrayList<TerminosPrecioDTO>();	
			String datos [][] = precioMovies.getPrecio();
			
			Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);

			precios = precio.generarDatosMoviesSeries(datos, idContrato, categorias, formatos, paises);							    
		    dao.guardarValoresPrecioMovies(precios, idContrato);
		    
			for (TerminosPaisDTO pais : precioMovies.getPaises()) {
				TerminosAuxiliarDTO impuesto = new TerminosAuxiliarDTO();
				impuesto.setIdOpcionalA(idContrato);
				impuesto.setIdOpcionalB(pais.getIdPais());
				impuesto.setIdOpcionalC(idSeccion);
				impuesto.setValorA(pais.getAplicaImpuesto());
				dao.guardaPaisesImpuestoEstatus(impuesto);
			}
		}catch(Exception e)
		{
			throw new TransaccionException("Se genero un error al guardar los datos.", e);
		}  				
	}
	

}
