package es.uv.saic.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import jakarta.servlet.http.HttpServletResponse;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
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.PathVariable;

import es.uv.saic.domain.Instancia;
import es.uv.saic.domain.InstanciaTasca;
import es.uv.saic.domain.Proces;
import es.uv.saic.domain.Usuari;
import es.uv.saic.service.ProcesService;

@Controller
public class ExportController {
	
	@Autowired
	private ProcesService ps;
	
	/*
	 * Export data for a given process and task as CSV
	 * @param model
	 * @param auth Authentication
	 * @param response HttpServletResponse
	 * @param id_p Process ID
	 * @param id_t Task ID
	 */
	@GetMapping("/export/{id_p}/{id_t}")  
	public void exportData(Model model, Authentication auth, HttpServletResponse response, 
			@PathVariable Integer id_p, @PathVariable Integer id_t) throws IOException {
		if(!((Usuari)auth.getPrincipal()).isAdmin() & !((Usuari)auth.getPrincipal()).isDataTest()) {
			return;
		}
		
		response.setContentType("text/csv");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=data_export.csv");
		
		PrintWriter pw = response.getWriter();
		Proces p = this.ps.findByID(id_p);
		List<Instancia> ins = p.getInstancies();
		List<String[]> lines = new ArrayList<>();
		if(p.getNomProces().equals("SAEM")) {
			String[] header = {"centre", "titulacio", "codi", "nom", "obs", "per"};
			lines.add(header);
		}
		else {
			String[] header = {"centre", "titulacio", "cod_assignatura_1er", "nom_assignatura_1er", "obs_assignatura_1er", "cod_assignatura_3er", "nom_assignatura_3er", "obs_assignatura_3er"};
			lines.add(header);
		}
				
		for(Instancia i : ins) {
			InstanciaTasca it = i.getInstanciaTasca().stream()
												     .filter(c -> id_t.equals(c.getTasca().getIdTascap()))
												     .findAny()
												     .orElse(null);
			if(it == null) {
				continue;
			}
			if(it.getEstat() == null){
				continue;
			}
			if(!it.getEstat().equals("E")){
				continue;
			}
			
			Document doc = Jsoup.parseBodyFragment(it.getText());
			
			Elements elements = doc.select("p.western.mceEditable");
			int j = 2;
			int size = lines.get(0).length;
	        String[] line = new String[size];
        	line[0] = i.getCentre().toString();
			line[1] = i.getTitulacio().toString();
			for(Element e : elements) {
				line[j] = e.text();
				j++;
			}
			
			lines.add(line);    
			
		}
		
		lines.stream()
	         .map(this::convertToCSV)
	         .forEach(pw::println);
		pw.close();
		pw.flush();
	}

//	@GetMapping("/export/{id_p}/{id_t}")  
//	public void exportData(Model model, Authentication auth, HttpServletResponse response, 
//			@PathVariable Integer id_p, @PathVariable Integer id_t) throws IOException {
//		if(!((Usuari)auth.getPrincipal()).isAdmin() & !((Usuari)auth.getPrincipal()).isDataTest()) {
//			return;
//		}
//		
//		response.setContentType("text/csv");
//        response.setCharacterEncoding("UTF-8");
//        response.setHeader("Content-Disposition", "attachment; filename=data_export.csv");
//		
//		PrintWriter pw = response.getWriter();
//		Proces p = this.ps.findByID(id_p);
//		List<Instancia> ins = p.getInstancies();
//		List<String[]> lines = new ArrayList<>();
//		if(p.getNomProces().equals("SAEM")) {
//			String[] header = {"centre", "titulacio", "cod_int", "nom_int", "per_int", "obs_int", "cod_fin", "nom_fin", "per_fin", "obs_fin", "data_fi_docencia"};
//			lines.add(header);
//		}
//		else {
//			String[] header = {"centre", "titulacio", "cod_assignatura_1er", "nom_assignatura_1er", "obs_assignatura_1er", "cod_assignatura_3er", "nom_assignatura_3er", "obs_assignatura_3er"};
//			lines.add(header);
//		}
//				
//		for(Instancia i : ins) {
//			InstanciaTasca it = i.getInstanciaTasca().stream()
//												     .filter(c -> id_t.equals(c.getTasca().getIdTascap()))
//												     .findAny()
//												     .orElse(null);
//			if(it == null) {
//				continue;
//			}
//			if(!it.getEstat().equals("E")){
//				continue;
//			}
//			
//			System.out.println(it.getText());
//			Document doc = Jsoup.parseBodyFragment(it.getText());
//	        int size = lines.get(0).length;
//	        String[] line = new String[size];
//        	line[0] = i.getCentre().toString();
//			line[1] = i.getTitulacio().toString();
//			String[] ids = {"", "",
//							//"ind_enquestes_1er_modul_cod", "ind_enquestes_1er_modul_nom", "ind_enquestes_1er_modul_per", "ind_enquestes_1er_modul_obs", 
//					        //"ind_enquestes_3er_modul_cod", "ind_enquestes_3er_modul_nom", "ind_enquestes_3er_modul_per", "ind_enquestes_3er_modul_obs", 
//						    "ind_enquestes_1er_modul_cod", "ind_enquestes_1er_modul_nom", "ind_enquestes_1er_modul_obs", 
//					        "ind_enquestes_3er_modul_cod", "ind_enquestes_3er_modul_nom", "ind_enquestes_3er_modul_obs", 
//					        "mceEditable"};
//
//			for(int x = 2; x<=8; x++) {
//				if(ids[x].startsWith("ind_")) {
//					try {
//						if(ids[x].equals("ind_enquestes_1er_modul_obs")) {
//							line[x] = doc.getElementById("ind_enquestes_1er_modul_nom").nextElementSibling().text();
//						}
//						else {
//							System.out.println(doc.getElementById(ids[x]));
//							line[x] = doc.getElementById(ids[x]).text();
//						}
//						
//					}
//					catch(Exception e) {
//						line[x] = "[error]";
//						System.out.println("instancia: "+i.getIdInstancia().toString()+", centre: "+i.getCentre().toString()+", titulacio: "+i.getTitulacio().toString());
//					}
//				}/*
//				else {
//					try {
//						line[x] = doc.getElementsByClass(ids[x]).last().text();
//					}
//					catch(Exception e) {
//						line[x] = "[error]";
//						System.out.println("instancia: "+i.getIdInstancia().toString()+", centre: "+i.getCentre().toString()+", titulacio: "+i.getTitulacio().toString());
//					}
//				}*/	
//			}
//
//			lines.add(line);    
//		}
//		
//		lines.stream()
//	         .map(this::convertToCSV)
//	         .forEach(pw::println);
//		pw.close();
//		pw.flush();
//	}

	/*
	 * Export data for a given process and task as CSV (not used)
	 * @param model
	 * @param auth Authentication
	 * @param response HttpServletResponse
	 * @param id_p Process ID
	 * @param id_t Task ID
	 */
	@GetMapping("/export2/{id_p}/{id_t}")  
	public void exportData2(Model model, Authentication auth, HttpServletResponse response, 
			@PathVariable Integer id_p, @PathVariable Integer id_t) throws IOException {
		if(!((Usuari)auth.getPrincipal()).isAdmin() & !((Usuari)auth.getPrincipal()).isDataTest()) {
			return;
		}
		
		response.setContentType("text/csv");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=data_export.csv");
		
		PrintWriter pw = response.getWriter();
		Proces p = this.ps.findByID(id_p);
		List<Instancia> ins = p.getInstancies();
		List<String[]> lines = new ArrayList<>();
		String[] header = {"centre", "titulacio", "nom", "cognoms", "email"};
		lines.add(header);
				
		for(Instancia i : ins) {
			InstanciaTasca it = i.getInstanciaTasca().stream()
												     .filter(c -> c.getTasca().getIdTascap().compareTo(id_t) == 0)
												     .findAny()
												     .orElse(null);
			
			if(it == null) {
				continue;
			}
			if(it.getEstat().isEmpty() || it.getEstat().isBlank()){
				continue;
			}
			if(!it.getEstat().equals("E")){
				continue;
			}
			
			Document doc = Jsoup.parseBodyFragment(it.getText());
	        int size = lines.get(0).length;   

			Elements rows = doc.getElementsByTag("tr");
			for(Element row : rows) {
				Elements cells = row.getElementsByTag("td");
				if(cells.get(0).text().equals("NOM")) {
					continue;
				}
				String[] line = new String[size];
				if(!cells.get(1).text().isEmpty()) {
					line[0] = i.getCentre().toString();
					line[1] = i.getTitulacio().toString();
					line[2] = cells.get(0).text();
					line[3] = cells.get(1).text();
					line[4] = cells.get(2).text();
					lines.add(line); 
				}
			}		
		}
		
		lines.stream()
	         .map(this::convertToCSV)
	         .forEach(pw::println);
		pw.close();
		pw.flush();
	}
	
	/*
	 * Convert an array of Strings to a single CSV line, escaping special characters
	 * @param data Array of Strings to convert
	 * @return A single CSV line as a String
	 */
	public String convertToCSV(String[] data) {
	    return Stream.of(data)
	      .map(this::escapeSpecialCharacters)
	      .collect(Collectors.joining(";"));
	}
	
	/*
	 * Escape special characters in a String for CSV format
	 * @param data The String to escape
	 * @return The escaped String
	 */
	public String escapeSpecialCharacters(String data) {
		if(data == null) return "";
	    String escapedData = data.replaceAll("\\R", " ");
	    data = data.replace("\"", "'");   
	    data = data.replace(";", ","); 
	    data = data.replace("\n", " ");
	    escapedData = "\"" + data + "\"";
	    return escapedData;
	}
	
	
}
