package es.uv.saic.domain;



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

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import es.uv.saic.dto.TascaAsignadaDTO;


@Repository
public interface UsuariRepository extends JpaRepository<Usuari, String> {
	
	@Query("SELECT i FROM Usuari i WHERE i.usuari = ?1")
	Usuari findByUsername(String usuari);
	
	@Query(value=("(SELECT ur.tlugar AS tLugar, ur.lugar AS lugar, id_proces AS idProces , id_instancia AS instancia, id_tascai AS instanciaTasca, id_tascap AS tascaP, ur.id_rol AS rol \n"+ 
			"FROM usuaris_rols ur \n"+
			"INNER JOIN tasquesi ti ON ur.tlugar=ti.tlugar AND ur.lugar=ti.lugar \n"+
			"WHERE ur.tlugar=ti.tlugar AND ur.id_rol=ti.id_rol AND vigent \n"+ 
			"AND estat='A' AND usuari=?1) \n"+
			"UNION \n"+
			"(SELECT ur.tlugar AS tLugar, ur.lugar AS lugar, id_proces AS idProces , id_instancia AS instancia, id_tascai AS instanciaTasca, id_tascap AS tascaP, ur.id_rol AS rol \n"+
			"FROM usuaris_rols ur, organs o, tasquesi ti \n"+
			"WHERE ti.tlugar='T' AND ti.tlugar=o.tlugar AND ti.lugar=o.lugar AND o.tlugar2=ur.tlugar AND o.lugar2=ur.lugar \n"+
			"AND ur.id_rol=ti.id_rol \n"+
			"AND vigent \n"+
			"AND estat='A' AND usuari=?1)"), nativeQuery=true)
	List<TascaAsignadaDTO> findActiveInstanciaTasques(String usuari);
	
	@Query(value=("SELECT DISTINCT(ins.id_instancia) FROM instancies ins, usuaris_rols usr, tasques tas, tasquesi tasi WHERE ins.estat = 'A' " + 
			"AND ((ins.tlugar = usr.tlugar AND ins.lugar = usr.lugar) OR (ins.centre = usr.lugar AND usr.tlugar = 'C')) " +
			"AND tasi.id_instancia = ins.id_instancia " + 
			"AND usr.vigent AND usr.usuari = ?1 AND tasi.id_tasca = tas.id_tasca AND tasi.estat = 'A' " + 
			"AND tas.id_proces = ins.id_proces AND tas.id_rol = usr.id_rol ORDER BY ins.id_instancia ASC"), nativeQuery=true)
	List<BigInteger> findActiveInstancies(String usuari);
	
	@Query(value=("SELECT DISTINCT(ins.id_instancia) FROM instancies ins, usuaris_rols usr, tasques tas, tasquesi tasi WHERE ins.estat = 'A'\n" + 
			"AND usr.usuari = ?1 AND tasi.id_tasca = tas.id_tasca AND tasi.estat = 'A' AND tasi.id_instancia = ins.id_instancia\n" + 
			"AND tas.id_proces = ins.id_proces AND tas.id_rol = usr.id_rol AND usr.vigent ORDER BY ins.id_instancia ASC"), nativeQuery=true)
	List<BigInteger> findActiveInstanciesGranted(String usuari);
	
	@Query(value=("SELECT id_instancia FROM instancies WHERE lugar = ?1 AND tlugar = ?2"), nativeQuery=true)
	List<BigInteger> findSupervisableProcessos(Integer lugar, String tlugar);
	
	@Query(value=("SELECT id_instancia FROM instancies WHERE centre = ?1"), nativeQuery=true)
	List<BigInteger> findSupervisableProcessosResp(Integer centre);
	
	@Query(value=("SELECT id_instancia FROM instancies WHERE id_proces IN(SELECT id_proces FROM processos WHERE nom_proces IN(?1))"), nativeQuery=true)
	List<BigInteger> findSupervisableProcessosSupervisor(List<String> procs);
	
	@Query(value=("SELECT DISTINCT(centre) FROM (SELECT o.lugar AS centre FROM usuaris_rols u " + 
			 "LEFT JOIN organs o ON u.tlugar = o.tlugar AND u.lugar = o.lugar " + 
			 "WHERE o.tlugar = 'C' AND u.usuari = ?1 AND u.vigent " + 
			 "UNION " + 
			 "SELECT lugar2 AS centre FROM usuaris_rols u " + 
			 "LEFT JOIN organs o ON u.tlugar = o.tlugar AND u.lugar = o.lugar " + 
			 "WHERE o.tlugar = 'T' AND u.usuari = ?1 AND u.vigent) a"), nativeQuery=true)
	List<Integer> findSupervisableCentres(String usuari);
	
	@Query(value=("SELECT DISTINCT ins.centre FROM instancies ins "
			+ "LEFT JOIN processos pr ON pr.id_proces = ins.id_proces "
			+ "WHERE pr.nom_proces IN(?1)"), nativeQuery=true)
	List<Integer> findSupervisableCentresSupervisor(List<String> procs);
	
	@Query(value="SELECT us.* FROM usuaris us, usuaris_rols usr, tasques tas, tasquesi tasi, instancies ins "
			+ "WHERE us.usuari = usr.usuari AND tasi.id_tasca = tas.id_tasca AND tasi.estat = 'A' "
			+ "AND ins.lugar = usr.lugar AND ins.tlugar = usr.tlugar AND ins.id_instancia = tasi.id_instancia AND ins.id_instancia = ?1 "
			+ "AND usr.vigent AND tas.id_rol = usr.id_rol "
			+ "UNION "
			+ "SELECT us.* FROM usuaris us, usuaris_rols usr, tasques tas, tasquesi tasi, instancies ins "
			+ "WHERE us.usuari = usr.usuari AND tasi.id_tasca = tas.id_tasca AND tasi.estat = 'A' "
			+ "AND ins.centre = usr.lugar AND ins.id_instancia = tasi.id_instancia AND ins.id_instancia = ?1 "
			+ "AND usr.vigent AND tas.id_rol = usr.id_rol "
			+ "UNION "
			+ "SELECT us.* FROM usuaris us, usuaris_rols usr, tasques tas, tasquesi tasi, instancies ins "
			+ "WHERE us.usuari = usr.usuari AND tasi.id_tasca = tas.id_tasca AND tasi.estat = 'A' "
			+ "AND usr.lugar = 0 AND usr.tlugar = 'U' AND ins.id_instancia = tasi.id_instancia AND ins.id_instancia = ?1 "
			+ "AND usr.vigent AND tas.id_rol = usr.id_rol ", nativeQuery=true)
	public List<Usuari> getInstanceAsignedUsers(BigInteger idInstancia);
	
	@Query(value=("SELECT * FROM usuaris WHERE usuari IN(SELECT DISTINCT usuari FROM usuaris_rols WHERE id_rol = ?1 "
			+ "AND (lugar IN(?2) OR lugar IN (SELECT lugar FROM organs WHERE tlugar = 'T' AND lugar2 IN(?2))) AND vigent)"), nativeQuery=true)
	List<Usuari> findByRolCentre(Integer idRol, List<Integer> centres);

}
