package es.uv.saic.domain;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import es.uv.saic.dto.IndicadorDTO;
import es.uv.saic.dto.IndicadorEnquestaValorDTO;

@Repository
public interface IndicadorEnquestaRepository extends JpaRepository<IndicadorEnquesta, Long> {
	
	@Query("SELECT i FROM IndicadorEnquesta i")
	List<IndicadorEnquesta> findAll();
	
	@Query(value="SELECT DISTINCT(CONCAT(enquesta, '_', indicador)) FROM indicador_enquesta ORDER BY 1 ASC", nativeQuery=true)
	List<String> findTypes();
	
	@Query(value="SELECT * FROM indicador_enquesta WHERE enquesta = ?1 AND curs = ?2 AND ambit = ?3 AND estudi = ?4", nativeQuery=true)
	List<IndicadorEnquesta> findByEnquestaCursAmbitEstudi(String enquesta, Integer curs, String ambit, String estudi);
	
	@Query(value="SELECT * FROM indicador_enquesta WHERE enquesta = ?1 AND curs = ?2 AND ambit = ?3 AND estudi = ?4 "
			+ "AND centre = ?5 AND (titulacio = ?6 OR titulacio IN(SELECT lugar_eq FROM organs_equivalents WHERE tlugar = 'T' AND lugar = ?6))", nativeQuery=true)
	List<IndicadorEnquesta> findByEnquestaCursAmbitEstudiCentreTitulacio(String enquesta, Integer curs, String ambit, String estudi,
																		 Integer centre, Integer titulacio);
	
	@Query(value="SELECT * FROM indicador_enquesta WHERE enquesta = ?1 AND curs = ?2 AND ambit = ?3 AND estudi = ?4 AND centre = ?5", nativeQuery=true)
	List<IndicadorEnquesta> findByEnquestaCursAmbitEstudiCentre(String enquesta, Integer curs, String ambit, String estudi,
																		 Integer centre);
	
	@Query(value="SELECT LOWER(ei.enquesta) AS enquesta, LOWER(ei.indicador) AS indicador, ei.valor, LOWER(ei.ambit) AS ambit, ei.tipus, ei.cursd "
			+ "FROM indicador_enquesta ei "
			+ "JOIN evidencia_indicador_enquesta eie ON LOWER(ei.enquesta) = LOWER(eie.enquesta) AND LOWER(ei.indicador) = LOWER(eie.indicador) "
			+ "WHERE eie.evidencia = ?1 AND eie.proces = ?2 AND ei.curs = ?5 AND ei.ambit = 'T' "
			+ "AND ei.centre = ?4 AND (ei.titulacio = ?3 OR ei.titulacio IN(SELECT lugar_eq FROM organs_equivalents WHERE tlugar_eq = 'T' AND tlugar = 'T' AND lugar = ?3)) "
			+ "UNION "
			+ "SELECT LOWER(ei.enquesta) AS enquesta, LOWER(ei.indicador) AS indicador, ei.valor, LOWER(ei.ambit) AS ambit, ei.tipus, ei.cursd  "
			+ "FROM indicador_enquesta ei "
			+ "JOIN evidencia_indicador_enquesta eie ON LOWER(ei.enquesta) = LOWER(eie.enquesta) AND LOWER(ei.indicador) = LOWER(eie.indicador) "
			+ "WHERE eie.evidencia = ?1 AND eie.proces = ?2 AND ei.curs = ?5 AND ei.ambit = 'C' "
			+ "AND ei.centre = ?4 "
			+ "UNION "
			+ "SELECT LOWER(ei.enquesta) AS enquesta, LOWER(ei.indicador) AS indicador, ei.valor, LOWER(ei.ambit) AS ambit, ei.tipus, ei.cursd  "
			+ "FROM indicador_enquesta ei "
			+ "JOIN evidencia_indicador_enquesta eie ON LOWER(ei.enquesta) = LOWER(eie.enquesta) AND LOWER(ei.indicador) = LOWER(eie.indicador) "
			+ "WHERE eie.evidencia = ?1 AND eie.proces = ?2 AND ei.curs = ?5 AND ei.ambit = 'U'", nativeQuery=true)
	List<IndicadorEnquestaValorDTO> getAssociatedInds(String evidencia, String proces, Integer titulacio, Integer centre, Integer curs);
	
	@Query(value="SELECT LOWER(ei.enquesta) AS enquesta, LOWER(ei.indicador) AS indicador, ei.valor, LOWER(ei.ambit) AS ambit, ei.tipus, ei.cursd, ei.titulacio "
			+ "FROM indicador_enquesta ei "
			+ "WHERE ei.curs = ?3 AND ei.ambit = 'T' AND ei.centre = ?2 "
			+ "AND (ei.titulacio = ?1 OR ei.titulacio IN(SELECT lugar_eq FROM organs_equivalents WHERE tlugar_eq = 'T' AND tlugar = 'T' AND lugar = ?1)) "
			+ "UNION "
			+ "SELECT LOWER(ei.enquesta) AS enquesta, LOWER(ei.indicador) AS indicador, ei.valor, LOWER(ei.ambit) AS ambit, ei.tipus, ei.cursd, 0 AS titulacio  "
			+ "FROM indicador_enquesta ei "
			+ "WHERE ei.curs = ?3 AND ei.ambit = 'C' AND ei.centre = ?2 "
			+ "UNION "
			+ "SELECT LOWER(ei.enquesta) AS enquesta, LOWER(ei.indicador) AS indicador, ei.valor, LOWER(ei.ambit) AS ambit, ei.tipus, ei.cursd, 0 AS titulacio  "
			+ "FROM indicador_enquesta ei "
			+ "WHERE ei.curs = ?3 AND ei.ambit = 'U' "
			+ "ORDER BY 7 DESC ", nativeQuery=true)
	List<IndicadorEnquestaValorDTO> getAllInds(Integer titulacio, Integer centre, Integer curs);
	
	@Query(value="SELECT LOWER(ei.enquesta) AS enquesta, LOWER(ei.indicador) AS indicador, ei.valor, ei.num, LOWER(ei.ambit) AS ambit, ei.tipus, ei.cursd, ei.titulacio "
			+ "FROM indicador_enquesta ei "
			+ "WHERE ei.curs = ?3 AND upper(ei.ambit) = 'T' AND ei.centre = ?2 "
			+ "AND (ei.titulacio = ?1 OR ei.titulacio IN(SELECT lugar_eq FROM organs_equivalents WHERE tlugar_eq = 'T' AND tlugar = 'T' AND lugar = ?1)) "
			+ "UNION "
			+ "SELECT LOWER(ei.enquesta) AS enquesta, LOWER(ei.indicador) AS indicador, ei.valor, ei.num, LOWER(ei.ambit) AS ambit, ei.tipus, ei.cursd, 0 AS titulacio  "
			+ "FROM indicador_enquesta ei "
			+ "WHERE ei.curs = ?3 AND upper(ei.ambit) = 'C' AND ei.centre = ?2 AND upper(ei.estudi) IN(?4, 'U') "
			+ "UNION "
			+ "SELECT LOWER(ei.enquesta) AS enquesta, LOWER(ei.indicador) AS indicador, ei.valor, ei.num, LOWER(ei.ambit) AS ambit, ei.tipus, ei.cursd, 0 AS titulacio  "
			+ "FROM indicador_enquesta ei "
			+ "WHERE ei.curs = ?3 AND upper(ei.ambit) = 'U' AND upper(ei.estudi) IN(?4, 'U') "
			+ "ORDER BY 7 DESC ", nativeQuery=true)
	List<IndicadorEnquestaValorDTO> getAllIndValsByEstudi(Integer titulacio, Integer centre, Integer curs, String estudi);
	
	@Query(value="SELECT ei.* "
			+ "FROM indicador_enquesta ei "
			+ "WHERE ei.curs = ?3 AND upper(ei.ambit) = 'T' AND ei.centre = ?2 "
			+ "AND (ei.titulacio = ?1 OR ei.titulacio IN(SELECT lugar_eq FROM organs_equivalents WHERE tlugar_eq = 'T' AND tlugar = 'T' AND lugar = ?1)) "
			+ "UNION "
			+ "SELECT ei.*  "
			+ "FROM indicador_enquesta ei "
			+ "WHERE ei.curs = ?3 AND upper(ei.ambit) = 'C' AND ei.centre = ?2 AND upper(ei.estudi) IN(?4, 'U') "
			+ "UNION "
			+ "SELECT ei.*  "
			+ "FROM indicador_enquesta ei "
			+ "WHERE ei.curs = ?3 AND upper(ei.ambit) = 'U' AND upper(ei.estudi) IN(?4, 'U') "
			+ "ORDER BY 7 DESC ", nativeQuery=true)
	List<IndicadorEnquesta> getAllIndsByEstudi(Integer titulacio, Integer centre, Integer curs, String estudi);
		
	@Query(value="SELECT DISTINCT gr.dimensio, gr.estudi, ie.ambit, gr.ordre, ie.indicador, curs, valor FROM indicador_enquesta ie "
			+ "		INNER JOIN grafiques gr ON ie.indicador = gr.indicador AND ie.enquesta = gr.enquesta AND LOWER(ie.estudi) = LOWER(gr.estudi) "
			+ "		WHERE UPPER(ie.ambit) = 'T' AND LOWER(ie.estudi) = LOWER(?3) AND titulacio IN (?1) AND centre = ?2 AND curs > ?4 AND tipus = 'avg' "
			+ "UNION "
			+ "SELECT DISTINCT gr.dimensio, gr.estudi, ie.ambit, gr.ordre, ie.indicador, curs, valor FROM indicador_enquesta ie "
			+ "		INNER JOIN grafiques gr ON ie.indicador = gr.indicador AND ie.enquesta = gr.enquesta AND (LOWER(ie.estudi) = LOWER(gr.estudi) OR LOWER(ie.estudi) = 'u') "
			+ "		WHERE UPPER(ie.ambit) = 'C' AND (LOWER(ie.estudi) = LOWER(?3) OR LOWER(ie.estudi) = 'u') AND centre = ?2 AND curs > ?4 AND tipus = 'avg' "
			+ "UNION "
			+ "SELECT DISTINCT gr.dimensio, gr.estudi, ie.ambit, gr.ordre, ie.indicador, curs, valor FROM indicador_enquesta ie "
			+ "		INNER JOIN grafiques gr ON ie.indicador = gr.indicador AND ie.enquesta = gr.enquesta AND (LOWER(ie.estudi) = LOWER(gr.estudi) OR LOWER(ie.estudi) = 'u') "
			+ "		WHERE UPPER(ie.ambit) = 'U' AND (LOWER(ie.estudi) = LOWER(?3) OR LOWER(ie.estudi) = 'u') AND curs > ?4 AND tipus = 'avg' "
			+ "ORDER BY 1, 2, 3, 4, 5, 6 ", nativeQuery=true)
	List<IndicadorDTO> getGraphData(List<Integer> titulacions, Integer centre, String estudi, Integer cursMax);
	
	@Query(value="SELECT DISTINCT gr.dimensio, gr.estudi, ie.ambit, gr.ordre, ie.indicador, curs, valor FROM indicador_enquesta ie "
			+ "		INNER JOIN grafiques gr ON ie.indicador = gr.indicador AND ie.enquesta = gr.enquesta AND (LOWER(ie.estudi) = LOWER(gr.estudi) OR LOWER(ie.estudi) = 'u') "
			+ "		WHERE UPPER(ie.ambit) = 'C' AND (LOWER(ie.estudi) = LOWER(?2) OR LOWER(ie.estudi) = 'u') AND centre = ?1 AND curs > ?3 AND tipus = 'avg' "
			+ "UNION "
			+ "SELECT DISTINCT gr.dimensio, gr.estudi, ie.ambit, gr.ordre, ie.indicador, curs, valor FROM indicador_enquesta ie "
			+ "		INNER JOIN grafiques gr ON ie.indicador = gr.indicador AND ie.enquesta = gr.enquesta AND (LOWER(ie.estudi) = LOWER(gr.estudi) OR LOWER(ie.estudi) = 'u') "
			+ "		WHERE UPPER(ie.ambit) = 'U' AND (LOWER(ie.estudi) = LOWER(?2) OR LOWER(ie.estudi) = 'u') AND curs > ?3 AND tipus = 'avg' "
			+ "ORDER BY 1, 2, 3, 4, 5, 6 ", nativeQuery=true)
	List<IndicadorDTO> getGraphData(Integer centre, String estudi, Integer cursMax);
	
	@Transactional
	@Modifying(clearAutomatically=true, flushAutomatically=true)
	@Query(value="DELETE FROM indicador_enquesta WHERE centre IN(111, 121, 641, 642) AND ambit = 'C';", nativeQuery=true)
	int deleteCentroNoAdscrito();
	
	@Transactional
	@Modifying(clearAutomatically=true, flushAutomatically=true)
	@Query(value="DELETE FROM indicador_enquesta WHERE enquesta = ?1", nativeQuery=true)
	int deleteByEnquesta(String enquesta);
	
	@Transactional
	@Modifying(clearAutomatically=true, flushAutomatically=true)
	@Query(value="DELETE FROM indicador_enquesta WHERE enquesta = ?1 AND curs = ?2", nativeQuery=true)
	int deleteByEnquestaCurs(String enquesta, Integer curs);
	
	@Transactional
	@Modifying(clearAutomatically=true, flushAutomatically=true)
	@Query(value="DELETE FROM indicador_enquesta WHERE enquesta = ?1 AND curs = ?2 AND ambit IN('C', 'U'); "
			+ "INSERT INTO indicador_enquesta (curs, enquesta, indicador, num, titulacio, valor, centre, ambit, tipus, estudi, cursd) "
			+ "(SELECT ?2 AS curs, enquesta, indicador, num, titulacio, valor, centre, ambit, tipus, estudi, cursd "
			+ "FROM indicador_enquesta WHERE enquesta = ?1 AND curs = ?2-1 AND ambit IN('C', 'U')); "
			+ "INSERT INTO indicador_enquesta (curs, enquesta, indicador, num, titulacio, valor, centre, ambit, tipus, estudi, cursd) "
			+ "(SELECT ?2 AS curs, enquesta, indicador, num, titulacio, valor, centre, ambit, tipus, estudi, cursd "
			+ "FROM indicador_enquesta WHERE enquesta = ?1 AND curs = ?2-1 AND ambit IN('T') "
			+ "AND titulacio NOT IN(SELECT DISTINCT(titulacio) FROM indicador_enquesta WHERE enquesta = ?1 AND curs = ?2 AND ambit IN('T')));", nativeQuery=true)
	int fixBiennials(String enquesta, Integer curs);
	
	@Transactional
	@Modifying(clearAutomatically=true, flushAutomatically=true)
	@Query(value="INSERT INTO indicador_enquesta (curs, enquesta, indicador, titulacio, centre, ambit, tipus, estudi, cursd, valor, centre_origen, titulacio_origen, curs_enquesta, nenq, ruct, data) "
			+ "SELECT curs, enquesta, indicador, titulacio, centre, ambit, tipus, estudi, cursd, valor, centre_origen, titulacio_origen, curs_enquesta, nenq, ruct, data "
			+ "FROM indicador_enquesta_tmp "
			+ "WHERE enquesta = ?1", nativeQuery=true)
	int consolidateByEnquesta(String enquesta);
	
}

