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

import java.util.ArrayList;
import java.util.List;

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

import com.mx.dla.dda.contrato.fees.daos.FeesContratoDAO;
import com.mx.dla.dda.contrato.transaccion.terminos.daos.TerminosTransaccionDAO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.FsCategoriaMGDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.FsPeriodoCatDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.FsPeriodoDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.FsSeccionDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.MinimoGarantizadoDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.MinimoTipos;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.RevenueTipos;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.TerminoMinimoDTO;
import com.mx.dla.global.bos.BaseBO;

@Service
public class TerminosMinimos extends BaseBO{

	@Autowired
	private TerminosTransaccionDAO dao;
	
	@Autowired
	private FeesContratoDAO     feesContratoDAO;
	
	private String anios[];
	private String revenue[][];
	private List<FsCategoriaMGDTO> categoriasMg;
	private Long idSeccion;
	
	public MinimoGarantizadoDTO obtenerMinimos(Long idContrato, String seccion){		
		MinimoGarantizadoDTO minimo = new MinimoGarantizadoDTO();
		String [][] periodos   = null;
		String [][] categorias = null;
		String         tipoMin = "";

		String fechaInicio = feesContratoDAO.fechaInicio(idContrato); 
		String fechaFin    = feesContratoDAO.fechaFin   (idContrato);  
				
		boolean na = this.obtenerMinimosNA(idContrato, seccion);				
		if(!na)
		{
			periodos = this.obtenerMinimosPeriodo(idContrato, seccion);
			if(periodos == null)
			   categorias = this.obtenerMinimosCategoria(idContrato, seccion);			
		}
		
		if(!na && periodos == null && categorias != null)
		{  
			periodos = new String[1][3];
			periodos[0][0] = null;
			periodos[0][1] = null;
			periodos[0][2] = null;
			tipoMin = "categoria";
		}
		else if(!na && periodos != null && categorias == null)
		{
			categorias = new String[1][4];
			categorias[0][0] = null;
			categorias[0][1] = null;
			categorias[0][2] = "MFTV/MFV";
			categorias[0][3] = null;
			this.anios    = new String[1];
			this.anios[0] = fechaInicio + "-" + fechaFin;
			tipoMin = "anio";
		}
		if(periodos == null && categorias == null)
		{
			 logger.debug("inicio");
		     na = true;
		     tipoMin = "na";
		     periodos = new String[1][3];
			 periodos[0][0] = null;
			 periodos[0][1] = null;
			 periodos[0][2] = null;
			 
			 categorias = new String[1][4];
			 categorias[0][0] = null;
			 categorias[0][1] = null;
			 categorias[0][2] = "MFTV/MFV";
			 categorias[0][3] = null;
			 this.anios    = new String[1];
			 this.anios[0] = fechaInicio + "-" + fechaFin;	            	            				 	
		}
		
		minimo.setAnios(this.anios);
		minimo.setMinimosCateg(categorias);
		minimo.setMinimosAnio(periodos);
		minimo.setNa(na);
		minimo.setTipoMin(tipoMin);
		logger.debug(""+minimo.toString());
		return minimo;
	}
	
	public boolean obtenerMinimosNA(Long idContrato, String seccion){
		Integer result = dao.obtenerMinimosNA(idContrato, seccion);
		if(result != null  && result.intValue() > 0)
			return true;
		else return false;
	}
	
	public String[][] obtenerMinimosPeriodo(Long idContrato, String seccion){
		 		
		List<TerminoMinimoDTO> minimos = dao.obtenerMinimosPeriodo(idContrato, seccion);
		String datos[][]               = null;		   
		   
		if(minimos != null && !minimos.isEmpty())			  		   
		{
		   datos = new String[minimos.size()][3];
		   int fila = 0;
		   for(TerminoMinimoDTO m : minimos)
		   {
			   datos[fila][0] = m.getFechaInicio() + "-" + m.getFechaFin();
			   datos[fila][1] = String.valueOf(m.getMinimo());
			   datos[fila][2] = String.valueOf(m.getAplicaMG());
			   fila++;
		   }
		}
		return datos;
	}
	
	public String[][] obtenerMinimosCategoria(Long idContrato, String seccion){		
		   List<TerminoMinimoDTO> minimos = dao.obtenerMinimosCategoria(idContrato, seccion);
		   List<String> periodos          = dao.obtenerMinPeriodosCategoria(idContrato, seccion);
		   List<String> categorias        = dao.obtenerMinCatsCategoria(idContrato, seccion);
		   String datos[][]               = null;		   
		   
		   if(minimos != null && !minimos.isEmpty())			  		   
		   {
			   categorias = this.removeRepetidas(categorias);
			   datos      = new String[categorias.size()][periodos.size()+3];			   
			   anios      = new String[periodos.size()];
			   
			   int fila = 0;
			   for(String categoria: categorias)
			   {
				   List<TerminoMinimoDTO> minCat = this.obtenerCategoria(categoria, minimos);
				   				   			  
				   for(TerminoMinimoDTO m : minCat)
				   {
					   datos[fila][0] = String.valueOf(m.getDesde());
					   datos[fila][1] = String.valueOf(m.getHasta());
					   datos[fila][2] = String.valueOf(m.getCategoria());
					   
					   int columna = 0;
					   for(int i=0; i<periodos.size(); i++)
					   {
						   if(periodos.get(i).equals(m.getFechaInicio()))
						   {
							   columna = i+3;
							   if(fila == 0)
								  anios[i] = m.getFechaInicio()+"-"+m.getFechaFin();
						   }							   
					   }						   							   
					   datos[fila][columna] = String.valueOf(m.getMinimo());					   
				   }  				   
				   fila++;
			   }			   
		   }		   		
		   return datos;
	} 
	
	public List<String> removeRepetidas(List<String> categorias){		
		
		 List<String> cats = new ArrayList<String>();
		 cats.add(categorias.get(0));
		 for(int i=1; i< categorias.size(); i++)
		 {
			 boolean encontrado = false;
			 for(int j=0; j< cats.size(); j++)
			 {
				 if( cats.get(j).equals(categorias.get(i)) )				 
					 encontrado = true;				 
			 }
			 if(!encontrado)
				cats.add(categorias.get(i));
		 }
		 return cats;
	}
	
	public  List<TerminoMinimoDTO> obtenerCategoria(String Categoria,  List<TerminoMinimoDTO> minimos){
		List<TerminoMinimoDTO> cats= new ArrayList<TerminoMinimoDTO>();
		for(TerminoMinimoDTO m : minimos)
		{
			if(m.getCategoria().compareTo(Categoria) == 0)
			   cats.add(m);
		}
		return cats;
	}

	public void guardarMinimos(String[][] minimosCat, String[][] minimosAnio, String anios[], String tipo, String seccion, Long idContrato){	
		   FsSeccionDTO seccionTab = new FsSeccionDTO();
		   seccionTab.setSeccion(seccion);
		   seccionTab.setIdContrato(idContrato);
		   this.eliminarMinimos(idContrato, seccion);
		   
		   if(tipo.compareTo("na") == 0)
		   {
			   seccionTab.setTipoMinimo("NA");			   
			   dao.guardarSeccionMinimo(seccionTab);
			   idSeccion = seccionTab.getIdSeccion();
			   
			   /*FsCategoriaMGDTO cm = new FsCategoriaMGDTO();
			   cm.setIdSeccion(seccionTab.getIdSeccion());
			   cm.setIdContrato(idContrato);
			   cm.setDesde(0.0);
			   cm.setHasta(0.0);
			   cm.setCategoriaMg("");
			   dao.guardarCategoriaMinimos(cm);
			   */			   
		   }
	       else if(tipo.compareTo("categoria") == 0)
	       {
	    	   categoriasMg = new ArrayList<FsCategoriaMGDTO>();
	    	   List<FsPeriodoDTO> periodos = new ArrayList<FsPeriodoDTO>();
	    	   seccionTab.setTipoMinimo("CATEGORIA");
	    	   dao.guardarSeccionMinimo(seccionTab);
	    	   idSeccion = seccionTab.getIdSeccion();
	    	   
	    	   for(int i=0; i<anios.length; i++)
	    	   {
	    		   String []splitRes = anios[i].split("-");
	    		   logger.debug(""+splitRes.length);
	    		   FsPeriodoDTO periodo = new FsPeriodoDTO();
	    		   periodo.setIdContrato (idContrato);
	    		   periodo.setIdSeccion  (seccionTab.getIdSeccion());
	    		   periodo.setFechaInicio(splitRes[0]);
	    		   periodo.setFechaFin   (splitRes[1]);
	    		   periodo.setTipo("MINIMO");
	    		   dao.guardarPeridoMinimos(periodo);
	    		   periodos.add(periodo);
	    	   }
			   
	    	   for(int i=0; i<minimosCat.length; i++)
	    	   {
	    		   FsCategoriaMGDTO categoria = new FsCategoriaMGDTO();
	    		   categoria.setDesde(minimosCat[i][0] != null ? Double.parseDouble(minimosCat[i][0]) : 0);
	    		   categoria.setHasta(minimosCat[i][1] != null ? Double.parseDouble(minimosCat[i][1]) : 0);
	    		   categoria.setCategoriaMg(minimosCat[i][2]);
	    		   categoria.setIdContrato(idContrato);
	    		   categoria.setIdSeccion(seccionTab.getIdSeccion());	    		   	    		   
	    		   
	    		   dao.guardarCategoriaMinimos(categoria);
	    		   categoriasMg.add(categoria);
	    		   
	    		   FsPeriodoCatDTO perCat = new FsPeriodoCatDTO();
	    		   for(int j=0; j<anios.length; j++)
	    		   {
	    			   perCat.setIdFsCategoriaMG(categoria.getIdFsCategoriaMG());
	    			   perCat.setIdPeriodo(periodos.get(j).getIdPeriodo());
	    			   perCat.setMinimo(Double.parseDouble(minimosCat[i][j+3]));
	    			   dao.guardarPerCategaMinimos(perCat);
	    		   }	    			   	    			   
	    	   }	    	   	    	   
		   }
		   else if(tipo.compareTo("anio") == 0)
		   {
			   seccionTab.setTipoMinimo("PERIODO");
			   dao.guardarSeccionMinimo(seccionTab);
			   idSeccion = seccionTab.getIdSeccion();
			   for(int i=0; i<minimosAnio.length; i++)
	    	   {
	    		   FsPeriodoDTO periodo = new FsPeriodoDTO();
	    		   periodo.setIdContrato (idContrato);
	    		   periodo.setIdSeccion  (seccionTab.getIdSeccion());
	    		   periodo.setFechaInicio(minimosAnio[i][0].split("-")[0]);
	    		   periodo.setFechaFin   (minimosAnio[i][0].split("-")[1]);
	    		   periodo.setAplicaMG(minimosAnio[i][2]);
	    		   periodo.setMinimo(Double.parseDouble(minimosAnio[i][1]));
	    		   periodo.setTipo("MINIMO");
	    		   dao.guardarPeridoMinimos(periodo);	    		   
	    	   }
		   }
	}
	
	public void eliminarMinimos(Long idContrato, String seccion){
		dao.eliminarRelease(idContrato, seccion);
		dao.eliminarPerCategaMinimos(idContrato, seccion);		
		dao.eliminarPeridoMinimos   (idContrato, seccion);
		dao.eliminarCategoriaMinimos(idContrato, seccion);								
		dao.eliminarSeccionMinimo   (idContrato, seccion);		
	}
	
	public String obtenerTipoMinimo(Long idContrato, String seccion){
		String tipo = dao.obtenerTipoMinimo(idContrato, seccion);
		return tipo == null ? MinimoTipos.NA.getDesc() : tipo;
	}
	
	public String[]   getAnios  () { return anios; }
	public String[][] getRevenue() { return revenue; }
	public List<FsCategoriaMGDTO> getCategorias() {return categoriasMg; }
	public Long getIdSeccion() { return idSeccion; }
	
	
	
}