package ovh.herisson.Clyde.EndPoints;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.ProtectionService;
import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


@RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
public class UserController {

    private final UserService userService;
    private final AuthenticatorService authServ;
    public UserController(UserService userService, AuthenticatorService authServ){
        this.userService = userService;
        this.authServ = authServ;
    }

    /** returns information about the connected user
     *
     * @param token the session token of the user
     * @return the user information except his password
     */
    @GetMapping("/user")
    public ResponseEntity<HashMap<String,Object>> getUser(@RequestHeader("Authorization") String token){

        User user = authServ.getUserFromToken(token);
            if (user == null) return new UnauthorizedResponse<>(null);

        return new ResponseEntity<>(ProtectionService.userWithoutPassword(user), HttpStatus.OK);
    }


    @GetMapping("/user/{id}")
    public ResponseEntity<HashMap<String ,Object>> getUserById(@RequestHeader("Authorization") String token, @PathVariable Long id){

        if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
            return new UnauthorizedResponse<>(null);

        return new ResponseEntity<>(ProtectionService.userWithoutPassword(userService.getUserById(id)), HttpStatus.OK);
    }

    @PostMapping("/user")
    public ResponseEntity<Map<String ,Object>> postUser(@RequestBody User user,@RequestHeader("Authorization") String token){

        if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService,Role.Secretary},token))
            return new UnauthorizedResponse<>(null);

        return new ResponseEntity<>(ProtectionService.userWithoutPassword(userService.save(user)),HttpStatus.CREATED);
    }

    @GetMapping("/users")
    public ResponseEntity<Iterable<HashMap<String,Object>>> getAllUsers(@RequestHeader("Authorization") String token){

        if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token))
          return new UnauthorizedResponse<>(null);

        Role posterRole = authServ.getUserFromToken(token).getRole();

        Iterable<User> users = new ArrayList<>();

        if (posterRole == Role.Admin)
            users = userService.getAll();

        else if (posterRole == Role.Secretary)
            users = userService.getAllExceptAdmins();

        return new ResponseEntity<>(ProtectionService.usersWithoutPasswords(users), HttpStatus.OK);
    }

    /** changes the specified user's information
     *
     * @param updates the changes to be made
     * @param token the session token of the user posting the change
     * @param id the id of the user to change
     * @return a string clarifying the issue (if there is any)
     */
    @PatchMapping("/user/{id}")
    public ResponseEntity<String> patchUser(@RequestHeader("Authorization") String token,
                                            @RequestBody Map<String,Object> updates,
                                            @PathVariable Long id) {

        if (token == null) return new UnauthorizedResponse<>(null);

        User poster = authServ.getUserFromToken(token);
        if (poster == null) {return new UnauthorizedResponse<>("bad token");}

        if (!userService.modifyData(id, updates, poster))
            return new UnauthorizedResponse<>("there was an issue with the updates requested");

        return new ResponseEntity<>(null, HttpStatus.OK);
    }

    @GetMapping("/teachers")
    public ResponseEntity<Iterable<HashMap<String,Object>>> getAllTeachers(@RequestHeader("Authorization") String token){
        if (authServ.getUserFromToken(token) == null)
            return new UnauthorizedResponse<>(null);

        Iterable<User> teachers = userService.getAllTeachers();

        return new ResponseEntity<>(ProtectionService.usersWithoutPasswords(teachers), HttpStatus.OK);
    }


    @GetMapping("/students")
    public ResponseEntity<Iterable<HashMap<String,Object>>> getAllStudent(@RequestHeader("Authorization") String token){
        if (authServ.getUserFromToken(token) == null)
            return new UnauthorizedResponse<>(null);

        Iterable<User> students = userService.getAllStudents();

        return new ResponseEntity<>(ProtectionService.usersWithoutPasswords(students), HttpStatus.OK);
    }


    @DeleteMapping("/user/{id}")
    public ResponseEntity<String> deleteStudent(@RequestHeader("Authorization") String token, @PathVariable Long id){
        if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token))
            return new UnauthorizedResponse<>(null);

        User toDelete = userService.getUserById(id);

        if (toDelete == null)
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);

        userService.delete(toDelete);
        return new ResponseEntity<>(HttpStatus.OK);
    }
}
