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

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.executor.result.ResultMapException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import com.mx.dla.dda.catalogos.dtos.FormatoDTO;
import com.mx.dla.dda.contrato.transaccion.exceptions.dtos.TransaccionException;
import com.mx.dla.dda.contrato.transaccion.fees.daos.FeesTransaccionDAO;
import com.mx.dla.dda.contrato.transaccion.fees.dtos.FeesEstDTO;
import com.mx.dla.dda.contrato.transaccion.fees.dtos.FeesTImpuestoDTO;
import com.mx.dla.dda.contrato.transaccion.fees.dtos.FeesTMinValoresDTO;
import com.mx.dla.dda.contrato.transaccion.fees.dtos.FeesTMinimoDTO;
import com.mx.dla.dda.contrato.transaccion.fees.dtos.FeesTPrecioDTO;
import com.mx.dla.dda.contrato.transaccion.fees.dtos.FeesTRevenueDTO;
import com.mx.dla.global.bos.BaseBO;

@Service
public class FeesEstTransaccioBO extends BaseBO{

	@Autowired
	private FeesTransaccionDAO dao;

	@Autowired
	private FeesGuardarTransaccioBO comun;
	
	private List<FeesTImpuestoDTO> paises;
	private List<FormatoDTO>       formatos;
	private List<FormatoDTO>       series;
	private List<FormatoDTO>       tiers;
	
	public FeesEstDTO obtenerFeesEst(Long idContrato, String fechaInicio, String fechaFin) throws ResultMapException, SQLException, TransaccionException{		
		FeesEstDTO fees = new FeesEstDTO();		
		try
		{
			fees =  this.obtenerCatalogos            (fees, idContrato);
			fees =  this.obtenerDatosMinimos         (fees, idContrato, fechaInicio, fechaFin);											
			fees =  this.obtenerDatosImpuesto        (fees, idContrato);						
			fees =  this.obtenerDatosDTOMovies       (fees, idContrato);						
			fees =  this.obtenerDatosDTOMoviesRevenue(fees, idContrato);						
			fees =  this.obtenerDatosDTOSeries       (fees, idContrato);
			fees =  this.obtenerDatosDTOSeriesRevenue(fees, idContrato);
						
		} catch (PersistenceException e) {
            throw new TransaccionException("Error al cargar los datos.", e);
        } catch (DataAccessException e) {
            throw new TransaccionException("Error al cargar los datos", e);
        }
		return fees;
	}
	
	public FeesEstDTO obtenerDatosMinimos(FeesEstDTO fees, Long idContrato, String fechaInicio, String fechaFin){		
		List<FeesTMinValoresDTO> valoresAnio = dao.obtenerMinimosAnioValoresEst(idContrato);
		List<FeesTMinimoDTO>     valoresCat  = dao.obtenerMinimosEst(idContrato);
		
		String [][] datos = FeesTransaccionUtileria.obtenerDatosMinimos(valoresAnio, valoresCat);
		String []   anios = FeesTransaccionUtileria.anios;
										
		if(valoresAnio != null && !valoresAnio.isEmpty())
		{		
			fees.setDatosMinAnio(datos);
			fees.setAniosMin(anios);			
		}
		else if(valoresCat != null  && !valoresCat.isEmpty())
		{						
			fees.setDatosMin(datos);
			fees.setAniosMin(anios);				
		}
		else
		{			
			int numAnios = comun.obtenerNumAnios(fechaInicio, fechaFin).intValue();
			
			String [][] datosMin  = new String[1][numAnios+3];
		    String [][] datosAnio = new String[1][numAnios];
            String anios1[]  = new String[numAnios]; 
            
            datosMin [0][0] = null;
            datosMin [0][1] = null;
            datosMin [0][2] = "MFTV/MFV";
            for(int i=0; i< numAnios; i++)
            {
            	anios1[i] = fechaInicio+"-"+fechaFin;
            	datosAnio[0][i] = null;
            	datosMin [0][i+3] = null;
            }
            	            	
			fees.setDatosMin(datosMin);
			fees.setDatosMinAnio(datosAnio);
			fees.setAniosMin(anios1);				
		}											
		return fees;
	}
			
	public FeesEstDTO obtenerDatosImpuesto(FeesEstDTO fees, Long idContrato){			
		List<FeesTImpuestoDTO> impuestos = dao.obtenerImpuestosEst(idContrato);		
		String [][] datos                = FeesTransaccionUtileria.obtenerDatosImpuesto(impuestos, this.paises);								
		fees.setDatosImpuestos(datos);				
		return fees;
	}
		
	public FeesEstDTO obtenerDatosDTOMovies(FeesEstDTO fees, Long idContrato){		
		List<Integer>      numeroReg = dao.obtenerNumRegPreciosMovies(idContrato);
		List<FeesTPrecioDTO> precios = numeroReg == null || numeroReg.isEmpty() ? null : dao.obtenerPrecioMovies(idContrato);		
		String [][]           datos  = FeesTransaccionUtileria.obtenerDatosPrecio(fees.getFormatos(), this.paises, fees.getTier(), numeroReg, precios);
		fees.setDatosDTOMovies(datos);								        		
		return fees;
	}
	
	public FeesEstDTO obtenerDatosDTOMoviesRevenue(FeesEstDTO fees, Long idContrato){						
		List<FeesTRevenueDTO> revenue = dao.obtenerRevenueMovies(idContrato);
		String [][]           datos   = FeesTransaccionUtileria.obtenerDatosRevenue(revenue, fees.getTier());							
		fees.setDatosRevenueMovies(datos);		
		return fees;
	}
	
	public FeesEstDTO obtenerDatosDTOSeries(FeesEstDTO fees, Long idContrato){		
		List<Integer>      numeroReg = dao.obtenerNumRegPreciosSeries(idContrato);
		List<FeesTPrecioDTO> precios = numeroReg == null || numeroReg.isEmpty() ? null : dao.obtenerPrecioSeries(idContrato);		
		String [][]           datos  = FeesTransaccionUtileria.obtenerDatosPrecio(fees.getFormatos(), this.paises, fees.getCatSeries(), numeroReg, precios);
		fees.setDatosDTOSeries(datos);								        		
		return fees;										      
	}
	
	public FeesEstDTO obtenerDatosDTOSeriesRevenue(FeesEstDTO fees, Long idContrato){		
		List<FeesTRevenueDTO> revenue = dao.obtenerRevenueSeries(idContrato);
		String [][]           datos   = FeesTransaccionUtileria.obtenerDatosRevenue(revenue, fees.getCatSeries());							
		fees.setDatosRevenueSeries(datos);		
		return fees;				
	}
	
	public void guardarFeesEst(Long idContrato, String fechaInicio, String fechaFin, FeesEstDTO fees) throws ResultMapException, SQLException, TransaccionException{		
		
		try
		{		
			//se borran los datos eliminados en pantalla minimos			
			
			String datosMin[][] = fees.getIdCatMin() != null && fees.getDatosMin() != null ? fees.getDatosMin() : fees.getDatosMinAnio();
			boolean anio        = fees.getDatosMin() == null && fees.getDatosMinAnio() != null ? true: false;
			boolean categoria   = fees.getDatosMin() != null && fees.getDatosMinAnio() == null ? true: false;			
			
			this.guardarDatosMinimos (datosMin, fees.getAniosMin(), fees.getIdCatMin(), categoria, anio, idContrato);				
			this.guardarDatosImpuesto(fees.getDatosImpuestos(), idContrato);
			this.guardarDatosPreciosMovies (fees.getDatosDTOMovies() , idContrato);
			this.guardarDatosPreciosSeries(fees.getDatosDTOSeries(), idContrato);
			this.guardarDatosRevenueMovies(fees.getDatosRevenueMovies(), idContrato);
			this.guardarDatosRevenueSeries(fees.getDatosRevenueSeries(), idContrato);
		} catch (PersistenceException e) {
            throw new TransaccionException("Error al cargar los datos.", e);
        } catch (DataAccessException e) {
            throw new TransaccionException("Error al cargar los datos", e);
        }						
	}
	
	public void guardarDatosMinimos(String datos[][], String anios[], Long [] idCat, Boolean isCategoria, Boolean isAnnio, Long idContrato) throws ResultMapException, SQLException, TransaccionException{							
	    comun.guardarDatosMinimos(datos, anios, idCat, isCategoria, isAnnio, idContrato, "VT");
	}
	
	public void guardarDatosImpuesto(String datos[][], Long idContrato) throws ResultMapException, SQLException, TransaccionException{							
	    comun.guardarDatosImpuesto(datos, idContrato, "VT", this.paises);
	}

	public void guardarDatosPreciosMovies(String datos[][], Long idContrato) throws ResultMapException, SQLException, TransaccionException{							
		try
		{												
			dao.eliminarValoresPrecioMovies(idContrato);
			
			List<FeesTPrecioDTO> precios = new ArrayList<FeesTPrecioDTO>();
			this.formatos = dao.getFormatos();			
			
			int indiceFila = 0;
		    for(int i=0; i< this.tiers.size(); i++)
		    {
		    	int indiceColumna = 2;		    	    
		    	for(int k=0; k< this.paises.size(); k++) //
		    	{		    		
		    		indiceFila = i == 0 ? 0 : i*3;
			    	for(int j=0; j< this.formatos.size(); j++)
			    	{		
			    		FeesTPrecioDTO precio = new FeesTPrecioDTO();			    		
			    		
			    		String moneda =  datos[indiceFila][indiceColumna   ] == null ? null : datos[indiceFila][indiceColumna   ]; 
			    		String dolar  =  datos[indiceFila][indiceColumna +1] == null ? null : datos[indiceFila][indiceColumna +1];
			    		precio = FeesTransaccionUtileria.generearFeesTPrecioDTO(this.tiers.get(i).getIdFormato(), this.formatos.get(j).getIdFormato(), this.paises.get(k).getIdPais(), moneda, dolar);			    					    					    		
			    		precios.add(precio);
			    		indiceFila++;
			    	}
			    	indiceColumna = indiceColumna +2;
		    	}		    	
			}				    
		    dao.guardarValoresPrecioMovies(precios, idContrato);
		}catch (PersistenceException e) {
			throw new TransaccionException("Se genero un error al guardar los datos.", e);
        } catch (DataAccessException e) {
        	throw new TransaccionException("Se genero un error al guardar los datos.", e);
        } 				
	}
		
	public void guardarDatosPreciosSeries(String datos[][], Long idContrato) throws ResultMapException, SQLException, TransaccionException{							
		try
		{												
			logger.debug(datos.toString());
			dao.eliminarValoresPrecioSeries(idContrato);
			
			List<FeesTPrecioDTO> precios = new ArrayList<FeesTPrecioDTO>();
			this.formatos = dao.getFormatos();			
			
			int indiceFila = 0;
		    for(int i=0; i< this.series.size(); i++)
		    {
		    	int indiceColumna = 2;		    	    
		    	for(int k=0; k< this.paises.size(); k++) //
		    	{		    		
		    		indiceFila = i == 0 ? 0 : i*3;
			    	for(int j=0; j< this.formatos.size(); j++)
			    	{		
			    		FeesTPrecioDTO precio = new FeesTPrecioDTO();			    		
			    		
			    		String moneda =  datos[indiceFila][indiceColumna   ] == null ? null : datos[indiceFila][indiceColumna   ]; 
			    		String dolar  =  datos[indiceFila][indiceColumna +1] == null ? null : datos[indiceFila][indiceColumna +1];
			    		precio = FeesTransaccionUtileria.generearFeesTPrecioDTO(this.tiers.get(i).getIdFormato(), this.formatos.get(j).getIdFormato(), this.paises.get(k).getIdPais(), moneda, dolar);			    					    		
			    		precios.add(precio);
			    		indiceFila++;
			    	}
			    	indiceColumna = indiceColumna +2;
		    	}		    	
			}				    
		    dao.guardarValoresPrecioSeries(precios, idContrato);
		} catch (PersistenceException e) {
			throw new TransaccionException("Se genero un error al guardar los datos.", e);
        } catch (DataAccessException e) {
        	throw new TransaccionException("Se genero un error al guardar los datos.", e);
        } 				
	}
	
	public void guardarDatosRevenueMovies(String datos[][], Long idContrato) throws ResultMapException, SQLException, TransaccionException{							
		try
		{									
			dao.eliminarValoresRevenueMovies(idContrato);			
			List<FeesTRevenueDTO> revenues = new ArrayList<FeesTRevenueDTO>();									
			
		    for(int i=0; i< this.tiers.size(); i++)
		    {
		    	FeesTRevenueDTO revenue = FeesTransaccionUtileria.generearFeesTRevenueDTO(this.tiers.get(i).getIdFormato(), datos[i][1], datos[i][2]);
		    	revenues.add(revenue);
			}				    		    
		    dao.guardarValoresRevenueMovies(revenues, idContrato);
		} catch (PersistenceException e) {
			throw new TransaccionException("Se genero un error al guardar los datos.", e);
        } catch (DataAccessException e) {
        	throw new TransaccionException("Se genero un error al guardar los datos.", e);
        } 				
	}
	
	public void guardarDatosRevenueSeries(String datos[][], Long idContrato) throws ResultMapException, SQLException, TransaccionException{							
		try
		{									
			dao.eliminarValoresRevenueSeries(idContrato);			
			List<FeesTRevenueDTO> revenues = new ArrayList<FeesTRevenueDTO>();									
			
		    for(int i=0; i< this.series.size(); i++)
		    {
		    	FeesTRevenueDTO revenue = FeesTransaccionUtileria.generearFeesTRevenueDTO(this.series.get(i).getIdFormato(), datos[i][1], datos[i][2]);
		    	revenues.add(revenue);
			}				    		    
		    dao.guardarValoresRevenueSeries(revenues, idContrato);
		} catch (PersistenceException e) {
			throw new TransaccionException("Se genero un error al guardar los datos.", e);
        } catch (DataAccessException e) {
        	throw new TransaccionException("Se genero un error al guardar los datos.", e);
        }  				
	}
	
	public FeesEstDTO obtenerCatalogos(FeesEstDTO fees, Long idContrato){
								
		this.series = dao.obtenerCatSeries();
		this.tiers  = dao.obtenerTiers();
		
		String series [] = new String[this.series.size()];
		
		for(int i=0; i<this.series.size(); i++)
			series[i] = this.series.get(i).getDescripcion();							
		fees.setCatSeries(series);
		
		
		List<String> formatosL = dao.obtenerFormatos();
		String formatos [] = new String[formatosL.size()];
		
		for(int i=0; i<formatosL.size(); i++)
			formatos[i] = formatosL.get(i);							
		fees.setFormatos(formatos);
		
		paises = dao.obtenerPaisesPremier(idContrato);		
		String paisesStr[] = new String[paises.size()];		
									
		for(int i=0; i< paises.size();i++)
			paisesStr[i] = paises.get(i).getPais();		
		fees.setPaises(paisesStr);
				
		
		String tiers [] = new String[this.tiers.size()];
		
		for(int i=0; i<this.tiers.size(); i++)
			tiers[i] = this.tiers.get(i).getDescripcion();							
		fees.setTier(tiers);
		
		return fees;
	}
}