namespace GmRelay.Shared.Features.Sessions.RescheduleSession;

public enum RescheduleVoteOutcome
{
    Pending,
    Rejected,
    Approved
}

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

public 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: "Один из участников отклонил перенос.",
                CallbackText: "Вы проголосовали против переноса.");
        }

        var everyoneApproved = approvedParticipants == totalParticipants;

        return new RescheduleVoteDecision(
            Outcome: everyoneApproved ? RescheduleVoteOutcome.Approved : RescheduleVoteOutcome.Pending,
            Reason: everyoneApproved
                ? "Все участники согласны."
                : "Голосование продолжается.",
            CallbackText: everyoneApproved
                ? "Вы подтвердили перенос! Все согласны — время обновлено."
                : "Вы подтвердили перенос!",
            ShouldRescheduleSession: everyoneApproved,
            ShouldResetParticipantRsvps: everyoneApproved);
    }
}
