package BOLO.controller;
import BOLO.ViewModel.BolosBagResponseVM;
import BOLO.model.Bolo;
import BOLO.model.BoloUser;
import BOLO.repository.BoloRepository;
import BOLO.repository.UserRepository;
import BOLO.services.EmailServiceImpl;
import java.security.Principal;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;

import com.auth0.jwt.JWT;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.data.domain.PageRequest;
import static BOLO.security.SecurityConstants.EXPIRATION_TIME;
import static BOLO.security.SecurityConstants.SECRET;
import static com.auth0.jwt.algorithms.Algorithm.HMAC512;
/*
This controller is the facade for the model layer of the application.
all requests to the database are handled through this controller.
 */

@RestController
@RequestMapping(path = "api/boloes")
@CrossOrigin
public class BoloController{
    
   

    @Autowired // This means to get the bean called AgencyRepository
    // Which is auto-generated by Spring, we will use it to handle the data
    private BoloRepository BoloRepository;
    @Autowired
    private EmailServiceImpl emailService;

    @Autowired
    private UserRepository userRepository;
    @RequestMapping(method = RequestMethod.POST)
    public ResponseEntity<Bolo> createBolo(@RequestBody Bolo bolo,Principal principal){
        
        try{
            BoloUser user = userRepository.findOneByUsername(principal.getName());
            if(user==null){
                return ResponseEntity.status(HttpStatus.FORBIDDEN).body(null);
            }
            bolo.setAuthor(user);
            bolo.setAgency(user.getAgency());            
            // YGP: I changed this to 'true' to set BOLO to confirmed without confirmation email.
            bolo.setIsConfirmed(true);

            String token = UUID.randomUUID().toString();
            bolo.setConfirmationToken(token);
            BoloRepository.save(bolo);
            ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentRequestUri();

            // YGP: commented this line to avoid sending confirmation email.
            // emailService.sendCreateBoloNotification(user.getEmail(),builder.build().toUriString()+"confirm/"+token);
        }catch(Exception e){
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
            
                   
        return ResponseEntity.status(HttpStatus.CREATED).body(null);

    }
      

    @RequestMapping(method = RequestMethod.GET,value = "/confirm/{token}")
	public void Confirm(@PathVariable String token,HttpServletResponse httpServletResponse){
            Bolo bolo = BoloRepository.findByToken(token);
            if(bolo != null){
               bolo.setIsConfirmed(true); 
               BoloRepository.save(bolo);
               //@Todo add list of receivers. It needs to came from subscription. 
               emailService.boloCreationNotification("jleyv018@fiu.edu", bolo);    
            }else{
                //@TODO Log suspicious access
            }
            httpServletResponse.setHeader("Location", "/bolo");
            httpServletResponse.setStatus(302);
	        
	}

    @RequestMapping(method = RequestMethod.GET)
	public BolosBagResponseVM<Bolo> Get(@RequestParam int page, @RequestParam int size){

            //@For you looking for something usufull to do. Here we return the whole model for the bolo with a bunch of unsuful things.
            //Including user information. Scary!!!!!!!!
            //It would be a way better if we create a responseVM that will just return back the information used to list the bolos. 
            //@Also fluent API is never a bad thing to implement. ;) 
            List<Bolo> bolos = BoloRepository.findByIsConfirmedOrderByUpdateOnDesc(true,PageRequest.of(page, size));

            BolosBagResponseVM<Bolo> response = new BolosBagResponseVM<Bolo>();
            response.setSize(size);
            response.setTotalItems(BoloRepository.findByIsConfirmed(true,null).size());
            response.setPage(page);
            response.setItems(bolos);

	        return response;
	}
    
    @RequestMapping(method = RequestMethod.GET,value = "/{id}")
    public Optional<Bolo> Get(@PathVariable long id) {
        Optional<Bolo> bolo = BoloRepository.findById(id);
        return bolo;
     }
    //@TODO Please do not implemet a physical delete. At most a logical one. 
}
