package es.uv.saic.web;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import jakarta.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import es.uv.saic.domain.Organ;
import es.uv.saic.domain.Rol;
import es.uv.saic.domain.Usuari;
import es.uv.saic.domain.UsuarisRol;
import es.uv.saic.service.OrganService;
import es.uv.saic.service.RolService;
import es.uv.saic.service.UsuariService;
import es.uv.saic.service.UsuarisRolService;

// Controller for the managers administration page 
@Controller
public class ManagersController {
	
	@Autowired
	private UsuarisRolService urs;
	@Autowired
	private OrganService ors;
	@Autowired
	private UsuariService us;
	@Autowired
	private RolService rs;
	
	/*
	 * Load the managers administration page data into the model
	 * - List of centres and titulacions the logged user can manage
	 * - List of all users
	 * - List of assignable roles
	 * - If there are search results in the session, load them too
	 * - If there is a roleExists attribute in the session, load it too
	 * - The view is managers.html
	 */
	@SuppressWarnings("unchecked")
	@GetMapping("/managers")
	public String managersForm(Model model, Authentication auth, HttpSession session) {
		
		List<Organ> sup_centres;
		List<Organ> sup_titulacions;
		if(urs.isGrantedUser((Usuari) auth.getPrincipal())){
			sup_centres = this.ors.getCentres();
			sup_titulacions = this.ors.getTitulacions();
		}
		else {
			sup_centres = this.ors.getUsuariCentres(((Usuari) auth.getPrincipal()).getUsuari());
			if(sup_centres != null) {
				if(sup_centres.size() > 0) {
					sup_titulacions = this.ors.getTitulacionsByCentres(sup_centres);
				}
				else {
					sup_titulacions = this.ors.getUsuariTitulacions(((Usuari) auth.getPrincipal()).getUsuari());
					for(Organ o : sup_titulacions) {
						sup_centres.add(o.getOrgan());
					}
				}
			}
			else {
				sup_titulacions = this.ors.getUsuariTitulacions(((Usuari) auth.getPrincipal()).getUsuari());
			}
		}
		model.addAttribute("sup_centres", sup_centres);
		model.addAttribute("sup_titulacions", sup_titulacions);
		
		List<Usuari> users = us.findAll();
		List<Rol> roles = rs.findAssignables();
		model.addAttribute("users", users);
		model.addAttribute("roles", roles);
		
	
		if(session.getAttribute("respTitulacions") != null && session.getAttribute("respCentres") != null ) {
			model.addAttribute("restoreCentres", ((List<Integer>)session.getAttribute("respCentres")).toString());
			model.addAttribute("restoreTitulacions", ((List<Integer>)session.getAttribute("respTitulacions")).toString());
			this.loadManagers(model, (List<Integer>)session.getAttribute("respCentres"), (List<Integer>)session.getAttribute("respTitulacions"));
			session.removeAttribute("respTitulacions");
			session.removeAttribute("respCentres");
		}
		
		if(session.getAttribute("roleExists") != null) {
			model.addAttribute("roleExists", true);
			session.removeAttribute("roleExists");
		}
		
		return "managers";
	}
	
	/*
	 * Process the search form submission and load the results into the model
	 * @Param centres List of centre ids to search managers in
	 * @Param titulacions List of titulacion ids to search managers in
	 * @Return The view component list_managers
	 */
	@PostMapping("/managers/search")
	public String managersSearch(Model model, Authentication auth, 
			@RequestParam("center") List<Integer> centres,
			@RequestParam(name="titulation[]", required=false) List<Integer> titulacions,
			HttpSession session) {

		if(titulacions == null) {
			titulacions = new ArrayList<Integer>();
		}
		this.loadManagers(model, centres, titulacions);
		
		session.setAttribute("respTitulacions", titulacions);
		session.setAttribute("respCentres", centres);
		
		return "components/list_managers";
	}
	
	/*
	 * Load the search results into the model
	 * @Param model The model to load the data into
	 * @Param centres List of centre ids to search managers in
	 * @Param titulacions List of titulacion ids to search managers in
	 */
	public void loadManagers(Model model, List<Integer> centres, List<Integer> titulacions) {
		List<UsuarisRol> resp_centre = urs.findManagerByCentres(centres);
		Collections.sort(resp_centre, new Comparator<UsuarisRol>() {  
		    @Override  
		    public int compare(UsuarisRol a, UsuarisRol b) {  
		          
		        int OrgnomComp = a.getOrgan().getNomVal().compareTo(b.getOrgan().getNomVal()); 
		        if (OrgnomComp != 0) {  
		            return OrgnomComp;  
		        }  
		        int rolComp = a.getRol().getNomRol().compareTo(b.getRol().getNomRol());
		        if (rolComp != 0) {  
		            return rolComp;  
		        }
		        return a.getUsuari().getNom().concat(a.getUsuari().getCognoms()).compareTo(
		        		b.getUsuari().getNom().concat(b.getUsuari().getCognoms()));  
		    }  
		});
		
		List<UsuarisRol> resp_titulacio = new ArrayList<UsuarisRol>();
		if(titulacions.size() > 0) {
			resp_titulacio = urs.findManagerByTitulacions(titulacions);
			Collections.sort(resp_titulacio, new Comparator<UsuarisRol>() {  
			    @Override  
			    public int compare(UsuarisRol a, UsuarisRol b) {  
			          
			        int OrgnomComp = a.getOrgan().getNomVal().compareTo(b.getOrgan().getNomVal()); 
			        if (OrgnomComp != 0) {  
			            return OrgnomComp;  
			        }  
			        int rolComp = a.getRol().getNomRol().compareTo(b.getRol().getNomRol());
			        if (rolComp != 0) {  
			            return rolComp;  
			        }
			        return a.getUsuari().getNom().concat(a.getUsuari().getCognoms()).compareTo(
			        		b.getUsuari().getNom().concat(b.getUsuari().getCognoms()));  
			    }  
			});
		}
				
		if(resp_centre == null) {
			model.addAttribute("results", false);
		}
		else{
			model.addAttribute("results", true);
			model.addAttribute("resp_centres", resp_centre);
			model.addAttribute("resp_titulacions", resp_titulacio);
		}
	}
	
}