package cz.muni.fi.pa165.soccermanager.controllers;


import static cz.muni.fi.pa165.soccermanager.ApplicationConstants.API_URL;

import cz.muni.fi.pa165.soccermanager.dto.MatchDto;
import cz.muni.fi.pa165.soccermanager.dto.PlayerDto;
import cz.muni.fi.pa165.soccermanager.dto.TeamDto;
import cz.muni.fi.pa165.soccermanager.dto.UserDto;
import cz.muni.fi.pa165.soccermanager.security.AuthServiceImpl;
import cz.muni.fi.pa165.soccermanager.service.TeamService;
import cz.muni.fi.pa165.soccermanager.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "User")
@RestController
@RequestMapping(API_URL)
@RequiredArgsConstructor
@CrossOrigin(origins = "*")
@SecurityRequirement(name = "bearerAuth")
public class UserController {

    private final UserService userService;
    private final TeamService teamService;
    private final AuthServiceImpl authService;

    @Operation(summary = "Get user",
        description = "The purpose of this method is to provide user. Available to Admin and User roles.")
    @GetMapping("/users/{userId}")
    public ResponseEntity<UserDto> getUserById(@PathVariable Long userId) {
        return ResponseEntity.of(userService.findUserById(userId));
    }

    @Operation(summary = "Get all users",
        description = "The purpose of this method is to provide all users. Available to Admin and User roles.")
    @GetMapping("/users")
    public Page<UserDto> getUsers(@RequestParam("page") Optional<Integer> page,
                                      @RequestParam("size") Optional<Integer> size, @RequestParam Optional<String> sortBy){
        return userService.getAllUsers(page.orElse(0), size.orElse(10), sortBy.orElse("id"));    }

    @Operation(summary = "Delete user",
        description = "The purpose of this method is to delete user. Available only to Admin role. Admin can not delete themself.")
    @DeleteMapping("users/{userId}")
    public ResponseEntity<Void> remove(@PathVariable Long userId){
        authService.removeUser(userId);
        return ResponseEntity.noContent().build();
    }

    @Operation(summary = "Remove team",
        description = "The purpose of this method is to remove user connection to team. Available to Admin and User-owner of team.")
    @PutMapping("users/{userId}/team")
    public ResponseEntity<Void> removeTeam(@PathVariable Long userId) {
        userService.removeTeam(userId);
        return ResponseEntity.accepted().build();
    }

    @Operation(summary = "Get user's team",
        description = "The purpose of this method is to provide user's team. Available to Admin and User roles.")
    @GetMapping("/users/{userId}/team")
    public ResponseEntity<TeamDto> findTeamByUserId(@PathVariable Long userId) {
        return ResponseEntity.of(teamService.findTeamByUserId(userId));
    }

    @Operation(summary = "Get user's matches",
        description = "The purpose of this method is to provide all matches user's team participate to. Available to Admin and User roles.")
    @GetMapping("users/{userId}/team/matches")
    public ResponseEntity<List<MatchDto>> findUserMatches(@PathVariable Long  userId) {
        return ResponseEntity.ok(userService.findUserMatches(userId));
    }

    @Operation(summary = "Get user's players",
        description = "The purpose of this method is to provide all the players belong to user's team. Available to Admin and User roles.")
    @GetMapping("users/{userId}/team/players")
    public ResponseEntity<List<PlayerDto>> findUserPlayers(@PathVariable Long userId){
        return ResponseEntity.ok(userService.findUserPlayers(userId));
    }
}