package es.uv.garcosda.input.controllers;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

import es.uv.garcosda.shared.domain.Mail;
import es.uv.garcosda.shared.domain.MailDTO;
import es.uv.garcosda.shared.domain.User;

@RestController
@RequestMapping("/api/v1")
public class InputController {

	@Autowired
    private RestTemplate template;
	
	@Value("${mailer.data.url}")
	private String api;
	
	@GetMapping("status")
	public ResponseEntity<String> test(){
		return new ResponseEntity<String>("Running", HttpStatus.OK);
	}
	
	@GetMapping("{mail}")
	@HystrixCommand(fallbackMethod="fallbackDataApi")
	public ResponseEntity<?> getMails(@PathVariable String mail){
		ResponseEntity<Mail[]> response;
		List<MailDTO> mailsdto = new ArrayList<MailDTO>(); 
		User u = this.getUser(mail);
		try {
			response = template.getForEntity(api+"/mails?to="+u.getId(), Mail[].class); 
		}
		catch(ResourceAccessException e){
			return new ResponseEntity<List<MailDTO>>(mailsdto, HttpStatus.SERVICE_UNAVAILABLE);
		}
		if(response.getStatusCode() == HttpStatus.OK) {
			for(Mail m : Arrays.stream(response.getBody()).collect(Collectors.toList())) {
				mailsdto.add(new MailDTO(m.getId(), this.getUser(m.getFrom()), 
							 this.getUser(m.getTo()), m.getSubject(), m.getBody(), 
							 new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(m.getDate())));
			}
			return new ResponseEntity<List<MailDTO>>(mailsdto, HttpStatus.OK);
		}
		return new ResponseEntity<List<MailDTO>>(mailsdto, HttpStatus.SERVICE_UNAVAILABLE);
	}
	
	@DeleteMapping("{id}")
	public ResponseEntity<?> deleteMail(@PathVariable String id){
		try {
			template.delete(api+"/mails/"+id);
			return new ResponseEntity<String>("Deleted", HttpStatus.OK);
		}
		catch(ResourceAccessException e){
			return new ResponseEntity<String>("Not available", HttpStatus.SERVICE_UNAVAILABLE);
		}
	}
	
	private User getUser(String var) {
		ResponseEntity<User> response;
		try {
			if(var.contains("@")) {
				response = template.getForEntity(api+"/users/email/"+var.toLowerCase(), User.class); 
			}
			else {
				response = template.getForEntity(api+"/users/id/"+var, User.class); 
			}
		}
		catch(ResourceAccessException e){
			return new User();
		}
		if(response.getStatusCode() == HttpStatus.OK) {
			return response.getBody();
		}
		return new User();
	}
	
	@SuppressWarnings("unused")
	private ResponseEntity<?> fallbackDataApi() {
		return new ResponseEntity<String>("Not available at this moment, try again later.", HttpStatus.SERVICE_UNAVAILABLE);
	}
	
}
