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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

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

import com.mx.dla.dda.contrato.transaccion.exceptions.dtos.TransaccionException;
import com.mx.dla.dda.contrato.transaccion.fees.bos.FeesTransaccionUtileria;
import com.mx.dla.dda.contrato.transaccion.terminos.daos.TerminosTransaccionDAO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.PrecioRentaDTO;
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 TerminosPrecio extends BaseBO{

	@Autowired
	private TerminosTransaccionDAO dao;
	
	private List<TerminosPaisDTO>   paises;
	private List<TerminosPaisDTO>   formatos;
	private String[]                releases;
	
	
	public PrecioRentaDTO obtenerPrecio(String[][] release, Long idContrato, String seccion){
		PrecioRentaDTO precio = new PrecioRentaDTO();
		
		this.releases = new String[release.length];
		this.obtenerCatalogos(idContrato, seccion);		
		
		precio.setPaises(this.paises);
		
		String [][]   datos = null;
		
		for(int i=0; i<release.length; i++)
			this.releases[i] = release[i][2];
		
		String formatosS [] = new String[formatos.size()];		
				
		for(int i=0; i<formatos.size(); i++)
			formatosS[i] = formatos.get(i).getDescripcion();
				
		Integer aplica = this.obtenerAplicaPrecios(idContrato, seccion);
		Integer pagoPpe = this.obtenerPagoPpe(idContrato, seccion);
		
		precio.setPagoPPE(pagoPpe == null ? 0 : pagoPpe);

		if(aplica != null && aplica.intValue() == 1)
		{
			List<TerminoPrecioDTO> precios = dao.obtenerPrecioPremier(idContrato, seccion);
			datos    = this.obtenerDatosPrecio(formatosS, this.paises, this.releases, precios);
			precio.setAplica(1);
		}
		else
		{
			precio.setAplica(0);
			datos = this.obtenerDatosPrecio(formatosS, this.paises, this.releases, null);

		}
		precio.setPrecio(datos);
													        
		return precio;				
	}
	
	public String[][] obtenerDatosPrecio(String [] formatos, List<TerminosPaisDTO> paises, String [] variable, List<TerminoPrecioDTO> precios){
		
		String [][]datos = new String[variable.length * formatos.length][(paises.size()*2)+2];
		int indFilaPais = 0;
		
		for (int i = 0; i < variable.length; i++) {
			for (int j = 0; j < formatos.length; j++) {
				datos[indFilaPais][0] = variable[i];
				datos[indFilaPais][1] = formatos[j];
				for (int k = 0; k < paises.size(); k++) {
					for (int x = 0; x < ListaUtilerias.safeList(precios).size(); x++) {
						TerminoPrecioDTO item = precios.get(x);
						if (item.getFormato().equals(formatos[j]) && item.getRelease().equals(variable[i]) && item.getIdPais().equals(paises.get(k).getIdPais())) {
							datos[indFilaPais][(k * 2) + 2] = item.getMoneda();
							datos[indFilaPais][(k * 2) + 3] = item.getDolar();
							break;
						}

					}
				}
				indFilaPais++;
			}

		}
		return datos;
	}
	
	
	public Integer obtenerAplicaPrecios(Long idContrato, String seccion){
		   return dao.obtenerAplicaPrecios(idContrato, seccion);
	}
	
	public Integer obtenerPagoPpe(Long idContrato, String seccion){
		   return dao.obtenerPagoPpe(idContrato, seccion);
	}

	public String[][] obtenerDatosPrecioMovSer(String[] formatos, List<TerminosPaisDTO> paises, String[] variable, Integer numeroReg, List<TerminoPrecioDTO> precios) {

		String[][] datosTemp = new String[variable.length * formatos.length][(paises.size() * 2) + 2];
		int indFilaPais = 0;

		for (int i = 0; i < variable.length; i++) {
			for (int j = 0; j < formatos.length; j++) {
				for (int k = 0; k < paises.size(); k++) {
					for (int x = 0; x < ListaUtilerias.safeList(precios).size(); x++) {
						TerminoPrecioDTO item = precios.get(x);
						if (item.getFormato().equals(formatos[j]) && item.getRelease().equals(variable[i]) && item.getIdPais().equals(paises.get(k).getIdPais())) {
							datosTemp[indFilaPais][0] = variable[i];
							datosTemp[indFilaPais][1] = formatos[j];
							datosTemp[indFilaPais][(k * 2) + 2] = item.getMoneda();
							datosTemp[indFilaPais][(k * 2) + 3] = item.getDolar();
							break;
						}

					}
				}
				indFilaPais++;
			}

		}

		List<String[]> lista = new ArrayList<String[]>(Arrays.asList(datosTemp));
		Iterator<String[]> it = lista.iterator();

		while (it.hasNext()) {
			int z = 0;
			String item[] = it.next();
			for (int y = 0; y < item.length; y++)
				if (item[y] == null || item[y].trim().equals(""))
					z++;

			if (item.length == z)
				it.remove();
		}

		String[][] datos = lista.toArray(new String[][] {});
		return datos;
	}
	
	
	public void guardarDatosPrecios(PrecioRentaDTO precioRenta, Long[]idRealeses, Long idContrato, String seccion) throws TransaccionException{							
		try
		{									
			
			Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);
			//dao.eliminarValoresPrecio(idContrato, seccion);
			
			List<TerminosPrecioDTO> precios = new ArrayList<TerminosPrecioDTO>();	
			String datos[][]  = precioRenta.getPrecio();
			
			logger.info("datos: {}", java.util.Arrays.deepToString(datos));
			logger.info("idRealeses: {}",java.util.Arrays.toString(idRealeses));
			logger.info("paises: {}",paises);
	        logger.info("formatos: {}",formatos);
	        logger.info("seccion: {} {}", seccion, idSeccion);

			
			int indiceFila = 0;
		    for(int i=0; i< idRealeses.length; i++)
		    {
		    	for(int j=0; j< this.formatos.size(); j++)
		    	{		    		
			    	for(int k=0; k< this.paises.size(); k++) //this.paises.size()
			    	{		
			    		TerminosPrecioDTO precio = new TerminosPrecioDTO();			    		
			    
			    		String moneda =  datos[indiceFila][(k * 2) + 2] == null ? null : datos[indiceFila][(k * 2) + 2].trim(); 
			    		String dolar  =  datos[indiceFila][(k * 2) + 3] == null ? null : datos[indiceFila][(k * 2) + 3].trim();
			    		precio = this.generarPrecioDTO(idRealeses[i], this.formatos.get(j).getIdPais(), this.paises.get(k).getIdPais(), moneda, dolar);			    		
			    		precios.add(precio);
			    	}
			    	
		    		indiceFila++;
		    	}		    	
			}	
		    
		    dao.guardarValoresPrecio(precios, idContrato, seccion);
		    
			for (TerminosPaisDTO pais : precioRenta.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);
		}  				
	}

	public PrecioRentaDTO obtenerDatosPreciosLibreria(Long idContrato, String seccion){						
		List<TerminoPrecioDTO> precios = dao.obtenerPrecioLibreria(idContrato);
		PrecioRentaDTO precio = new PrecioRentaDTO();
		
		this.formatos = dao.obtenerFormatos();
		
		Integer aplica = dao.obtenerAplicaPrecios(idContrato, seccion);
		Integer pagoPpe = dao.obtenerPagoPpe(idContrato, seccion);
		
		this.obtenerCatalogos(idContrato, seccion);		
		
		precio.setPaises(this.paises);
		
		String [][] datos = new String[formatos.size()][(paises.size()*2)+1];
		
		if(precios == null || precios.isEmpty())
		{															
			for(int j=0; j<formatos.size(); j++)														
				datos[j][0] = formatos.get(j).getDescripcion();															
		}
		else
		{														
			Long pais = 0l;
			int indFilaPais = 0;
			int indColPais  = 0;
			
			for(int i=0; i<precios.size(); i++)
			{
				if(pais.longValue() != precios.get(i).getIdPais().longValue())
				{
					for(int j=0; j<paises.size(); j++)
					{
						if(precios.get(i).getIdPais().longValue() == paises.get(j).getIdPais().longValue())
						{
							pais = paises.get(j).getIdPais();
							indColPais = j;
							break;
						}						  
					}	
					indFilaPais = 0;
				}
								
				datos[indFilaPais][0] = precios.get(i).getFormato();
				datos[indFilaPais][(indColPais*2)+1] = precios.get(i).getMoneda();
				datos[indFilaPais][(indColPais*2)+2] = precios.get(i).getDolar();
				indFilaPais++;
			}
						
		}	
		
		precio.setAplica(aplica == null ? 1 : aplica);
		precio.setPagoPPE(pagoPpe == null ? 0 : pagoPpe);
		
		precio.setPrecio(datos);
		return precio;
	}
	
	public void guardarDatosPreciosLibreria(PrecioRentaDTO precioLibreria, Long idContrato, String seccion) throws TransaccionException{							
		try
		{	
			List<TerminosPrecioDTO> precios = new ArrayList<TerminosPrecioDTO>();			
			
			Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);

			
			String[][] datos = precioLibreria.getPrecio();
			
		    int indiceColumna = 1;		    	    
		    for(int k=0; k< this.paises.size(); k++) 
		    {		    				    	
			   	for(int j=0; j< this.formatos.size(); j++)
			   	{		
			   		TerminosPrecioDTO precio = new TerminosPrecioDTO();			    					    		
			   		String moneda =  datos[j][indiceColumna   ] == null ? null : datos[j][indiceColumna   ]; 
			   		String dolar  =  datos[j][indiceColumna +1] == null ? null : datos[j][indiceColumna +1];
			   		precio = this.generarPrecioDTO(null, this.formatos.get(j).getIdPais(), this.paises.get(k).getIdPais(), moneda, dolar);			    		
			   		precios.add(precio);			   		
			   	}
			   	indiceColumna = indiceColumna +2;			   	
		    }		    								    
		    dao.guardarValoresPrecioLibreria(precios, idContrato);
		    
			for (TerminosPaisDTO pais : precioLibreria.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);
		}  				
	}
	
	public List<TerminosPrecioDTO> generarDatosMoviesSeries(String datos[][], Long idContrato, List<TerminosPaisDTO> categorias, List<TerminosPaisDTO> formatos, List<TerminosPaisDTO> paises) throws TransaccionException{							
		List<TerminosPrecioDTO> precios = new ArrayList<TerminosPrecioDTO>();
		logger.debug(datos.toString());
		try
		{				
			for(int i=0; i< datos.length; i++)
			{				
				int indiceColumna = 2;		    	    
		    	for(int k=0; k< paises.size(); k++) //
		    	{		    				    		
			    	TerminosPrecioDTO precio = new TerminosPrecioDTO();			    		
			    		
			    	String moneda  =  datos[i][indiceColumna   ] == null ? null : datos[i][indiceColumna   ]; 
			    	String dolar   =  datos[i][indiceColumna +1] == null ? null : datos[i][indiceColumna +1];
			    	long idRelease =  this.obtenerId(categorias, datos[i][0]);
			    	long idFormato =  this.obtenerId(formatos, datos[i][1]);
			    	precio = this.generarPrecioDTO(idRelease, idFormato, paises.get(k).getIdPais(), moneda, dolar);			    					    					    		
			    	precios.add(precio);			    	
			    	indiceColumna = indiceColumna +2;
		    	}								
			}
																						    		 
		}catch(Exception e)
		{
			throw new TransaccionException("Se genero un error al guardar los datos.", e);
		}  				
		return precios;
	}

	public Long obtenerId(List<TerminosPaisDTO> catalogo, String buscar){
		Long id = null;
		for(int i=0; i< catalogo.size(); i++)
		{				
			if(catalogo.get(i).getDescripcion().equals(buscar))
				id = catalogo.get(i).getIdPais();
		}
		return id;
	}
	
	public TerminosPrecioDTO generarPrecioDTO(Long idRelease, Long idFormato, Long idPais, String moneda, String dolar){		
		TerminosPrecioDTO precio = new TerminosPrecioDTO();
		precio.setIdRelease(idRelease);
		precio.setIdFormato(idFormato);
		precio.setIdPais(idPais);
		precio.setDolar(dolar);
		precio.setMoneda(moneda);
		return precio;
	}
	
	public void obtenerCatalogos(Long idContrato, String 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.formatos = dao.obtenerFormatos();											
		this.paises   = paises;							
	}

	public void eliminarPreciosPremium(Long idContrato, String seccion){
		dao.eliminarValoresPrecio(idContrato, seccion);		
	}
	
	public void eliminarPreciosLibreria(Long idContrato){
		dao.eliminarValoresPrecioLibreria(idContrato);
	}
	
	public void eliminarPreciosMovies(Long idContrato){
		dao.eliminarPrecioMovies(idContrato); 
	}
	
	public void eliminarPreciosSeries(Long idContrato){
		dao.eliminarPrecioSeries(idContrato); 
	}
	
	
	
	public void eliminarPaisesImpuestoEstatus(Long idContrato, String seccion){
		dao.eliminarPaisesImpuestoEstatus(idContrato, seccion);
	}
	
	public void actualizarPrecioAplica(Long idContrato, String seccion, Integer aplica){
		dao.actualizarAplicaPrecios(idContrato, seccion, aplica);		
	}
	public List<TerminosPaisDTO> getFormatos() { return formatos; }

	public List<TerminosPaisDTO> getPaises() {return paises; }
	
	public void actualizarPagoPpe(Long idContrato, String seccion, Integer pagoPpe){
		dao.actualizarPagoPpe(idContrato, seccion, pagoPpe);		
	}
	
}
