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

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

import cz.muni.fi.pa165.soccermanager.ApplicationConstants;
import cz.muni.fi.pa165.soccermanager.dto.MatchDto;
import cz.muni.fi.pa165.soccermanager.dto.MatchScoreDto;
import cz.muni.fi.pa165.soccermanager.dto.request.CreateMatchRequest;
import cz.muni.fi.pa165.soccermanager.dto.request.UpdateMatchDto;
import cz.muni.fi.pa165.soccermanager.service.MatchService;
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.net.URI;
import java.util.List;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

    private final MatchService matchService;

    @Operation(summary = "Get all match by id",
        description = "The purpose of this method is to provide match. Available to Admin and User roles.")
    @GetMapping("matches/{matchId}")
    public ResponseEntity<MatchDto> getMatchById(@PathVariable Long matchId) {
        return ResponseEntity.of(matchService.findMatchById(matchId));
    }

    @Operation(summary = "Update match",
        description = "The purpose of this method is to update match. Available only to Admin role.")
    @PutMapping("/matches/{matchId}")
    public ResponseEntity<Void> updateMatch(@Valid @RequestBody UpdateMatchDto newMatchDto, @PathVariable Long matchId) {
        matchService.update(matchId,newMatchDto);
        return ResponseEntity.accepted().build();
    }

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

    @Operation(summary = "Create match for given league",
        description = "The purpose of this method is to create match. Available to Admin and User roles.")
    @PostMapping("leagues/{leagueId}/matches")
    public ResponseEntity<MatchDto> saveMatch(@Valid @RequestBody CreateMatchRequest request, @PathVariable Long leagueId) {
        final var id = matchService.saveMatch(request, leagueId);
        final var next = new MatchDto();
        next.setId(id);
        return ResponseEntity.created(URI.create(ApplicationConstants.MATCH_URL + next.getId())).body(next);
    }

    @Operation(summary = "Play match",
        description = "The purpose of this method is to play match. Available to Admin and User roles.")
    @GetMapping("matches/play/{matchId}")
    public MatchScoreDto playMatch(@PathVariable Long matchId) {
        return matchService.playMatch(matchId);
    }
}
