namespace GmRelay.Bot.Features.Sessions.RescheduleSession;

internal enum RescheduleVoteOutcome
{
    Pending,
    Rejected,
    Approved
}

internal sealed record RescheduleVoteDecision(
    RescheduleVoteOutcome Outcome,
    string Reason,
    Guid? SelectedOptionId = null,
    string CallbackText = "",
    bool ShouldRescheduleSession = false,
    bool ShouldResetParticipantRsvps = false);

internal static class RescheduleVoteRules
{
    public static RescheduleVoteDecision SelectWinner(IReadOnlyList<RescheduleOptionVoteCount> voteCounts)
    {
        var maxVotes = voteCounts.Count == 0 ? 0 : voteCounts.Max(x => x.VoteCount);
        if (maxVotes == 0)
        {
            return new RescheduleVoteDecision(
                RescheduleVoteOutcome.Rejected,
                "Никто не проголосовал до дедлайна, перенос не применяется.");
        }

        var winners = voteCounts.Where(x => x.VoteCount == maxVotes).ToList();
        if (winners.Count > 1)
        {
            return new RescheduleVoteDecision(
                RescheduleVoteOutcome.Rejected,
                "Голоса разделились поровну, перенос не применяется.");
        }

        return new RescheduleVoteDecision(
            RescheduleVoteOutcome.Approved,
            "Победил вариант с большинством голосов.",
            winners[0].OptionId,
            ShouldRescheduleSession: true,
            ShouldResetParticipantRsvps: true);
    }

    public static RescheduleVoteDecision Evaluate(string vote, int totalParticipants, int approvedParticipants)
    {
        if (string.Equals(vote, "no", StringComparison.OrdinalIgnoreCase))
        {
            return new RescheduleVoteDecision(
                Outcome: RescheduleVoteOutcome.Rejected,
                Reason: "\u041e\u0434\u0438\u043d \u0438\u0437 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u043e\u0442\u043a\u043b\u043e\u043d\u0438\u043b \u043f\u0435\u0440\u0435\u043d\u043e\u0441.",
                CallbackText: "\u0412\u044b \u043f\u0440\u043e\u0433\u043e\u043b\u043e\u0441\u043e\u0432\u0430\u043b\u0438 \u043f\u0440\u043e\u0442\u0438\u0432 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430.");
        }

        var everyoneApproved = approvedParticipants == totalParticipants;

        return new RescheduleVoteDecision(
            Outcome: everyoneApproved ? RescheduleVoteOutcome.Approved : RescheduleVoteOutcome.Pending,
            Reason: everyoneApproved
                ? "\u0412\u0441\u0435 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u044b."
                : "\u0413\u043e\u043b\u043e\u0441\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442\u0441\u044f.",
            CallbackText: everyoneApproved
                ? "\u0412\u044b \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441! \u0412\u0441\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u044b \u2014 \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043e."
                : "\u0412\u044b \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441!",
            ShouldRescheduleSession: everyoneApproved,
            ShouldResetParticipantRsvps: everyoneApproved);
    }
}
