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

import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

import org.apache.ibatis.executor.result.ResultMapException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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.Estatus;
import com.mx.dla.dda.contrato.titulo.dtos.Lista;
import com.mx.dla.dda.contrato.titulo.exception.TituloException;
import com.mx.dla.dda.contrato.transaccion.exceptions.dtos.TransaccionException;
import com.mx.dla.dda.contrato.transaccion.titulos.daos.TituloTransDAO;
import com.mx.dla.dda.contrato.transaccion.titulos.dtos.TituloTransDB;
import com.mx.dla.dda.contrato.transaccion.titulos.dtos.TituloTransaccionDTO;
import com.mx.dla.dda.general.utilerias.ListaUtilerias;
import com.mx.dla.global.bos.BaseBO;

@Component
public class TituloTranRules extends BaseBO {

	@Autowired
	private TitulosBussinesTranBO titulosBussinesBO;

	@Autowired
	private TituloTransDAO tituloDAO;

	@Autowired
	private GeneralesDAO generalesDAO;

	public void validaEntrada(TituloTransaccionDTO titulo)
			throws TransaccionException, ResultMapException, SQLException {

		try {
			this.validaVentanaTitulo(titulo);
			this.validaHvrdTitulo(titulo, Arrays.asList(titulo));
		} catch (TituloException e) {
			throw new TransaccionException("Error al cargar los datos", e);
		}

	}

	public void validaHvrdTitulo(TituloTransaccionDTO cambio, List<TituloTransaccionDTO> validaEn)
			throws TituloException {

		logger.info("cambio: {}", cambio);
		logger.info("validaEn: {}", validaEn);

		for (TituloTransaccionDTO item : ListaUtilerias.safeList(validaEn)) {

			logger.info("cambio.getHvrd(): {}", cambio.getHvrd());
			logger.info("item.getFechaInicio(): {}", item.getFechaInicio());

			if (cambio.getHvrd() != null && item.getFechaInicio() != null
					&& cambio.getHvrd().after(item.getFechaInicio())) {
				logger.info("Se cumple!!");
				throw new TituloException("Fecha HVRD no puede ser posterior a Fecha inicio");
			}
		}
	}

	public void validaVentanaTitulo(TituloTransaccionDTO titulo)
			throws TituloException, ResultMapException, SQLException, TransaccionException {

		List<TituloTransDB> titulos = null;
		List<TituloTransDB> tmirror = null;

		ContratoDTO fechas = titulosBussinesBO.calculaFechasInicioFinValidacion(titulo.getIdContrato());

		ContratoDTO contrato = generalesDAO.obtenerContrato(titulo.getIdContrato());
		contrato.setIdEstatus(Estatus.Vigente.getValor());
		logger.info("{}", TituloTranUtil.getTituloType(titulo));
		titulo.setTypeTitulo(TituloTranUtil.getTituloType(titulo));

		logger.info("validaVentanaTitulo: {}", titulo);

		if (titulo.getFechaInicio() != null && titulo.getFechaFin() != null
				&& titulo.getFechaFin().before(titulo.getFechaInicio()))
			throw new TituloException("Fecha fin no puede ser anterior a Fecha inicio");

		if (titulo.getFechaInicio() != null && (fechas.getFechaInicio().after(titulo.getFechaInicio())
				|| fechas.getFechaFin().before(titulo.getFechaInicio())))
			throw new TituloException("Fecha de exhibición fuera de rango");

		titulos = tituloDAO.titulosVentanaEnContrato(titulo, contrato, Lista.REAL);
		logger.info(": {}", titulos);
		tmirror = tituloDAO.titulosVentanaEnContrato(titulo, contrato, Lista.MIRROR);
		logger.info(": {}", tmirror);
		if ((titulos != null && titulos.size() > 0) || (tmirror != null && tmirror.size() > 0))
			throw new TituloException("Este título se encuentra en este periodo en exhibición en el contrato.");

		titulos = tituloDAO.titulosVentanaEnNoTransaccionales(titulo, contrato);
		logger.info(": {}", titulos);
		if (titulos != null && titulos.size() > 0)
			throw new TituloException(
					"Este título se encuentra en este periodo en exhibición en un contrato no transaccional ("
							+ titulos.get(0).getNombreEstandar() + ")");

		titulos = tituloDAO.titulosVentanaEnTransaccionales(titulo, contrato);
		logger.info(": {}", titulos);
		if (titulos != null && titulos.size() > 0)
			throw new TituloException(
					"Este título se encuentra en este periodo en exhibición en otro contrato transaccional ("
							+ titulos.get(0).getNombreEstandar() + ")");

	}

	public void cuentaOcurrenciasEnOtrosContratos(TituloTransaccionDTO t) throws TituloException {
		Integer ocurrences = tituloDAO.buscarTitulosOtrosContratosXBV(t.getFechaInicio(), t.getFechaFin(), t.getIdBv(),
				t.getIdLista());

		if (ocurrences != null && ocurrences.intValue() != 0)
			throw new TituloException("El título ya se encuentra en otro contrato en el mismo id BroadView");

		ocurrences = 0;
		ocurrences = tituloDAO.buscarTitulosListaXBV(t.getFechaInicio(), t.getFechaFin(), t.getIdBv(), t.getIdLista(),
				t.getIdTituloCnt());

		if (ocurrences != null && ocurrences.intValue() != 0)
			throw new TituloException("El título ya se encuentra en la misma lista con el mismo id BroadView");
	}

	public boolean verificarSerieNueva(TituloTransaccionDTO titulo) {
		boolean valido = true;

		if (tituloDAO.findCategoriaTrans(titulo.getCategoria()) != 1)
			valido = false;
		logger.debug("serie categoria {}", valido);
		if (valido && (!isNumeric(titulo.getEpisodio()) || Integer.parseInt(titulo.getEpisodio()) < 1))
			valido = false;
		logger.debug("serie episodio {}", valido);
		if (valido && (!isNumeric(titulo.getTemporada()) || Integer.parseInt(titulo.getTemporada()) < 0))
			valido = false;
		logger.debug("serie temporada {}", valido);
		if (valido && tituloDAO.findSerieSeasonTrans(titulo.getNombreUnico(), titulo.getTemporada()) > 1)
			valido = false;
		logger.debug("serie existe {}", valido);
		return valido;
	}

	private static boolean isNumeric(String cadena) {
		try {
			Integer.parseInt(cadena);
			return true;
		} catch (NumberFormatException nfe) {
			return false;
		}
	}

}
