package es.uv.saic.web;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Optional;

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 com.fasterxml.jackson.databind.ObjectMapper;

import es.uv.saic.domain.SupervisionSearchParams;
import es.uv.saic.domain.Usuari;
import es.uv.saic.feign.SupervisionClient;
import jakarta.servlet.http.HttpSession;

// Render the supervision page and handle supervision searches
@Controller
public class SupervisionController {

	@Autowired
	private SupervisionClient sc;

	/*
	 * Renders the supervision page
	 * 
	 * @param model The model to pass data to the view
	 * @param auth The authentication object
	 * @param session The HTTP session
	 * @return The name of the view to render
	 */
	@GetMapping("/supervision")
	public String supervisionForm(Model model, Authentication auth, HttpSession session) {

		Object obj = session.getAttribute("searchParams");

		SupervisionSearchParams params = null;

		if (obj instanceof LinkedHashMap) {
			ObjectMapper mapper = new ObjectMapper();
			params = mapper.convertValue(obj, SupervisionSearchParams.class);
		} else if (obj instanceof SupervisionSearchParams) {
			params = (SupervisionSearchParams) obj;
		}

		HashMap<String, Object> response =
			sc.supervisionForm(((Usuari) auth.getPrincipal()).getUsuari(), Optional.ofNullable(params));

		if (response == null) {
			return "401";
		}

		model.addAllAttributes(response);
		if (response.get("removeAttribute") != null)
			session.removeAttribute(response.get("removeAttribute").toString());

		return "supervision";
	}

	
	/*
	 * Handles the supervision search form submission
	 * 
	 * @param model The model to pass data to the view
	 * @param auth The authentication object
	 * @param centres The selected centers
	 * @param cursos The selected years
	 * @param titulacions The selected titulacions
	 * @param procediments The selected procedures
	 * @param evidencies The selected evidences
	 * @param searchType The type of search (by procedures or evidences)
	 * @param session The HTTP session
	 * @return The name of the view to render
	 */
	@PostMapping("/supervision/search")
	public String supervisionSearch(Model model, Authentication auth, 
			@RequestParam(name="centers[]", required=false) List<Integer> centres,
			@RequestParam("years[]") List<Integer> cursos,
			@RequestParam("titulations[]") List<Integer> titulacions,
			@RequestParam(name="procedures[]", required=false) List<String> procediments,
			@RequestParam(name="evidences[]", required=false) List<String> evidencies,
			@RequestParam(name="searchType", required=false) String searchType,
			HttpSession session) {

		HashMap<String, Object> response =
			sc.supervisionSearch(centres, cursos, titulacions, procediments, evidencies, searchType, searchType);

		if (response == null) {
        	return "401";
		}

		model.addAllAttributes(response);
		session.setAttribute("searchParams", response.get("searchParams"));

		return "supervisionProcedures";
	}
	
	/*
	 * Restores the previous search results from the session
	 * 
	 * @param model The model to pass data to the view
	 * @param auth The authentication object
	 * @param session The HTTP session
	 * @return The name of the view to render
	 */
	@GetMapping("/supervision/search")
	public String restoreSearch(Model model, Authentication auth, HttpSession session) {
		Object obj = session.getAttribute("searchParams");

		SupervisionSearchParams params = null;

		if (obj instanceof LinkedHashMap) {
			ObjectMapper mapper = new ObjectMapper();
			params = mapper.convertValue(obj, SupervisionSearchParams.class);
		} else if (obj instanceof SupervisionSearchParams) {
			params = (SupervisionSearchParams) obj;
		}
		HashMap<String, Object> response =
			sc.restoreSearch(((Usuari) auth.getPrincipal()).getUsuari(), params);

        if (response == null) {
        	return "401";
		}

		model.addAllAttributes(response);

		return "supervisionProcedures";
	}
}