public async Task <IActionResult> ManagerClaimGame([FromBody] ClaimGameRequest request)
    {
        var leagueYearPublisherRecord = await GetExistingLeagueYearAndPublisher(request.PublisherID, ActionProcessingModeBehavior.Ban, RequiredRelationship.LeagueManager, RequiredYearStatus.YearNotFinishedDraftFinished);

        if (leagueYearPublisherRecord.FailedResult is not null)
        {
            return(leagueYearPublisherRecord.FailedResult);
        }
        var validResult = leagueYearPublisherRecord.ValidResult !;
        var leagueYear  = validResult.LeagueYear;
        var publisher   = validResult.Publisher;

        MasterGame?masterGame = null;

        if (request.MasterGameID.HasValue)
        {
            masterGame = await _interLeagueService.GetMasterGame(request.MasterGameID.Value);
        }

        bool counterPickedGameIsManualWillNotRelease = PlayerGameExtensions.CounterPickedGameIsManualWillNotRelease(leagueYear, request.CounterPick, masterGame, false);
        ClaimGameDomainRequest domainRequest         = new ClaimGameDomainRequest(leagueYear, publisher, request.GameName, request.CounterPick, counterPickedGameIsManualWillNotRelease, request.ManagerOverride, false, masterGame, null, null);
        ClaimResult            result = await _gameAcquisitionService.ClaimGame(domainRequest, true, false, false);

        var viewModel = new ManagerClaimResultViewModel(result);

        await _fantasyCriticService.UpdatePublisherGameCalculatedStats(leagueYear);

        return(Ok(viewModel));
    }
        public async Task <ClaimResult> ClaimGame(ClaimGameDomainRequest request)
        {
            PublisherGame playerGame = new PublisherGame(Guid.NewGuid(), request.GameName, _clock.GetCurrentInstant(), request.CounterPick, null, null,
                                                         new MasterGameYear(request.MasterGame.Value, request.Publisher.Year), request.DraftPosition, request.OverallDraftPosition, request.Publisher.Year);

            ClaimResult claimResult = await CanClaimGame(request);

            if (!claimResult.Success)
            {
                return(claimResult);
            }

            LeagueAction leagueAction = new LeagueAction(request, _clock.GetCurrentInstant());
            await _fantasyCriticRepo.AddLeagueAction(leagueAction);

            await _fantasyCriticRepo.AddPublisherGame(request.Publisher, playerGame);

            return(claimResult);
        }
        public async Task <ClaimResult> MakePickupBid(Publisher publisher, MasterGame masterGame, uint bidAmount)
        {
            if (bidAmount > publisher.Budget)
            {
                return(new ClaimResult(new List <ClaimError>()
                {
                    new ClaimError("You do not have enough budget to make that bid.", false)
                }));
            }

            IReadOnlyList <PickupBid> pickupBids = await _fantasyCriticRepo.GetActivePickupBids(publisher);

            bool alreadyBidFor = pickupBids.Select(x => x.MasterGame.MasterGameID).Contains(masterGame.MasterGameID);

            if (alreadyBidFor)
            {
                return(new ClaimResult(new List <ClaimError>()
                {
                    new ClaimError("You cannot have two active bids for the same game.", false)
                }));
            }

            var claimRequest = new ClaimGameDomainRequest(publisher, masterGame.GameName, false, false, masterGame, null, null);
            var claimResult  = await CanClaimGame(claimRequest);

            if (!claimResult.Success)
            {
                return(claimResult);
            }

            var nextPriority = pickupBids.Count + 1;

            PickupBid currentBid = new PickupBid(Guid.NewGuid(), publisher, masterGame, bidAmount, nextPriority, _clock.GetCurrentInstant(), null);
            await _fantasyCriticRepo.CreatePickupBid(currentBid);

            return(claimResult);
        }
        private async Task <ClaimResult> CanClaimGame(ClaimGameDomainRequest request)
        {
            List <ClaimError> claimErrors = new List <ClaimError>();

            var basicErrors = await GetBasicErrors(request.Publisher.League, request.Publisher);

            claimErrors.AddRange(basicErrors);

            var leagueYear = await _fantasyCriticRepo.GetLeagueYear(request.Publisher.League, request.Publisher.Year);

            if (leagueYear.HasNoValue)
            {
                throw new Exception("Something has gone terribly wrong with league years.");
            }

            LeagueOptions yearOptions = leagueYear.Value.Options;

            if (request.MasterGame.HasValue)
            {
                var masterGameErrors = GetMasterGameErrors(leagueYear.Value.Options, request.MasterGame.Value, leagueYear.Value.Year, request.CounterPick);
                claimErrors.AddRange(masterGameErrors);
            }

            IReadOnlyList <Publisher> allPublishers = await _fantasyCriticRepo.GetPublishersInLeagueForYear(request.Publisher.League, request.Publisher.Year);

            IReadOnlyList <Publisher> otherPublishers = allPublishers.Where(x => x.User.UserID != request.Publisher.User.UserID).ToList();

            IReadOnlyList <PublisherGame> gamesForYear      = allPublishers.SelectMany(x => x.PublisherGames).ToList();
            IReadOnlyList <PublisherGame> thisPlayersGames  = request.Publisher.PublisherGames;
            IReadOnlyList <PublisherGame> otherPlayersGames = otherPublishers.SelectMany(x => x.PublisherGames).ToList();

            bool gameAlreadyClaimed = gamesForYear.ContainsGame(request);

            if (!request.CounterPick)
            {
                if (gameAlreadyClaimed)
                {
                    claimErrors.Add(new ClaimError("Cannot claim a game that someone already has.", false));
                }

                int leagueDraftGames = yearOptions.StandardGames;
                int userDraftGames   = thisPlayersGames.Count(x => !x.CounterPick);
                if (userDraftGames == leagueDraftGames)
                {
                    claimErrors.Add(new ClaimError("User's game spaces are filled.", false));
                }
            }

            if (request.CounterPick)
            {
                bool otherPlayerHasCounterPick = otherPlayersGames.Where(x => x.CounterPick).ContainsGame(request);
                if (otherPlayerHasCounterPick)
                {
                    claimErrors.Add(new ClaimError("Cannot counter-pick a game that someone else has already counter-picked.", false));
                }

                bool otherPlayerHasDraftGame = otherPlayersGames.Where(x => !x.CounterPick).ContainsGame(request);

                int leagueCounterPicks = yearOptions.CounterPicks;
                int userCounterPicks   = thisPlayersGames.Count(x => x.CounterPick);
                if (userCounterPicks == leagueCounterPicks)
                {
                    claimErrors.Add(new ClaimError("User's counter pick spaces are filled.", false));
                }

                if (!otherPlayerHasDraftGame)
                {
                    claimErrors.Add(new ClaimError("Cannot counterPick a game that no other player is publishing.", false));
                }
            }

            var result = new ClaimResult(claimErrors);

            if (result.Overridable && request.ManagerOverride)
            {
                return(new ClaimResult(new List <ClaimError>()));
            }

            return(result);
        }