public IHttpActionResult InviteVoters(InviteVotersModel requestModel)
        {
            if (!ModelState.IsValid)
            {
                VerboseReporter.ReportError("Missing required parameters or invalid data submitted", "invite_voters");
                return RespondFailure();
            }

            var videoBattleId = requestModel.VideoBattleId;
            var voterIds = requestModel.VoterIds;
            var emails = requestModel.Emails;
            //first check if it's a valid videobattle and the logged in user can actually invite
            var videoBattle = _videoBattleService.Get(videoBattleId);
            if (videoBattle == null)
            {
                VerboseReporter.ReportError("Battle doesn't exist", "invite_voters");
                return RespondFailure();

            }

            var participants = _videoBattleParticipantService.GetVideoBattleParticipants(videoBattleId,
                BattleParticipantStatus.ChallengeAccepted);

            var model = new List<object>();
            if (CanInvite(videoBattle) ||
                participants.Select(x => x.ParticipantId).Contains(ApplicationContext.Current.CurrentUser.Id))
            {
                if (voterIds != null)
                {
                    var votes = _videoBattleVoteService.GetVideoBattleVotes(videoBattleId, null);

                    foreach (var vi in voterIds)
                    {
                        //exclude self
                        if (vi == ApplicationContext.Current.CurrentUser.Id)
                            continue;
                        var vote = votes.FirstOrDefault(x => x.UserId == vi);
                        if (vote == null)
                        {
                            vote = new VideoBattleVote() {
                                VideoBattleId = videoBattleId,
                                ParticipantId = ApplicationContext.Current.CurrentUser.Id,
                                VoteStatus = BattleVoteStatus.NotVoted,
                                VoteValue = 0,
                                UserId = vi
                            };
                            _videoBattleVoteService.Insert(vote);

                            //send the notification
                            var receiver = _userService.Get(vi);
                            _emailSender.SendVotingReminderNotification(
                                ApplicationContext.Current.CurrentUser, receiver,
                                videoBattle);
                            model.Add(new {
                                Success = true,
                                VoterId = vi,
                            });
                        }
                        else
                        {
                            model.Add(new {
                                Success = false,
                                VoterId = vi,
                                Message = "Already invited"
                            });
                        }
                    }
                }

                if (emails != null)
                {
                    //and direct email invites
                    foreach (var email in emails)
                    {
                        _emailSender.SendVotingReminderNotification(
                            ApplicationContext.Current.CurrentUser, email, email, videoBattle);
                        model.Add(new {
                            Success = true,
                            Email = email,
                        });
                    }
                }
                return RespondSuccess(model);
            }
            VerboseReporter.ReportError("Unauthorized", "invite_voters");
            return RespondFailure();
        }
        public IHttpActionResult VoteBattle(int videoBattleId, int participantId, int voteValue)
        {
            var user = ApplicationContext.Current.CurrentUser;
            //should not vote himself or herself
            if (user.Id == participantId)
            {
                VerboseReporter.ReportError("You can't vote yourself", "vote_battle");
                return RespondFailure();
            }

            //in any case a sponsor can't vote a battle
            if (_sponsorService.IsSponsor(ApplicationContext.Current.CurrentUser.Id, videoBattleId, BattleType.Video))
            {
                VerboseReporter.ReportError("Sponsors can't vote on a battle", "vote_battle");
                return RespondFailure();
            }

            //has the person watched all the videos before voting can be done
            //get all the videos of current battle
            var battleVideos = _videoBattleVideoService.GetBattleVideos(videoBattleId);
            //and now watched videos
            var watchedVideos = _watchedVideoService.GetWatchedVideos(null, user.Id, VideoType.BattleVideo);

            //if the person voting is already a participant in the battle then one of his own videos need not be watched.
            var battleVideosIds = battleVideos.Where(x => x.ParticipantId != user.Id).Select(x => x.Id);
            //only current battle videos
            var watchedVideosIds = watchedVideos.Where(x => battleVideosIds.Contains(x.VideoId)).Select(x => x.VideoId);

            if (watchedVideosIds.Count() != battleVideosIds.Count())
            {
                VerboseReporter.ReportError("You haven't watched all videos", "vote_battle");
                return RespondFailure();
            }

            //first find the video battle
            var videoBattle = _videoBattleService.Get(videoBattleId);
            //is the video available for voting
            if (videoBattle.VideoBattleStatus == BattleStatus.Open)
            {
                //check if the logged in user has voted for this battle
                var videoBattleVotes = _videoBattleVoteService.GetVideoBattleVotes(videoBattleId, user.Id);

                var vote =
                    videoBattleVotes.FirstOrDefault(x => x.UserId == user.Id && x.ParticipantId == participantId);

                if (vote != null)
                {
                    //so there is a vote. is the voting status notvoted then only he'll be able to vote
                    if (vote.VoteStatus == BattleVoteStatus.Voted)
                    //already voted for this participant, not it can't be changed
                    {
                        VerboseReporter.ReportError("You have already voted", "vote_battle");
                        return RespondFailure();
                    }

                    //yep...this vote might be from somebody who has been invited and not voted yet. let's do it.
                    vote.VoteValue = voteValue;
                    vote.VoteStatus = BattleVoteStatus.Voted;
                    _videoBattleVoteService.Update(vote);
                }
                else
                {
                    //user has not voted for this participant however it may be possible that depending on vote type, user can't vote on this battle
                    switch (videoBattle.VideoBattleVoteType)
                    {
                        case BattleVoteType.SelectOneWinner:
                            //if one winner was to be selected, we'll have to check if user has not voted for some other participant
                            if (videoBattleVotes.Count(x => x.VoteStatus == BattleVoteStatus.Voted) > 0)
                            {
                                //yes, user has voted for some other participant so he can't vote for this participant now.
                                VerboseReporter.ReportError("You have already voted", "vote_battle");
                                return RespondFailure();
                            }
                            break;
                        case BattleVoteType.Rating:
                            break;
                        case BattleVoteType.LikeDislike:
                            break;
                    }

                    //is this a paid battle, if it is, then user must pay first before proceeding
                    if (videoBattle.IsVotingPayable)
                    {
                        //check if user has available credits to vote
                        var credits = _creditService.GetUsableCreditsCount(user.Id);

                        if (credits < videoBattle.MinimumVotingCharge)
                        {
                            VerboseReporter.ReportError("You don't have enough credits to vote", "vote_battle");
                            return RespondFailure();
                        }

                        //reduce those many credits
                        var credit = new Credit() {
                            CreatedOnUtc = DateTime.UtcNow,
                            CreditCount = videoBattle.MinimumVotingCharge,
                            CreditExchangeRate = _paymentSettings.CreditExchangeRate,
                            CreditTransactionType = CreditTransactionType.Spent,
                            CreditType = CreditType.Transactional,
                            UserId = user.Id,
                            PaymentTransactionId = 0,
                            CreditContextKey = string.Format(CreditContextKeyNames.BattleVote, videoBattle.Id)
                        };
                        _creditService.Insert(credit);
                    }

                    //user can vote now. let's create a new vote
                    var videoBattleVote = new VideoBattleVote() {
                        ParticipantId = participantId,
                        UserId = user.Id,
                        VideoBattleId = videoBattle.Id,
                        VoteValue = voteValue,
                        VoteStatus = BattleVoteStatus.Voted
                    };
                    _videoBattleVoteService.Insert(videoBattleVote);
                }
                //and add user to the followers list
                _followService.Insert<VideoBattle>(user.Id, videoBattleId);

                return RespondSuccess();
            }
            VerboseReporter.ReportError("Closed for voting", "vote_battle");
            return RespondFailure();
        }