	package com.rjconsultores.ventaboletos.dao.hibernate;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.rjconsultores.ventaboletos.dao.AidfDAO;
import com.rjconsultores.ventaboletos.entidad.Aidf;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.Estado;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.vo.aidf.AidfVo;

@Repository("aidfDAO")
public class AidfHibernateDAO extends GenericHibernateDAO<Aidf, Long> implements AidfDAO {

	private static final Logger log = LogManager.getLogger(AidfHibernateDAO.class);

	@Autowired
	public AidfHibernateDAO(
			@Qualifier("sessionFactory") SessionFactory factory) {
		setSessionFactory(factory);
	}

	@Override
	public List<Aidf> obtenerTodos() {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));

		return (List<Aidf>) c.list();
	}

	@Override
	public List<AidfVo> obtenerAidfFromSerieDocfiscal(String serie, String subSerie, String docfiscal, Connection conn,Integer empresaId) {

		PreparedStatement pstmt = null;
		ResultSet rs = null;

		StringBuilder sb = new StringBuilder();
		sb.append(" select x.AIDF_ID, ");
		sb.append(" x.ESTADO_ID, ");
		sb.append(" REGEXP_REPLACE( x.docfiscal ,'[^[:alnum:]'' '']', NULL) , ");
		sb.append(" x.ACFISCAL, ");
		sb.append(" x.SERIE, ");
		sb.append(" x.FORMINICIAL, ");
		sb.append(" x.FORMFINAL, ");
		sb.append(" x.FECADQUISICION, ");
		sb.append(" x.FECVENCIMIENTO, ");
		sb.append(" x.INSCESTADUAL, ");
		sb.append(" x.EMPRESA_ID, ");
		sb.append(" x.AIDFESP_ID, ");
		sb.append(" x.AIDFTIPO_ID, ");
		sb.append(" x.ACTIVO, ");
		sb.append(" x.FECMODIF, ");
		sb.append(" x.USUARIO_ID, ");
		sb.append(" x.SUBSERIE, ");
		sb.append(" x.CNPJ, ");
		sb.append(" x.TIPOVALIDAVENTA ");
		sb.append(" from AIDF x where x.SERIE = '" + serie + "' ");
		
		if( subSerie !=null && !subSerie.equals("") ) {
			sb.append(" AND x.SUBSERIE = '" + subSerie + "' ");
		}
		
		if( docfiscal != null ) {
			sb.append("   and REGEXP_REPLACE( x.docfiscal ,'[^[:alnum:]'' '']', NULL) like '" + docfiscal + "'  ");
		}
		if (empresaId != null){
			sb.append(" and x.EMPRESA_ID = ").append(empresaId);
		}
		sb.append(" and x.activo = 1 ");

		List<AidfVo> ls = new ArrayList<AidfVo>();

		try {
			pstmt = conn.prepareStatement(sb.toString());

			rs = pstmt.executeQuery();
			while (rs.next()) {
				AidfVo a = new AidfVo();
				a.setAidfId(rs.getLong(1));
				a.setDocfiscal(rs.getString(3));
				a.setSerie(rs.getString(5));
				a.setSubserie(rs.getString(17)!=null?rs.getString(17):"");
				a.setForminicial(rs.getString(6));
				a.setFormfinal(rs.getString(7));
				ls.add(a);
			}
		} catch (Exception e) {
			log.error("", e);
		} finally {
			try {
				rs.close();
			} catch (Exception ignore) {
				log.error("", ignore);
			}
			try {
				pstmt.close();
			} catch (Exception ignore) {
				log.error("", ignore);
			}
			try {
				conn.close();
			} catch (Exception ignore) {
				log.error("", ignore);
			}

		}
		
		return ls;
	};

	@Override
	public List<Aidf> buscaAidfsPorEmpresas(List<Empresa> empresas) {

		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		c.add(Restrictions.in("empresa", empresas));

		return (List<Aidf>) c.list();
	}
	
	@Override
	public List<Aidf> buscaAidfsPorEmpresaAgencia(Empresa empresa, PuntoVenta pontoVenda) {

		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		c.add(Restrictions.eq("empresa", empresa));
		c.add(Restrictions.eq("puntoVenta", pontoVenda));

		return (List<Aidf>) c.list();
	}

	public Boolean existeAidfComCodFiscalEEstado(Long idAidf, Integer especieId, String docFiscal, Estado estado) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq("estado", estado));
		c.add(Restrictions.eq("docfiscal", docFiscal));

		if (idAidf != null) {
			c.add(Restrictions.ne("aidfId", idAidf));
		}

		if (especieId != null) {
			c.add(Restrictions.eq("aidfEspecie.aidfespId", especieId));
		}

		return c.list().isEmpty();
	}

	@Override
	public List<Aidf> buscaAidfEstadoEmpresa(Integer empresaId, Integer estadoId, Boolean isRMD) {

		StringBuilder sb = new StringBuilder();
		sb.append(" from Aidf ");
		sb.append(" where activo = :activo ");
		sb.append("       and estado.estadoId = :estadoId ");
		sb.append("       and empresa.empresaId = :empresaId ");
		if(isRMD){
			sb.append("   and aidfEspecie.decespecie = 'RMD' ");
		}
		
		Query query = getSession().createQuery(sb.toString());

		query.setBoolean("activo", Boolean.TRUE);
		query.setInteger("estadoId", estadoId);
		query.setInteger("empresaId", empresaId);

		return (List<Aidf>) query.list();
	}

	public String buscaUltimoAidfRMDUtilizado(Long idAidf, Integer empresaId, Integer estadoId) {
		StringBuilder sb = new StringBuilder();
		sb.append(" select max(to_number(folio)) as ultimo ");
		sb.append(" from folio_consumo_rmd ");
		sb.append(" where activo = 1 ");
		sb.append(" and (indimpresso = 1  or indcancelacion = 1) ");
		sb.append(" and rmd_id = :rmdId ");
		sb.append(" and empresa_id = :empresaId ");
		sb.append(" and estado_id = :estadoId ");

		Query query = getSession().createSQLQuery(sb.toString());
		query.setLong("rmdId", idAidf);
		query.setInteger("empresaId", empresaId);
		query.setInteger("estadoId", estadoId);

		Object resp = query.uniqueResult();

		Integer aux = resp == null ? null : Integer.parseInt(resp.toString());
		if (aux != null)
			aux++;
		return aux == null ? null : aux.toString();
	}

	@Override
	public boolean vaidaRMDUtilizado(Long idAidf, Integer empresaId, Integer estadoId, String folio) {
		StringBuilder sb = new StringBuilder();
		sb.append(" select max(to_number(folio)) as ultimo ");
		sb.append(" from folio_consumo_rmd ");
		sb.append(" where activo = 1 ");
		sb.append(" and (indimpresso = 1  or indcancelacion = 1) ");
		sb.append(" and rmd_id = :rmdId ");
		sb.append(" and empresa_id = :empresaId ");
		sb.append(" and estado_id = :estadoId ");
		sb.append(" and folio = :folio ");

		Query query = getSession().createSQLQuery(sb.toString());
		query.setLong("rmdId", idAidf);
		query.setInteger("empresaId", empresaId);
		query.setInteger("estadoId", estadoId);
		query.setString("folio", folio);

		Object resp = query.uniqueResult();
		return resp == null ? true : false;
	}

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

		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq("estado", estado));
		c.add(Restrictions.eq("puntoVenta", puntoVenta));
		c.add(Restrictions.eq("docfiscal", docFiscal));
		c.add(Restrictions.eq("forminicial", formInicial));
		c.add(Restrictions.eq("formfinal", formFinal));

		if (idAidf != null) {
			c.add(Restrictions.ne("aidfId", idAidf));
		}

		if (especieId != null) {
			c.add(Restrictions.eq("aidfEspecie.aidfespId", especieId));
		}
		return c.list().isEmpty();
	}

}
