package GameNationBackEnd.Controllers;

import GameNationBackEnd.Documents.Game;
import GameNationBackEnd.RequestDocuments.SkillLevelRequest;
import GameNationBackEnd.Documents.User;
import GameNationBackEnd.Documents.UserGame;
import GameNationBackEnd.Repositories.GameRepository;
import GameNationBackEnd.Repositories.UserGameRepository;
import GameNationBackEnd.Repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.security.Principal;
import java.util.*;

import GameNationBackEnd.Exceptions.*;

/**
 * Created by lucas on 17/11/2016.
 */
@RestController
@CrossOrigin
@RequestMapping("/api/users")
public class UsersController {


    @Autowired
    private UserRepository userDB;

    @Autowired
    private UserGameRepository userGameDB;

    @Autowired
    private GameRepository gameRepository;

    // get all users
    @RequestMapping(method = RequestMethod.GET)
    public List<User> GetUsers() {
        return userDB.findAll();
    }

    // get user by username
    @RequestMapping(method = RequestMethod.GET, params = {"username"})
    public List<User> GetUserByUsername(@RequestParam String username) {
        User user = userDB.findByUsername(username);
        if (user != null) {
            return Arrays.asList(userDB.findByUsername(username));
        } else {
            return new ArrayList<>();
        }
    }

    // get user by id
    @RequestMapping(value = "/{user}", method = RequestMethod.GET)
    public User GetUser(@PathVariable User user) {
        return user;
    }

    // update user
    @RequestMapping(value = "/{user}", method = RequestMethod.POST)
    public User UpdateUser(@PathVariable User user, @RequestBody User updatedUser) {
        // either this
        if (updatedUser.getUsername() != null) {
            user.setUsername(updatedUser.getUsername());
        }
        if (updatedUser.getEmail() != null) {
            user.setEmail(updatedUser.getEmail());
        }
        if (updatedUser.getPassword() != null) {
            user.setPassword(updatedUser.getPassword());
        }
        if (updatedUser.getFirstname() != null) {
            user.setFirstname(updatedUser.getFirstname());
        }
        if (updatedUser.getLastname() != null) {
            user.setLastname(updatedUser.getLastname());
        }
        if (updatedUser.getTeamspeak() != null) {
            user.setTeamspeak(updatedUser.getTeamspeak());
        }
        if (updatedUser.getDiscord() != null) {
            user.setDiscord(updatedUser.getDiscord());
        }
        if (updatedUser.getDescription() != null) {
            user.setDescription(updatedUser.getDescription());
        }

        // or this , with @Valid @RequestBody User updatedUser
//        updatedUser.setId(user.getId());

        return userDB.save(updatedUser);
    }

    // create a user
    @RequestMapping(method = RequestMethod.POST)
    @ResponseStatus(value = HttpStatus.CREATED)
    public User InsertUser(@Valid @RequestBody User user) throws UserAlreadyExistsException {
        if (userDB.findByUsername(user.getUsername()) != null) {
            throw new UserAlreadyExistsException(user.getId());
        } else {
            return userDB.save(user);
        }
    }

    // delete user
    @RequestMapping(value = "/{user}", method = RequestMethod.DELETE)
    public void DeleteUser(@PathVariable User user) {
        userDB.delete(user);
    }

    // get games for user
    @RequestMapping(value = "/{user}/games", method = RequestMethod.GET)
    public List<UserGame> GetGamesFromUser(@PathVariable User user) {
        return userGameDB.findByUser(user);
    }

    // add games to user
    @RequestMapping(value = "/{user}/games", method = RequestMethod.POST)
    public List<UserGame> AddGamesToUser(@PathVariable User user, @RequestBody List<String> games) {
        // skill moe wel hier nie peisk als ge het nie toevoegt van de eerste keer.
        // of ja alleszins altijd 0 zijn zoals.. wel hier :p
        int skill = new Integer(0);

        List<Game> gameList = gameRepository.findByIdIn(games);
        for (Game game : gameList) {
            if (!userGameDB.findByUser(user).stream().anyMatch(ug -> ug.getGame().equals(game))) {
                UserGame newUserGame = new UserGame(user, game, skill);
                userGameDB.save(newUserGame);
            } else {
                UserGame editUserGame = userGameDB.findByUserAndGame(user, game);
                if (editUserGame.getSkill_level() != skill) {
                    editUserGame.setSkill_level(skill);
                    userGameDB.save(editUserGame);
                } else throw new GameAlreadyExistsException(game.getId());
            }
        }

        return userGameDB.findByUser(user);
    }

    // set skill on game for user
    @RequestMapping(value = "/{user}/games/{game}", method = RequestMethod.POST)
    public UserGame setSkillLevelForUserGame(@PathVariable User user, @PathVariable Game game, @RequestBody SkillLevelRequest skillLevel) {
        UserGame ug = userGameDB.findByUserAndGame(user, game);
        ug.setSkill_level(skillLevel.level);
        return userGameDB.save(ug);
    }

    // delete game from user
    @RequestMapping(value = "/{user}/games/{game}", method = RequestMethod.DELETE)
    public void deleteGameFromUser(@PathVariable User user, @PathVariable Game game) {
        UserGame ug = userGameDB.findByUserAndGame(user, game);
        userGameDB.delete(ug);
    }

    // get logged in user
    @RequestMapping(value = "/me", method = RequestMethod.GET)
    public User GetAuthenticatedUser(Principal principal) {
        // principal contains authenticated user name
        User user = userDB.findByUsername(principal.getName());
        return user;
    }
}

@@ -3975,190 +3975,8 @@
 ) %7B%0A
-        // skill moe wel hier nie peisk als ge het nie toevoegt van de eerste keer.%0A        // of ja alleszins altijd 0 zijn zoals.. wel hier :p%0A        int skill = new Integer(0);%0A%0A
     
@@ -4035,24 +4035,25 @@
 games);%0A
+%0A
         
 for (Gam
@@ -4048,48 +4048,84 @@
     
-for (Game game : gameList) %7B%0A   
+// check if any of the games already exist in the user's collection%0A
         
  if 
@@ -4124,14 +4124,8 @@
     
- if (!
 user
@@ -4161,14 +4161,13 @@
 m().
-anyMat
+forEa
 ch(u
@@ -4175,256 +4175,122 @@
  -%3E 
-ug.getGame().equals(game))) %7B%0A                UserGame newUserGame = new UserGame(user, game, skill);%0A                userGameDB.save(newUserGame);%0A            %7D else %7B%0A                UserGame editUserGame = userGameDB.findByUserAndGame(user, game
+%7B%0A           if (gameList.contains(ug)) %7B%0A               throw new GameAlreadyExistsException(ug.getGame().getId()
 );%0A 
@@ -4303,123 +4303,60 @@
     
+%7D%0A
      
-if (editUserGame.getSkill_level() != skill) %7B%0A                    editUserGame.setSkill_level(skill);%0A        
+   %7D);%0A%0A        for (Game game : gameList) %7B%0A
     
@@ -4383,20 +4383,20 @@
 ave(
-edit
+new 
 UserGame
 );%0A 
@@ -4395,99 +4395,24 @@
 Game
-);%0A                %7D else throw new GameAlreadyExistsException(game.getId());%0A            %7D
+(user,game, 0));
 %0A   

Refactor adding game to user