package com.rms.tfc.dao;

import java.math.BigInteger;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.rms.tfc.entity.Pedido;
import com.rms.tfc.util.LogUtil;
import com.rms.tfc.util.StringUtil;

@Repository
@Transactional
public class PedidoDaoImpl implements PedidoDao {

	@Autowired
    private SessionFactory sessionFactory;

    private final String className = "com.rms.tfc.dao.PedidoDaoImpl";
    
    public Long getNextId(){
    	int newId = 0;
    	Session session = null;
    	try{
			String queryStr = "SELECT IFNULL(MAX(idPedido), 0) + 1 FROM pedido";
			session = sessionFactory.openSession();
			newId = ((BigInteger) session.createSQLQuery(queryStr).uniqueResult()).intValue();
		} catch (Exception e){
			LogUtil.printLog(className, "Error obteniendo el siguiente Id");
			e.printStackTrace();
		} finally {
			if (session != null){
				session.close();
			}
		}
		return new Long(newId);
    }
    
    public synchronized Long createPedido(Pedido pedido){
    	Session session = null;
    	try{
    		session = sessionFactory.openSession();
			Transaction tx = session.getTransaction();
			if (!tx.isActive()){
               		tx.begin();
           		}
			session.save(pedido);
			tx.commit();
		} catch (Exception e){
			LogUtil.printLog(className, "Error al hacer el save del pedido");
			e.printStackTrace();
			return null;
		} finally {
			if (session != null){
				session.close();
			}
		}
		return pedido.getIdPedido();
	}
	
    public synchronized Pedido updatePedido(Pedido pedido){
    	Session session = null;
    	try{
    		session = sessionFactory.openSession();
			Transaction tx = session.getTransaction();
			if (!tx.isActive()){
               		tx.begin();
           		}
			session.update(pedido);
			tx.commit();
		} catch (Exception e){
			LogUtil.printLog(className, "Error al hacer el update del pedido");
			e.printStackTrace();
		} finally {
			if (session != null){
				session.close();
			}
		}
		return pedido;
	}
	
	public Pedido getPedidoById(Long idPedido){
		List<Pedido> lista = null;
		Session session = null;
		try{
            String queryStr = "SELECT * FROM pedido WHERE idPedido = " + idPedido;
            session = sessionFactory.openSession();
            lista = (List<Pedido>) session.createSQLQuery(queryStr).addEntity(Pedido.class).list();
        }catch (Exception e){
            LogUtil.printLog(className, "Error realizando la busqueda de pedido");
            e.printStackTrace();
        } finally {
			if (session != null){
				session.close();
			}
		}
        if (lista != null && lista.size() > 0){
            return (Pedido) lista.get(0);
        } else {
            return null;
        }
	}
	
	public List<Pedido> getAllPedidos(){
		List<Pedido> lista = null;
		Session session = null;
		try{
            String queryStr = "SELECT * FROM pedido ORDER BY idPedido";
            session = sessionFactory.openSession();
            lista = (List<Pedido>) session.createSQLQuery(queryStr).addEntity(Pedido.class).list();
        }catch (Exception e){
            LogUtil.printLog(className, "Error realizando la busqueda de pedidos");
            e.printStackTrace();
        } finally {
			if (session != null){
				session.close();
			}
		}
        return lista;
	}
	
	public List<Pedido> getAllPedidosByEstado(String estado){
		List<Pedido> lista = null;
		Session session = null;
		try{
            String queryStr = "SELECT * FROM pedido WHERE estado = '" + estado + "'  ORDER BY idPedido";
            session = sessionFactory.openSession();
            lista = (List<Pedido>) session.createSQLQuery(queryStr).addEntity(Pedido.class).list();
        }catch (Exception e){
            LogUtil.printLog(className, "Error realizando la busqueda de pedidos con estado: " + estado);
            e.printStackTrace();
        } finally {
			if (session != null){
				session.close();
			}
		}
        return lista;
	}
	
	public List<Pedido> getAllPedidosNotInEstado(String estado){
		List<Pedido> lista = null;
		Session session = null;
		try{
            String queryStr = "SELECT * FROM pedido WHERE estado != '" + estado + "'  ORDER BY idPedido";
            session = sessionFactory.openSession();
            lista = (List<Pedido>) session.createSQLQuery(queryStr).addEntity(Pedido.class).list();
        }catch (Exception e){
            LogUtil.printLog(className, "Error realizando la busqueda de pedidos con estado: " + estado);
            e.printStackTrace();
        } finally {
			if (session != null){
				session.close();
			}
		}
        return lista;
	}
	
	public List<Pedido> getAllPedidosHistorico(String descripcion, String fechaDesde, String fechaHasta){
		List<Pedido> lista = null;
		Session session = null;
		try{
            String queryStr = "SELECT * FROM pedido WHERE estado = 'Recibido' ";
            if (!StringUtil.isNullOrEmptyOrBlankString(descripcion)){
            	queryStr += "AND UPPER(descripcion) LIKE UPPER('%" + descripcion + "%') ";
            }
            if (!StringUtil.isNullOrEmptyOrBlankString(fechaDesde)){
            	queryStr += "AND fechaPedido >= STR_TO_DATE('" + fechaDesde + " 00:00:00','%d/%m/%Y %T') ";
            }
            if (!StringUtil.isNullOrEmptyOrBlankString(fechaHasta)){
            	queryStr += "AND fechaPedido <= STR_TO_DATE('" + fechaHasta + " 23:59:59','%d/%m/%Y %T') ";
            }
            queryStr += "ORDER BY idPedido";
            session = sessionFactory.openSession();
            lista = (List<Pedido>) session.createSQLQuery(queryStr).addEntity(Pedido.class).list();
        }catch (Exception e){
            LogUtil.printLog(className, "Error realizando la busqueda de pedidos de historico");
            e.printStackTrace();
        } finally {
			if (session != null){
				session.close();
			}
		}
        return lista;
	}
}