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

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.exceptions.PersistenceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
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.license.titulo.daos.TituloFeeDmDAO;
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 TituloFeeAsyncBO extends BaseBO {

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

	@Autowired
	private TitulosAmortizacionDAO titulosAmortizacionDAO;

	@Autowired
	private CommonRestBO commonRestBO;

	@Autowired
	protected CatalogosDAO catalogosDAO;

	@Autowired
	private TituloFeeDmDAO tituloDmDAO;

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

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

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

	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;
	}

	/**
	 * Valida presupuesto y valida minimos de seleccion
	 * 
	 * @param ct
	 * @param l
	 * @param origen
	 * @return
	 * @throws TransaccionException
	 * @throws IOException
	 * @throws SocketTimeoutException
	 */
	public PresupuestoTitulo buscarPresupuesto(ContratoDTO ct, Lista l, String origen)
			throws TransaccionException, SocketTimeoutException, IOException {
		List<String> errors = new ArrayList<String>();
		List<String> mensajes = new ArrayList<String>();
		PresupuestoTitulo p = new PresupuestoTitulo();

		logger.debug("----------------------------------------");

		Long totalT = tituloDmDAO.cuentaTitulosPorListaYDescTitulo(l.getIdLista(), null, Lista.REAL);
		logger.debug("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 otro = Double.parseDouble("0");
				Double diff = monto - otro;

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

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

				if (!resp.getResultado()) {
					errors.add("Ocurrió un error en la validación de presupuesto");
				}

				if (resp.getResultado() && resp.getMensaje() != null) {
					mensajes.addAll(resp.getMensaje());
				}

			} catch (PersistenceException e) {
				throw new TransaccionException("Error al cargar los datos.", e);
			} catch (DataAccessException e) {
				throw new TransaccionException("Error al cargar los datos", e);
			}

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

			if (!respmin.getResultado()) {
				if (respmin.getErrores() != null) {
					errors.addAll(respmin.getErrores());
				}
			}
			p.setMensajes(mensajes);
			p.setErrores(errors);
		}
		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.debug("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;
	}

}