package com.mx.dla.dda.contrato.titulo.bos;

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

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

import com.mx.dla.dda.catalogos.daos.CatalogosDAO;
import com.mx.dla.dda.catalogos.dtos.CatalogoDTO;
import com.mx.dla.dda.contrato.common.bos.CommonRestBO;
import com.mx.dla.dda.contrato.generales.daos.GeneralesDAO;
import com.mx.dla.dda.contrato.generales.dtos.ContratoDTO;
import com.mx.dla.dda.contrato.generales.enums.Movimiento;
import com.mx.dla.dda.contrato.titulo.constants.TipoCambioTitulo;
import com.mx.dla.dda.contrato.titulo.daos.ListaDAO;
import com.mx.dla.dda.contrato.titulo.daos.TituloDAO;
import com.mx.dla.dda.contrato.titulo.daos.TituloDmDAO;
import com.mx.dla.dda.contrato.titulo.dtos.Lista;
import com.mx.dla.dda.contrato.titulo.dtos.SapNum;
import com.mx.dla.dda.contrato.titulo.dtos.Titulo;
import com.mx.dla.dda.contrato.titulo.exception.TituloException;
import com.mx.dla.dda.contrato.titulo.rules.TituloRules;
import com.mx.dla.global.bos.BaseBO;

@Component
public class TituloGridBO extends BaseBO {

	@Autowired
	private TituloDmDAO tituloDmDAO;

	@Autowired
	protected TituloDAO tituloDAO;

	@Autowired
	protected ListaDAO listaDAO;

	@Autowired
	protected CatalogosDAO catalogosDAO;

	@Autowired
	protected GeneralesDAO generalesDAO;

	@Autowired
	protected CommonRestBO commonRestBO;

	@Autowired
	protected TituloRules tituloRules;

	@Autowired
	protected TitulosBussinesBO titulosBussinesBO;

	@Autowired
	private TitulosUtilBO titulosUtilBO;

	public String alta(ContratoDTO c, Lista l, Titulo t) throws TituloException {
		logger.info("Alta. Titulo [{}]", t);
		String serie = null;
		if (tituloRules.verificarSerieNueva(t))
			serie = "El sistema generará automáticamente" + t.getEpisodio() + " los episodios de " + t.getDescTitulo();
		else {
			guardaTitulo(c, l, t);
			titulosBussinesBO.actualizaCostoTodosLosTitulos(c);
		}
		return serie;
	}

	public void altaSeriesAuto(ContratoDTO c, Lista l, Titulo t) throws TituloException {
		logger.info("Alta Serie. Titulo [{}]", t);
		int numEpisodios = Integer.parseInt(t.getEpisodio());
		String nombre = t.getDescTitulo() + ": Episodio # ";

		for (int i = 1; i <= numEpisodios; i++) {
			String name = nombre + i;
			guardaTitulo(c, l, titulosUtilBO.getTituloSerieAuto(t, name, String.valueOf(i)));
		}
		titulosBussinesBO.actualizaCostoTodosLosTitulos(c);
	}

	public Titulo guardaTitulo(ContratoDTO c, Lista l, Titulo t) throws TituloException {
		t.setIdLista(l.getIdLista());
		tituloRules.validaEntrada(t, titulosBussinesBO.calculaFechasInicioFinValidacion(c));
		t = titulosUtilBO.getTituloGuardar(t, c);
		tituloDmDAO.insertarTitulo(t);
		return t;
	}

	public void cambio(ContratoDTO c, Lista l, Titulo t) throws TituloException {
		logger.info("Cambio. Titulo [{}]", t);
		tituloRules.validaEntrada(t, titulosBussinesBO.calculaFechasInicioFinValidacion(c));
		Titulo bd = tituloDmDAO.buscarTitulo(t.getIdTituloCnt());
		t = titulosUtilBO.copiarTitulo(t, bd);
		tituloDmDAO.actualizarTitulo(t);
		titulosBussinesBO.actualizaCostoTodosLosTitulos(c);
	}

	public void cambioMultiple(ContratoDTO c, Lista l, Titulo titulo, String tipoCambio, List<Long> idsTitulos)
			throws TituloException {

		titulo.setIdLista(l.getIdLista());

		if (TipoCambioTitulo.VENTANA.name().equals(tipoCambio)) {
			titulo.setVidaUtil(titulosUtilBO.calcularVidaUtil(titulo.getFechaInicio(), titulo.getFechaFin()));
			titulo.setMesesvu(titulosUtilBO.calculaMesesVidaUtil(titulo.getFechaInicio(), titulo.getFechaFin()));
			for (Long id : idsTitulos) {
				titulo.setIdTituloCnt(id);
				tituloDmDAO.actualizarTituloCambio(titulo);
			}
		}

		if (Movimiento.Adendum.getValor().longValue() == c.getIdTipoMovimiento().longValue()
				|| Movimiento.Original.getValor().longValue() == c.getIdTipoMovimiento().longValue()) {
			if (TipoCambioTitulo.CATEGORIA.name().equals(tipoCambio)) {
				CatalogoDTO cat = null;
				if (titulo.getPagoCateg() != null)
					cat = catalogosDAO.buscarCategoriaPagoPorDesc(c.getIdContrato(), titulo.getPagoCateg().getDesc());
				titulo.setPagoCateg(cat);
				titulo.setPrecioAnual(null);

				for (Long id : idsTitulos) {
					titulo.setIdTituloCnt(id);
					tituloDmDAO.actualizarTituloCambio(titulo);
				}
			}

			titulosBussinesBO.actualizaCostoTodosLosTitulos(c);
		} else if (Movimiento.Enmienda.getValor().longValue() == c.getIdTipoMovimiento().longValue()) {
			titulo.setIdTituloCnt(idsTitulos.get(0));
			if (TipoCambioTitulo.TRASLADAR.name().equals(tipoCambio))
				tituloRules.validaEntrada(titulo, titulosBussinesBO.calculaFechasInicioFinValidacion(c));

			titulosBussinesBO.verificarEnmiendaActualizacion(titulo, tipoCambio, c);
			titulosBussinesBO.actualizaCostoTodosLosTitulos(c);
			titulosBussinesBO.actualizarBanderasTraslados(c.getIdContrato());
		}

	}

	public void baja(ContratoDTO c, Titulo t) {
		logger.info("baja. Titulo [{}]", t);

		Titulo tbd = tituloDmDAO.buscarTitulo(t.getIdTituloCnt());
		if (tbd.getIdSap() == null)
			tituloDmDAO.borrarTitulo(t.getIdTituloCnt());
		else {
			tbd.setEstatus("ELIMINADO");
			tbd.setFechaContabilizacion(t.getFechaContabilizacion());
			if (tbd.getFechaNotifsap() != null)
				tbd.setBajaPerdida(t.getBajaPerdida());
			else
				tbd.setBajaPerdida(0L);
			tituloDmDAO.actualizarTitulo(tbd);
		}
	}

	public List<Titulo> busqueda(Titulo t, boolean calculaAmortizacion, String prefix) throws TituloException {
		List<Titulo> titulos = new ArrayList<Titulo>();

		titulos.addAll(tituloDmDAO.buscaTotalesLista(t.getIdLista(), prefix));
		titulos.addAll(tituloDmDAO.buscaDetallePeliculas(t.getIdLista(), prefix));
		logger.info(titulos.toString());
		List<Titulo> nombresUnicos = tituloDmDAO.buscaSerie1Capitulo(t.getIdLista(), prefix);
		List<Titulo> series = tituloDmDAO.buscaTotalesSerie(t.getIdLista(), t.getNombreUnico(), prefix);

		for (Titulo s : nombresUnicos) {
			int i = 0;
			for (Titulo tt : series) {
				if (tt.getNombreUnico().equals(s.getNombreUnico())) {
					series.remove(i);
					break;
				}
				i++;
			}
		}

		titulos.addAll(nombresUnicos);
		titulos.addAll(series);

		// Se quita transformacion de amortizaiciones de lista a mapa
		if (calculaAmortizacion) {
			for (Titulo tam : titulos) {
				HashMap<String, String> h = new HashMap<String, String>();
				if (tam.getAmortizaciones() != null) {
					for (CatalogoDTO cat : tam.getAmortizaciones()) {
						h.put(cat.getValue(), cat.getDesc());
					}
				}
				tam.setAmortizacionesH(h);
			}
		}
		return titulos;
	}

	public List<Titulo> busquedaDetalle(Titulo t, boolean calcularAmort, String prefix) throws TituloException {
		List<Titulo> titulos = new ArrayList<Titulo>();

		logger.info("t :{}", t);
		logger.info("calcularAmort :{}", calcularAmort);
		logger.info("prefix :{}", prefix);

		logger.info("buscaTotalesSerie :{}", tituloDmDAO.buscaTotalesSerie(t.getIdLista(), t.getNombreUnico(), prefix));
		logger.info("buscaDetalleSerie :{}", tituloDmDAO.buscaDetalleSerie(t.getIdLista(), t.getNombreUnico(), prefix));

		titulos.addAll(tituloDmDAO.buscaTotalesSerie(t.getIdLista(), t.getNombreUnico(), prefix));
		titulos.addAll(tituloDmDAO.buscaDetalleSerie(t.getIdLista(), t.getNombreUnico(), prefix));

		titulos.get(0).setAgrupable(0);

		if (calcularAmort) {
			for (Titulo tam : titulos) {
				HashMap<String, String> h = new HashMap<String, String>();
				if (tam.getAmortizaciones() != null) {
					for (CatalogoDTO cat : tam.getAmortizaciones()) {
						h.put(cat.getValue(), cat.getDesc());
					}
				}
				tam.setAmortizacionesH(h);
			}
		}

		logger.info("titulos :{}", titulos);

		return titulos;
	}

	public List<SapNum> getAumentosSapNumXTitulo(Long IdTituloCnt, Long idCto) {
		return tituloDmDAO.getAumentosSapNumXTitulo(IdTituloCnt, idCto);
	}
}