package dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.util.MultiValueMap;

import bean.AppVariables;
import common.dao.GenericDAO;
import common.dao.IDAO;
import sicura.entities.FunzioniOrdinanti;

@Repository
public class FunzioniOrdinantiDAO extends SicuraDAO<FunzioniOrdinanti, Integer> implements IDAO<FunzioniOrdinanti, Integer>{

	public List<FunzioniOrdinanti> list(Integer startFrom, Integer size, String filter, String orderField) {
		boolean tx = startTransaction();
		try {
			String sql = generateSql(filter, false);
			
			SQLQuery q = currentSession().createSQLQuery(sql);
			
			if (filter!=null && !"".equals(filter))
				q.setParameter("filter", "%" + filter +"%");
			
			q.addEntity(FunzioniOrdinanti.class);
			
			List<FunzioniOrdinanti> res = null;
			
			try {
				res = q.list();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
			
			return res;
		} finally {
			if (tx)
				tx = commit();
		}
	}
	
	public Integer count(String filter) {
		boolean tx = startTransaction();
		
		try {
			String sql = generateSql(filter, true);
			
			SQLQuery q = currentSession().createSQLQuery(sql);
			
			if (filter!=null && !"".equals(filter))
				q.setParameter("filter", "%" + filter +"%");
			
			Integer res = (Integer) q.uniqueResult();
			
			return res;
		} finally {
			if (tx)
				tx = commit();
		}
	}

	private String generateSql(String filter, boolean doCount) {
		String sql = "select " 
				+ (doCount? "count(*)": "*") + 
				" from FunzioniOrdinanti ";
		
		if (filter!=null && !"".equals(filter))
			sql += " where FunzioneOrdinante like :filter or Descrizione like :filter";
		
		if (!doCount)
			sql += " order by id asc";
		return sql;
	}
	
	public List<FunzioniOrdinanti> listForUser(String userId, String guid) {
		boolean tx = startTransaction();
		try {
			//String sql = "exec spSecurityUtenteFunzioni (:userId, :guid)";
			
			String sql = "select distinct F.* from FunzioniOrdinanti F join UtentiFunzioni UF on UF.UserId='" + userId + "'";
			
			SQLQuery q = currentSession().createSQLQuery(sql);
			
			
			q
				.addEntity(FunzioniOrdinanti.class)
			//	.setParameter("userId", userId)
			//	.setParameter("guid", guid)
			;
			
			List<FunzioniOrdinanti> res;
			try {
				 res = q.list();
			} catch (Exception ex) {
				res = new ArrayList<FunzioniOrdinanti> ();
			}
			return res;
		} finally {
			if (tx)
				tx = commit();
		}
	}

	public Integer delete(Integer id, AppVariables appVariables) {
		
		boolean tx = startTransaction();
		try {
			
			/*
				CREATE PROC [dbo].[spUCBase_FunzioniOrdinanti_delete]
					@SecurityUserId VARCHAR(15),
					@SecurityGuid UNIQUEIDENTIFIER,
				
					@ID int
			 */
			Integer res = null;
			Connection connection = getConnection();
			CallableStatement proc;
			try {
				proc = connection.prepareCall("{? = call spUCBase_FunzioniOrdinanti_delete (?,?,?)}");
					
				proc.registerOutParameter(1, Types.VARCHAR);
				proc.setString(2, appVariables.getUserId());
				proc.setString(3, appVariables.getGuid());
				proc.setObject(4, id);
				
				proc.execute();
				proc.getMoreResults();
					
				res = proc.getInt(1);
					
			} catch (SQLException e) {
				e.printStackTrace();
				return null;
			}
			
			return res;
			
			
		} finally {
			if (tx)
				tx = commit();
		}
	}

	public String save(FunzioniOrdinanti funzione, AppVariables appVariables) {
		boolean tx = startTransaction();
		try {
			
			
			Connection connection = getConnection();
	
			/*
			  CREATE PROC [dbo].[spUCBase_FunzioniOrdinanti_update]
				@SecurityUserId VARCHAR(15),
				@SecurityGuid UNIQUEIDENTIFIER,
			
				@ID int,
				@FunzioneOrdinante varchar(10),
				@Descrizione varchar(50),
				@AbilitaCausali bit,
				@GestioneDatiContabili bit,
				@ApprovazioneAutomatica bit,
				@AbilitaGiroconti bit,
				@AbilitaCircuitoCassa bit,
				@AbilitaCircuitoPoste bit
			 */
			CallableStatement proc;
			try {

				if (funzione.getId()!=null && funzione.getId()!=0) {
					Integer checkResult = checkRecord(appVariables.getUserId(), appVariables.getGuid(), "FunzioniOrdinanti", funzione.getId(), funzione.getLastSaved(), "ID");

					if (checkResult==K_RECORD_MODIFICATO) 
						return "Record modificato da un altro utente";
					if (checkResult == K_RECORD_ELIMINATO) {
						return "Record eliminato da un altro utente";
					}
				}
			
				proc = connection.prepareCall("{? = call spUCBase_FunzioniOrdinanti_update (?,?,?,?,?,?,?,?,?,?,?)}");
					
				proc.registerOutParameter(1, Types.VARCHAR);
				proc.setString(2, appVariables.getUserId());
				proc.setString(3, appVariables.getGuid());
				proc.setObject(4, funzione.getId());
				proc.setString(5, funzione.getFunzioneOrdinante());
				proc.setString(6, funzione.getDescrizione());
				proc.setBoolean(7, funzione.isAbilitaCausali());
				proc.setBoolean(8, funzione.isGestioneDatiContabili());
				proc.setBoolean(9, funzione.isApprovazioneAutomatica());
				proc.setBoolean(10, funzione.isAbilitaGiroconti());
				proc.setBoolean(11, funzione.isAbilitaCircuitoCassa());
				proc.setBoolean(12, funzione.isAbilitaCircuitoPoste());
				
				proc.execute();
				proc.getMoreResults();
					
				proc.getInt(1);
					
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return e.getMessage();
			}
			return null;
		} finally {
			if (tx)
				tx = commit();
		}		
	}	
}
