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.FeesPremierDTO;
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 FeesPremierTransaccioBO extends BaseBO{

	@Autowired
	private FeesTransaccionDAO dao;

	@Autowired
	private FeesGuardarTransaccioBO comun;
	
	private List<FeesTImpuestoDTO> paises;
	private List<FormatoDTO>       formatos;
	private String[]               releases;
	private Long  []               idRealeses;
	
	public FeesPremierDTO obtenerFeesTransaccion(Long idContrato, String fechaInicio, String fechaFin) throws ResultMapException, SQLException, TransaccionException{		
		FeesPremierDTO fees = new FeesPremierDTO();
		try
		{
			fees =  this.obtenerCatalogos    (fees, idContrato);
			fees =  this.obtenerDatosMinimos (fees, idContrato, fechaInicio, fechaFin);
			fees =  this.obtenerDatosRelease (fees, idContrato);
			fees =  this.obtenerDatosPrecios (fees, idContrato);
			fees =  this.obtenerDatosRevenue (fees, idContrato);						
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al obtener datos de Fees.", e);
        } catch (DataAccessException e) {
        	throw new TransaccionException("Error al obtener datos de Fees.", e);
        }				
		return fees;
	}
	
	public FeesPremierDTO obtenerDatosMinimos(FeesPremierDTO fees, Long idContrato, String fechaInicio, String fechaFin){				
		List<FeesTMinValoresDTO> valoresAnio = dao.obtenerMinimosAnioValoresPremier(idContrato);
		List<FeesTMinimoDTO>     valoresCat  = dao.obtenerMinimosPremier(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())
		{						
			Long [] idsCategorias = new Long[valoresCat.size()];
			for(int i=0; i< valoresCat.size(); i++)
				idsCategorias[i] = valoresCat.get(i).getIdCategoria();
			
			fees.setIdCatMin(idsCategorias);			
			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 FeesPremierDTO obtenerDatosRelease(FeesPremierDTO fees, Long idContrato){
		
		List<FeesTMinimoDTO> valores = dao.obtenerReleasePremier(idContrato);
		String [][] datos = {{null, null, null}};
		Long   []   ids   = null;
		
		if(valores != null && !valores.isEmpty())		
		{
			ids   = new Long[valores.size()];
			datos = new String[valores.size()][3];						
			
			for(int i=0; i<valores.size(); i++)
			{
				ids[i]      = valores.get(i).getIdCategoria();
				datos[i][0] = String.valueOf(valores.get(i).getDesde());
				datos[i][1] = String.valueOf(valores.get(i).getHasta());
				datos[i][2] = String.valueOf(valores.get(i).getCategoria());			
			}	
		}		 				
		fees.setIdCatRel(ids);
		fees.setDatosReleases(datos);		
		return fees;
	}
	
	public FeesPremierDTO obtenerDatosImpuesto(FeesPremierDTO fees, Long idContrato){											
		List<FeesTImpuestoDTO> impuestos = dao.obtenerImpuestosPremier(idContrato);		
		String [][] datos  = FeesTransaccionUtileria.obtenerDatosImpuesto(impuestos, this.paises);								
		fees.setDatosImpuestos(datos);				
		return fees;
	}
		
	public FeesPremierDTO obtenerDatosPrecios(FeesPremierDTO fees, Long idContrato ){	
		this.releases = new String[fees.getDatosReleases().length];
		for(int i=0; i<fees.getDatosReleases().length; i++)
			this.releases[i] = fees.getDatosReleases()[i][2];
				
		List<Integer>      numeroReg = dao.obtenerNumRegPrecios(idContrato);
		List<FeesTPrecioDTO> precios = numeroReg == null || numeroReg.isEmpty() ? null : dao.obtenerPrecioPremier(idContrato);					
		String [][]           datos  = FeesTransaccionUtileria.obtenerDatosPrecio(fees.getFormatos(), this.paises, releases, numeroReg, precios);
		fees.setDatosPrecio(datos);								        		
		return fees;										
	}
	
	public FeesPremierDTO obtenerDatosRevenue(FeesPremierDTO fees, Long idContrato){		
		List<FeesTRevenueDTO> revenue = dao.obtenerRevenuePremier(idContrato);
		String [][]           datos   = FeesTransaccionUtileria.obtenerDatosRevenue(revenue, this.releases);							
		fees.setDatosRevenue(datos);		
		return fees;		
	}
	
	public FeesPremierDTO guardarFeesTransaccion(Long idContrato, String fechaInicio, String fechaFin, FeesPremierDTO fees) throws ResultMapException, SQLException, TransaccionException{		
				
		try
		{		
			//se borran los datos eliminados en pantalla minimos, releases
			if(fees.getIdCatEli() != null && fees.getIdCatEli().length > 0)			
			   this.eliminarCategoriasMinimos(fees.getIdCatEli());			
			
			if(fees.getIdsRelEli() != null && fees.getIdsRelEli().length > 0)			
			   this.eliminarCategoriasRelease(fees.getIdsRelEli());
			
			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.guardarDatosRelease (fees.getDatosReleases() , fees.getIdCatRel(), idContrato);
			//this.guardarDatosImpuesto(fees.getDatosImpuestos(), idContrato);
			this.guardarDatosPrecios (fees.getDatosPrecio()   , idContrato);
			this.guardarDatosRevenue (fees.getDatosRevenue()  , idContrato);
			
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al guardar los datos.", e);	
        } catch (DataAccessException e) {
        	throw new TransaccionException("Error al guardar los datos.", e);	
        }					
		return fees;
	}
	
	public void eliminarCategoriasMinimos(Long[] ids){		
		 dao.eliminarCategValMinimos(ids);
		 dao.eliminarCategMinimos   (ids);		 
	}
	
	public boolean verificarCategoriasMinimos(Long id){
		   return true;
	}
	
	public void eliminarCategoriasRelease(Long[] ids){
		  logger.debug(ids.toString());
		 dao.eliminarCategRevenueXRelease(ids);
		 dao.eliminarCategPrecioxRelease (ids);
		 dao.eliminarCategReleaseXRelease(ids);
	}

	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, "RP");
	}
	
	public void guardarDatosRelease(String datos[][], Long [] idRelease, Long idContrato) throws ResultMapException, SQLException, TransaccionException{							
		try
		{				
			idRealeses = new Long[idRelease.length];			
		    for(int j=0; j< idRelease.length; j++)
		    {
		    	FeesTMinimoDTO catMin = null;		    			
			    if(idRelease[j] == 0)
			    {			    	
			    	catMin = FeesTransaccionUtileria.generearMinimoDTO(datos[j][0], datos[j][1], datos[j][2], null, null, null);
			    	dao.guardarValoresReleasePremier(catMin, idContrato);
			    	idRelease[j] = catMin.getIdCategoria();
			    }
			    else
			    {
			    	catMin = FeesTransaccionUtileria.generearMinimoDTO(datos[j][0], datos[j][1], datos[j][2], null, null, idRelease[j]);
			        dao.editarValoresReleasePremier(catMin);
			    }							    
			    idRealeses[j] = idRelease[j];
			}		    		    				    			    			    
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al guardar los datos.", e);	
        } catch (DataAccessException e) {
        	throw new TransaccionException("Error al guardar los datos.", e);	
        } 				
	}
	
	public void guardarDatosImpuesto(String datos[][], Long idContrato) throws ResultMapException, SQLException, TransaccionException{							
	    comun.guardarDatosImpuesto(datos, idContrato, "RP", this.paises);
	}

	public void guardarDatosPrecios(String datos[][], Long idContrato) throws ResultMapException, SQLException, TransaccionException{							
		try
		{									
			dao.eliminarValoresPrecioPremier();
			
			List<FeesTPrecioDTO> precios = new ArrayList<FeesTPrecioDTO>();
			this.formatos = dao.getFormatos();			
			
			int indiceFila = 0;
		    for(int i=0; i< this.idRealeses.length; i++)
		    {
		    	int indiceColumna = 2;		    	    
		    	for(int k=0; k< this.paises.size(); k++) //this.paises.size()
		    	{		    		
		    		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.idRealeses[i], this.formatos.get(j).getIdFormato(), this.paises.get(k).getIdPais(), moneda, dolar);			    		
			    		precios.add(precio);
			    		indiceFila++;
			    	}
			    	indiceColumna = indiceColumna +2;
		    	}		    	
			}				    
		    dao.guardarValoresPrecioPremier(precios, idContrato);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al guardar los datos.", e);	
        } catch (DataAccessException e) {
        	throw new TransaccionException("Error al guardar los datos.", e);	
        }				
	}
	
	public void guardarDatosRevenue(String datos[][], Long idContrato) throws ResultMapException, SQLException, TransaccionException{							
		try
		{									
			dao.eliminarValoresRevenuePremier(idContrato);			
			List<FeesTRevenueDTO> revenues = new ArrayList<FeesTRevenueDTO>();									
			
		    for(int i=0; i< this.idRealeses.length; i++)
		    {
		    	FeesTRevenueDTO revenue = FeesTransaccionUtileria.generearFeesTRevenueDTO(this.idRealeses[i], datos[i][1], datos[i][2]);
		    	revenues.add(revenue);
			}				    		    
		    dao.guardarValoresRevenuePremier(revenues, idContrato);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al guardar los datos.", e);	
        } catch (DataAccessException e) {
        	throw new TransaccionException("Error al guardar los datos.", e);	
        }				
	}
	
	public FeesPremierDTO obtenerCatalogos(FeesPremierDTO fees, Long idContrato){
		
		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);
		
		return fees;
	}
}