package es.uv.saic.service;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import es.uv.saic.domain.Instancia;
import es.uv.saic.domain.InstanciaRepository;
import es.uv.saic.domain.InstanciaTasca;
import es.uv.saic.dto.InstanciaGanttDTO;


@Service
public class InstanciaService {

	@Autowired
	private InstanciaRepository instanciaRepository;
	
	@Autowired
	@Lazy
	private InstanciaTascaService instanciaTascaService;
	
	@SuppressWarnings("rawtypes")
	public Instancia findByID(BigInteger p_id) {
		Optional opt = this.instanciaRepository.findById(p_id);
		if(opt.isEmpty()) {
			return null;
		}
		else {
			return (Instancia) opt.get();
		}
	}
	
	public InstanciaTasca getReportFromInstancia(BigInteger idInstancia) {
		return this.getReportFromInstancia(idInstancia);
	}
	
	public List<BigInteger> filterSupervisables(List<Integer> centres, List<Integer> titulacions, List<Integer> cursos, List<String> procediments) {
		return this.instanciaRepository.filterSupervisables(centres, titulacions, cursos, procediments);
	}
	
	public BigInteger filterSupervisable(Integer centre, Integer titulacio, Integer curs, String procediment) {
		return this.instanciaRepository.filterSupervisable(centre, titulacio, curs, procediment);
	}
	
	public List<BigInteger> filterSupervisablesByEvidencies(List<Integer> centres, List<Integer> titulacions, List<Integer> cursos, List<String> evidencies){
		return this.instanciaRepository.filterSupervisablesByEvidencies(centres, titulacions, cursos, evidencies);
	}
	
	public void save(Instancia i) {
		this.instanciaRepository.save(i);
		this.instanciaRepository.flush();
	}
	
	public List<Instancia> findAll(){
		return this.instanciaRepository.findAll();
	}
	
	public List<BigInteger> findAllIds(){
		return this.instanciaRepository.findAllIds();
	}
	
	public List<Instancia> findByOrganCursNom(String tlugar, Integer lugar, Integer centre, Integer titulacio, Integer curs, List<String> nom){
		return this.instanciaRepository.findByOrganCursNom(tlugar, lugar, centre, titulacio, curs, nom);
	}

	public List<Instancia> findByCentreCursNom(Integer lugar2, Integer curs, List<String> nom){
		return this.instanciaRepository.findByCentreCursNom(lugar2, curs, nom);
	}

	public List<Instancia> findByIdProces(Integer idProces){
		return this.instanciaRepository.findByIdProces(idProces);
	}
	
	public List<InstanciaGanttDTO> findByOrganBetweenCurs(String tlugar, Integer lugar, Integer centre, List<Integer> titulacio, Integer cursIni, Integer cursFi){
		return this.instanciaRepository.findByOrganBetweenCurs(tlugar, lugar, centre, titulacio, cursIni, cursFi);
	}
	
	public boolean exists(String proces, String tlugar, Integer lugar, Integer centre, Integer titulacio, Integer curs) {
		List<Instancia> ins = this.instanciaRepository.findOlders(proces, tlugar, lugar, centre, titulacio, curs);
		return ins.size() > 0;
	}
	
	public boolean exists(String proces, String tlugar, Integer lugar, Integer centre, Integer titulacio, Integer curs, Integer idtascap, String estat) {
		List<Instancia> ins = this.instanciaRepository.findOlders(proces, tlugar, lugar, centre, titulacio, curs, idtascap, estat);
		return ins.size() > 0;
	}
	
	public BigInteger instantiateT(Integer idProces, Integer titulacio) {
		try {
			BigInteger idInstancia = this.instanciaRepository.instantiateT(idProces, titulacio);
			this.instanciaRepository.activateInstantiatedTask(idInstancia);
			InstanciaTasca it = this.instanciaTascaService.findActiveByInstancia(idInstancia);
			if(it.getTasca().getRol().getNomRol().equals("sys")) {
				it = this.instanciaTascaService.system(it);
			}
			return idInstancia;
		}
		catch(Exception e){
			e.printStackTrace();
			return new BigInteger("0");
		}
	}
	
	public BigInteger instantiateC(Integer idProces, Integer centre, Integer titulacio) {
		try {
			BigInteger idInstancia = this.instanciaRepository.instantiateC(idProces, centre, titulacio);
			this.instanciaRepository.activateInstantiatedTask(idInstancia);
			InstanciaTasca it = this.instanciaTascaService.findActiveByInstancia(idInstancia);
			if(it.getTasca().getRol().getNomRol().equals("sys")) {
				it = this.instanciaTascaService.system(it);
			}
			return idInstancia;
		}
		catch(Exception e){
			e.printStackTrace();
			return new BigInteger("0");
		}
	}
	
	public BigInteger instantiateU(Integer idProces, Integer titulacio) {
		try {
			BigInteger idInstancia = this.instanciaRepository.instantiateU(idProces, titulacio);
			this.instanciaRepository.activateInstantiatedTask(idInstancia);
			InstanciaTasca it = this.instanciaTascaService.findActiveByInstancia(idInstancia);
			if(it.getTasca().getRol().getNomRol().equals("sys")) {
				it = this.instanciaTascaService.system(it);
			}
			return idInstancia;
		}
		catch(Exception e){
			e.printStackTrace();
			return new BigInteger("0");
		}
	}
	
	public void deleteInstance(Instancia instancia) {
		if(this.instanciaRepository.clearInstance(instancia.getIdInstancia()) > 0) {
			this.instanciaRepository.deleteInstance(instancia.getIdInstancia());
		}
	}
	
	public void clearInstance(Instancia instancia) {
		if(this.instanciaRepository.clearInstance(instancia.getIdInstancia()) > 0) {
			this.instanciaRepository.instantiateTasks(instancia.getIdInstancia(), instancia.getProces().getIdProces());
			this.instanciaRepository.activateInstantiatedTask(instancia.getIdInstancia());
		}
	}
	
}

