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

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
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.dtos.ContratoDTO;
import com.mx.dla.dda.contrato.titulo.daos.TituloDmDAO;
import com.mx.dla.dda.contrato.titulo.daos.TitulosAmortizacionDAO;
import com.mx.dla.dda.contrato.titulo.dtos.DatosAmortizacion;
import com.mx.dla.dda.contrato.titulo.dtos.Lista;
import com.mx.dla.dda.contrato.titulos.dtos.PresupuestoTitulo;
import com.mx.dla.dda.contrato.transaccion.exceptions.dtos.TransaccionException;
import com.mx.dla.dda.contrato.ws.validapresupuesto.ResponseValidaPresupuestoCntDTO;
import com.mx.dla.dda.contrato.ws.validarMinimoSeleccion.ResponseValidaMinimoSeleccionDTO;
import com.mx.dla.global.bos.BaseBO;

@Component
public class TituloAsyncBO extends BaseBO {

	@Autowired
	protected CatalogosDAO catalogosDAO;
	@Autowired
	private TituloDmDAO tituloDmDAO;
	@Autowired
	private TitulosAmortizacionDAO titulosAmortizacionDAO;
	@Autowired
	private CommonRestBO commonRestBO;

	public static DecimalFormat currency = new DecimalFormat("$###,###,###,###.##");
	public static DecimalFormat numeric = new DecimalFormat("###,###,###,###.##");

	public List<CatalogoDTO> buscaCategoriasDDATodas(ContratoDTO ct) {
		List<CatalogoDTO> cat = catalogosDAO.buscarCategoriaPagoTodosLosPeriodos(ct.getIdContrato());
		return cat;
	}

	public List<CatalogoDTO> buscaListas(ContratoDTO ct) {
		return catalogosDAO.buscarListasByContrato(ct.getIdContrato(), Lista.MIRROR);
	}

	public List<CatalogoDTO> buscaCategoriasDDAFecha(ContratoDTO ct) {
		return catalogosDAO.buscarCategoriaPago(ct.getIdContrato());
	}

	public List<CatalogoDTO> buscaCategoriaContrato(ContratoDTO ct) {
		return catalogosDAO.buscaCategoriasPorContrato(ct.getIdContrato());
	}

	public List<String> buscaSugerencias(ContratoDTO ct) {
		List<String> cat = catalogosDAO.buscarListaTitlosPorEstudio(ct.getIdEstudio());
		return cat;
	}

	public List<String> buscaSugerenciasCategoria(ContratoDTO ct) {
		List<CatalogoDTO> cat = catalogosDAO.buscarCategoriaPagoTodosLosPeriodos(ct.getIdContrato());
		List<String> c = new ArrayList<String>();
		for (CatalogoDTO ca : cat) {
			c.add(ca.getDesc());
		}
		return c;
	}

	/**
	 * Valida presupuesto y valida minimos de seleccion
	 * 
	 * @param ct
	 * @param l
	 * @param origen
	 * @return
	 */
	public PresupuestoTitulo buscarPresupuesto(ContratoDTO ct, Lista l, String origen) {
		PresupuestoTitulo p = new PresupuestoTitulo();

		logger.info("----------------------------------------");

		Long totalT = tituloDmDAO.cuentaTitulosPorListaYDescTitulo(l.getIdLista(), null, Lista.REAL);
		logger.info("Total Titulos [{}]", totalT);
		if (totalT != 0) {
			try {
				ResponseValidaPresupuestoCntDTO resp = new ResponseValidaPresupuestoCntDTO();
				resp = commonRestBO.validaPresupuesto(ct.getFechaInicio(), ct.getIdContrato(), origen);

				p.setAnioAmortizacion(String.valueOf(ct.getAnioAmortizacion()));

				Double monto = Double.parseDouble("0"); // Double.parseDouble(resp.getMontoAmortizable() != null ?
														// resp.getMontoAmortizable() : "0");
				Double otro = Double.parseDouble("0"); // Double.parseDouble(resp.getAmortizacionOtrosCnt() != null ?
														// resp.getAmortizacionOtrosCnt() : "0");
				Double diff = monto - otro;

				logger.info("monto {} otro {} ", monto, otro);
				logger.info("diff {} en string {}", diff, diff.toString());

				p.setAmortizableEstudio(currency.format(monto));
				p.setComprometidoEstudiod(currency.format(otro));
				p.setDisponibleEstudio(currency.format(diff));

				logger.info("{}", resp);

				if (!resp.getResultado())
					p.setAdvertencias(resp.getMensaje());

				if (resp.getResultado() && resp.getMensaje() != null)
					p.setMensajes(resp.getMensaje());

			} catch (IOException e) {
				logger.error("Error ", e);
				p.setErrores(Arrays.asList("Ocurrió un error en la validación de presupuesto"));
			} catch (TransaccionException e) {
				logger.error("Error ", e);
				p.setErrores(Arrays.asList("Ocurrió un error en la validación de presupuesto"));
			}

			try {

				ResponseValidaMinimoSeleccionDTO respmin = commonRestBO.validaMinimos(ct, origen);

				logger.info("{}", respmin);

				if (!respmin.getResultado())
					if (respmin.getErrores() != null)
						p.setAdvertencias(respmin.getErrores());

			} catch (IOException e) {
				logger.error("Error ", e);
				p.setErrores(Arrays.asList("Ocurrió un error en la validación de presupuesto"));
			} catch (TransaccionException e) {
				logger.error("Error ", e);
				p.setErrores(Arrays.asList("Ocurrió un error en la validación de presupuesto"));
			}
		}
		return p;
	}

	public DatosAmortizacion buscarDatosAmortizacion(ContratoDTO ct, Lista l) {
		DatosAmortizacion d = new DatosAmortizacion();
		Long total = tituloDmDAO.cuentaTitulosPorListaYDescTitulo(l.getIdLista(), null, Lista.REAL);
		Double monto = tituloDmDAO.buscarTotalCostoTitulos(ct.getIdContrato(), Lista.REAL);

		monto = monto == null ? 0 : monto;
		total = total == null ? 0 : total;

		logger.info("Total [{}] Mondo[{}] ", total, monto);

		d.setTotalTitulos(numeric.format(total));
		d.setTotalMonto(currency.format(monto));

		List<CatalogoDTO> c = titulosAmortizacionDAO.buscarAniosAmortizacionContrato(ct.getIdContrato());
		d.setAmortizaciones(c);

		return d;
	}

}
