summaryrefslogtreecommitdiff
path: root/backend/Elements.Backend/Services/FinishVoteService.cs
blob: 8486036c7cf694e9984b0367c4917b9a65026162 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
using Elements.Data;
using Elements.Data.Models;
using Microsoft.EntityFrameworkCore;

namespace Elements.Backend.Services;

public class FinishVoteService
{
    private readonly ApplicationDbContext _dbContext;
    private readonly ILogger<FinishVoteService> _logger;

    public FinishVoteService(ApplicationDbContext dbContext, ILogger<FinishVoteService> logger)
    {
        _dbContext = dbContext;
        _logger = logger;
    }

    public async Task DoSomethingAsync()
    {
        _logger.LogDebug("Starting finalizing votes");
        List<Suggestion> finishedSuggestions = _dbContext.Suggestions
            .Include(s => s.Votes)
            .Where(s => DateTime.UtcNow > s.VotingEnd)
            .ToList();

        if (finishedSuggestions.Count == 0)
            return;

        bool finished = false;
        while (!finished)
        {
            Suggestion currentSuggestion = finishedSuggestions.First();
            int firstElementId = currentSuggestion.FirstElementId;
            int secondElementId = currentSuggestion.SecondElementId;
            //Get all suggestions with same recipe as current suggestion
            List<Suggestion> sameRecipeSuggestions = finishedSuggestions.Where(s =>
                    (s.FirstElementId == firstElementId && s.SecondElementId == secondElementId) ||
                    (s.FirstElementId == secondElementId && s.SecondElementId == firstElementId))
                .ToList();
            sameRecipeSuggestions.Sort((s1, s2) => s2.Votes.Count.CompareTo(s1.Votes.Count));
            
            Suggestion winner;
            if (sameRecipeSuggestions.Count > 1 &&
                sameRecipeSuggestions[0].Votes.Count == sameRecipeSuggestions[1].Votes.Count)
            {
                List<Suggestion> sameAmountOfVotes = sameRecipeSuggestions
                        .Where(s => s.Votes.Count == sameRecipeSuggestions[0].Votes.Count)
                        .OrderBy(s => s.CreationDate)
                        .ToList();

                winner = sameAmountOfVotes[0];
            }
            else
            {
                winner = sameRecipeSuggestions[0];
            }

            Element newElement = new()
            {
                CreationDate = winner.CreationDate,
                UserId = winner.UserId,
                Name = winner.Name,
                State = ElementState.HasColor,
                IconPng = winner.Icon
            };
            await _dbContext.Elements.AddAsync(newElement);
            await _dbContext.SaveChangesAsync();
            
            await _dbContext.Recipes.AddAsync(new Recipe
            {
                FirstElementId = winner.FirstElementId,
                SecondElementId = winner.SecondElementId,
                ResultElementId = newElement.Id,
            });

            //Delete votes
            foreach (Vote vote in sameRecipeSuggestions.SelectMany(suggestion => suggestion.Votes))
                _dbContext.Entry(vote).State = EntityState.Deleted;

            //Delete suggestions
            foreach (Suggestion suggestion in sameRecipeSuggestions)
                _dbContext.Entry(suggestion).State = EntityState.Deleted;
            
            await _dbContext.SaveChangesAsync();
            
            finishedSuggestions = finishedSuggestions
                .Where(s => !(s.FirstElementId == firstElementId && s.SecondElementId == secondElementId) &&
                            !(s.FirstElementId == secondElementId && s.SecondElementId == firstElementId))
                .ToList();
            
            if (finishedSuggestions.Count == 0)
                finished = true;
        }
    }
}