package es.uv.saic.web;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import jakarta.mail.MessagingException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.Authentication;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import es.uv.saic.domain.Datasource;
import es.uv.saic.dto.ImportDTO;
import es.uv.saic.dto.IndicadorEnquestaTmpDup;
import es.uv.saic.dto.TablaDTO;
import es.uv.saic.service.DataService;
import es.uv.saic.service.DatasourceService;

@RestController
@RequestMapping("/data")
public class DataController {

	@Autowired
	private DataService ips;

	@Autowired
	private DatasourceService das;
	
	// GET que carga la interfaz relacionada con toda la importación de datos
	@GetMapping("/import")
	public List<Datasource> renderImport() {
		return this.das.findAll();
	}
	
	// POST encargado de importar los datos que han sido adjuntados
	@PostMapping("/import")
	public String uploadFile(@RequestBody ImportDTO importDTO) throws IOException, MessagingException, ClassNotFoundException, SQLException { 
		String retval = "";
		if(importDTO.getTipus().equals("file")){
			byte[] fileBytes = importDTO.getFileContent();
			ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes);
			InputStreamReader in = new InputStreamReader(bais);
			retval = ips.doImport(in, importDTO.getPrincipal(), importDTO.getEnquesta(), importDTO.getAmbit(), importDTO.getEstudi(), importDTO.getLocale(),
								importDTO.getDelim(), importDTO.getClau(), importDTO.getIgnoredColumns());
		}
		else if(importDTO.getTipus().equals("db")){
			retval = ips.doDbImport(importDTO.getDbOrigen(), importDTO.getVista(), importDTO.getCurs(), importDTO.getDstCurs(),
								importDTO.getPrincipal(), importDTO.getEnquesta(), importDTO.getAmbit(), importDTO.getEstudi(),
								importDTO.getLocale(), importDTO.getClau(), importDTO.getIgnoredColumns());
		}
		
		return retval;
	}
	
	//GET para cargar el apartado de coonsolidate
	@GetMapping("/consolidate")
	@Secured({"ROLE_ADMIN", "ROLE_TESTER"})
	public String consolidate(Model model, Authentication auth) throws IOException {    
		return "dataConsolidate";
	}
	
	// POST para comprobar si existen problemas con los datos, si estan duplicados o su integridad
	@PostMapping("/check/{type}")
	public List<IndicadorEnquestaTmpDup> check(@RequestBody String enquesta, @PathVariable Integer type) throws IOException {   
		if(type == 1) {
			return this.ips.checkDuplicates(enquesta);
		}
		else {
			return this.ips.checkIntegrity(enquesta);
		}
		
	}
	
	// POST que consolida los datos pasadas por la encuesta
	@PostMapping("/consolidate")
	public Integer consolidate(@RequestBody String enquesta) throws IOException {    
		return this.ips.consolidateByEnquesta(enquesta);
	}
	
	// POST que comprueba los datos a partir de la encuesta
	@PostMapping("/count")
	public Integer countByEnquesta(@RequestBody String enquesta) throws IOException {    
		return this.ips.countByEnquesta(enquesta);
	}

	// POST para mostrar los datos en columnas
	@PostMapping("/view/columns")
	public List<String> listTableColumns(@RequestBody TablaDTO tablaDto) {    
		try {
			return this.ips.listTableColumns(tablaDto.getDbOrigen(), tablaDto.getVista(), tablaDto.getLocale());
		} catch (ClassNotFoundException | SQLException e) {
			return new ArrayList<String>();
		}
	}

	@GetMapping("/sources")
	public List<Datasource> getDatasources() throws IOException {  
		List<Datasource> sources = this.das.findAll();
		for(Datasource d : sources){
			d.setConn(null);
		}
        return sources;
	}
}
