package com.rjconsultores.ventaboletos.service.impl;

import java.sql.Connection;
import java.util.Calendar;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.rjconsultores.ventaboletos.dao.AidfDAO;
import com.rjconsultores.ventaboletos.dao.AidfEspecieDAO;
import com.rjconsultores.ventaboletos.dao.AidfTipoDAO;
import com.rjconsultores.ventaboletos.entidad.Aidf;
import com.rjconsultores.ventaboletos.entidad.AidfEspecie;
import com.rjconsultores.ventaboletos.entidad.AidfTipo;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.Estado;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.service.AidfService;
import com.rjconsultores.ventaboletos.service.MovimentacionBilhetesService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.vo.aidf.AidfVo;

@Service("aidfService")
public class AidfServiceImpl implements AidfService {

	private static final Integer TIPO_FORMULARIO_CONTINUO = 1;
	private static final Integer TIPO_VENDA_MANUAL = 2;

	@Autowired
	private AidfDAO aidfDAO;

	@Autowired
	private AidfEspecieDAO aidfEspecieDAO;

	@Autowired
	private AidfTipoDAO aidfTipoDAO;

	@Autowired
	private MovimentacionBilhetesService movimentacionBilhetesService;

	public List<Aidf> obtenerTodos() {
		return aidfDAO.obtenerTodos();
	}

	@Transactional
	public Aidf obtenerID(Long id) {
		return aidfDAO.obtenerID(id);
	}

	@Transactional
	public Aidf suscribir(Aidf entidad) {
		setUsuarioFecmodifActivo(entidad);

		Aidf aidf = aidfDAO.suscribir(entidad);

		/*
		 * Mantis #9124 Desativado devido a lentidão ao criar o AbastoCentrol e AbastoHisto. if (aidf != null) movimentacionBilhetesService.realizaAdquisicionBilhetes(aidf);
		 */

		return aidf;
	}

	@Transactional
	public Aidf actualizacion(Aidf entidad) {
		setUsuarioFecmodifActivo(entidad);
		return aidfDAO.actualizacion(entidad);
	}

	@Transactional
	public void borrar(Aidf entidad) {
		setUsuarioFecmodifActivo(entidad);
		entidad.setActivo(Boolean.FALSE);
		aidfDAO.actualizacion(entidad);
	}

	private void setUsuarioFecmodifActivo(Aidf entidad) {
		entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		entidad.setFecmodif(Calendar.getInstance().getTime());
		entidad.setActivo(Boolean.TRUE);
	}

	public List<AidfEspecie> obtenerTodosAdifEspecie() {
		return aidfEspecieDAO.obtenerTodos();
	}

	public List<AidfTipo> obtenerTodosAdifTipo() {
		return aidfTipoDAO.obtenerTodos();
	}

	public List<Aidf> buscaAidfsPorEmpresas(List<Empresa> empresas) {
		return aidfDAO.buscaAidfsPorEmpresas(empresas);
	}
	
	public List<Aidf> buscaAidfsPorEmpresaAgencia(Empresa empresa, PuntoVenta pontoVenda){
		return aidfDAO.buscaAidfsPorEmpresaAgencia(empresa, pontoVenda);
	}
	
	public List<AidfVo> obtenerAidfFromSerieDocfiscal(String serie, String subSerie, String docfiscal, Connection conn,Integer empresaId) {
		return aidfDAO.obtenerAidfFromSerieDocfiscal(serie, subSerie, docfiscal, conn,empresaId);
	}

	public Long validarDocFiscalSerieFormInicialFinal(Aidf entidad, Connection conn) {

		List<AidfVo> list = obtenerAidfFromSerieDocfiscal(
				entidad.getSerie(), entidad.getSubserie(), entidad.getDocfiscal().replaceAll("[^a-zA-Z0-9]+", ""), conn,entidad.getEmpresa().getEmpresaId());

		for (AidfVo aidf : list) {
			// desconsiderar o próprio ID, caso contrário o erro de validação sempre acontece qdo o registro é editado.
			if ((entidad.getAidfId() == null) || (aidf.getAidfId().compareTo(entidad.getAidfId()) != 0)) {
				if (aidf.getDocfiscal().trim().equals(entidad.getDocfiscal().replaceAll("[^a-zA-Z0-9]+", "").trim())) {
					if (aidf.getSerie().trim().equals(entidad.getSerie().trim())) {
						if ((Long.parseLong(entidad.getForminicial()) >= Long.parseLong(aidf.getForminicial()) && Long.parseLong(entidad.getForminicial()) <= Long.parseLong(aidf.getFormfinal()))
								|| (Long.parseLong(entidad.getFormfinal()) >= Long.parseLong(aidf.getForminicial()) && Long.parseLong(entidad.getFormfinal()) <= Long.parseLong(aidf.getFormfinal()))) {
							return aidf.getAidfId();
						}
					}
				}
			}
		}
		return -1l;
	}
	
	public Long validarSerieFormInicialFinal(Aidf entidad, Connection conn) {

		List<AidfVo> list = obtenerAidfFromSerieDocfiscal(entidad.getSerie(), entidad.getSubserie(), null, conn,entidad.getEmpresa().getEmpresaId());

		for (AidfVo aidf : list) {
			// desconsiderar o próprio ID, caso contrário o erro de validação sempre acontece qdo o registro é editado.
			if ((entidad.getAidfId() == null) || (aidf.getAidfId().compareTo(entidad.getAidfId()) != 0)) {				
				if (aidf.getSerie().trim().equals(entidad.getSerie().trim())) {
					if (entidad.getSubserie() != null && aidf.getSubserie().equals(entidad.getSubserie())) {
						if ((Long.parseLong(entidad.getForminicial()) >= Long.parseLong(aidf.getForminicial()) && Long.parseLong(entidad.getForminicial()) <= Long.parseLong(aidf.getFormfinal()))
								|| (Long.parseLong(entidad.getFormfinal()) >= Long.parseLong(aidf.getForminicial()) && Long.parseLong(entidad.getFormfinal()) <= Long.parseLong(aidf.getFormfinal()))) {
							return aidf.getAidfId();
						}
					}
				}				
			}
		}
		return -1l;
	}

	public Boolean validarDocFiscalPorEstado(Long idAidf, Integer especieId, String docFiscal, Estado estado) {
		return aidfDAO.existeAidfComCodFiscalEEstado(idAidf, especieId, docFiscal, estado);
	}

	public Boolean validarTipoVenda(String tipoVenda, String serie, Integer idTipo) {
		return !("M".equals(tipoVenda)
				&& ("UNIC".equals(serie) || TIPO_FORMULARIO_CONTINUO.equals(idTipo)));
	}

	public Boolean validarVendaManual(Integer idTipo, String serie) {
		return !(TIPO_VENDA_MANUAL.equals(idTipo) && "UNIC".equals(serie));
	}

	@Override
	public List<Aidf> buscaAidfEstadoEmpresa(Integer empresaId, Integer estadoId, Boolean isRMD) {
		return aidfDAO.buscaAidfEstadoEmpresa(empresaId, estadoId, isRMD);
	}

	@Override
	public String buscaUltimoAidfRMDUtilizado(Long idAidf, Integer empresaId, Integer estadoId) {
		return aidfDAO.buscaUltimoAidfRMDUtilizado(idAidf, empresaId, estadoId);
	}

	@Override
	public boolean vaidaRMDUtilizado(Long idAidf, Integer empresaId, Integer estadoId, String folio) {
		return aidfDAO.vaidaRMDUtilizado(idAidf, empresaId, estadoId, folio);
	}

	@Override
	public Boolean validarDocFiscalPorEstadoAgencia(Long idAidf, Integer especieId, String docFiscal, String formInicial, String formFinal, Estado estado, PuntoVenta puntoVenta) {
		return aidfDAO.validarDocFiscalPorEstadoAgencia(idAidf, especieId, docFiscal, formInicial, formFinal, estado, puntoVenta);

	}


}
