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.TeamDto;
import cz.muni.fi.pa165.soccermanager.dto.request.UpdateTeamDto;
import cz.muni.fi.pa165.soccermanager.dto.request.CreateTeamRequest;
import cz.muni.fi.pa165.soccermanager.service.MatchService;
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 javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

    private final TeamService teamService;
    private final UserService userService;
    private final MatchService matchService;

    @Operation(summary = "Assign user to team",
        description = "The purpose of this method is to assign user to given free team. Available to Admin and User roles."
            + "User can assign free team only to themself")
    @PostMapping("/teams/{teamId}/{userId}")
    public ResponseEntity<Void> assignTeamToUser(@PathVariable Long teamId, @PathVariable Long userId) {
        userService.assignTeamToUser(teamId, userId);
        return ResponseEntity.accepted().build();
    }

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

    @Operation(summary = "Get all teams",
        description = "The purpose of this method is to provide all teams for given league. Available to Admin and User roles.")
    @GetMapping("/league/{leagueId}/teams")
    public ResponseEntity<List<TeamDto>> getTeamsByLeague(@PathVariable Long leagueId){
        return ResponseEntity.ok(teamService.getAllTeamsByLeague(leagueId));
    }

    @Operation(summary = "Get all teams",
        description = "The purpose of this method is to provide all teams for given championship. Available to Admin and User roles.")
    @GetMapping("/championships/{championshipId}/teams")
    public ResponseEntity<List<TeamDto>> getTeamsByChampionship(@PathVariable Long championshipId){
        return ResponseEntity.ok(teamService.getAllTeamsByChampionship(championshipId));
    }

    @Operation(summary = "Update team",
        description = "The purpose of this method is to update team. Available to Admin and User-owner of the team.")
    @PutMapping("/teams/{teamId}")
    public ResponseEntity<Void> updateTeam(@Valid @RequestBody UpdateTeamDto newUpdateTeamDTO, @PathVariable Long teamId) {
        teamService.update(teamId, newUpdateTeamDTO);
        return ResponseEntity.accepted().build();
    }

    @Operation(summary = "Create team",
        description = "The purpose of this method is to create team for given league. Available only to Admin role.")
    @PostMapping("/leagues/{leagueId}/teams")
    public ResponseEntity<UpdateTeamDto> createTeam(@PathVariable Long leagueId, @Valid @RequestBody CreateTeamRequest request) {
        final var next = teamService.createTeam(leagueId, request);
        final var t = new UpdateTeamDto();
        t.setId(next);
        return ResponseEntity.ok(t);
    }

    @Operation(summary = "Get all matches of team",
        description = "The purpose of this method is to provide matches for given team. Available to Admin and User roles.")
    @GetMapping("/teams/{teamId}/matches")
    public ResponseEntity<List<MatchDto>> findTeamMatches(@PathVariable Long teamId) {
        return ResponseEntity.ok(matchService.getMatchesByTeamId(teamId));
    }
}
