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.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();
		} 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;
	}

}