using System;
using sodoff.Model;
using sodoff.Schema;

namespace sodoff.Services;

public class ModerationService
{
    public readonly DBContext ctx;

    public ModerationService(DBContext ctx)
    {
        this.ctx = ctx;
    }

    public string AddBanToViking(Viking viking, UserBanType userBanType, DateTime expirationDate = new DateTime())
    {
        // get UTC time stamp of function execution
        DateTime timestamp = DateTime.UtcNow;

        // construct user ban
        UserBan userBan = new UserBan
        {
            UserBanType = userBanType,
            ExpiresOn = expirationDate,
            CreatedAt = timestamp
        };

        // add to viking userban list
        viking.UserBans.Add(userBan);
        ctx.SaveChanges();

        // return success message
        return "Success";
    }
    
    public bool RemoveBanById(int id)
    {
        // find ban
        UserBan? ban = ctx.Bans.FirstOrDefault(e => e.Id == id);

        // remove it
        if (ban != null) { ctx.Bans.Remove(ban); ctx.SaveChanges(); return true; }
        else return false;
    }

    public bool RemoveBansFromVikingByType(Viking viking, UserBanType userBanType)
    {
        // get all bans of type
        List<UserBan> userBans = viking.UserBans.Where(e => e.UserBanType == userBanType).ToList();

        if (userBans.Count == 0) return false;

        // delete all
        foreach(var ban in userBans) { viking.UserBans.Remove(ban); }

        ctx.SaveChanges();

        return true;
    }

    public UserBanType IsVikingBanned(Viking viking)
    {
        // get UTC time stamp of function execution
        DateTime timestamp = DateTime.UtcNow;

        // sort viking ban list by latest first
        List<UserBan> bans = viking.UserBans.OrderByDescending(e => e.CreatedAt).ToList();

        if (bans.Count == 0) return UserBanType.NotBanned; // no bans in list means viking is not banned

        if (bans.First().UserBanType == UserBanType.IndefiniteAccountBan) return UserBanType.IndefiniteAccountBan;
        else if (bans.First().UserBanType == UserBanType.IndefiniteOpenChatBan) return UserBanType.IndefiniteOpenChatBan;

        if (DateTime.Compare(bans.First().ExpiresOn ?? new DateTime(9999, 99, 99), timestamp) > 0) return bans.First().UserBanType;
        else
        {
            // ban should be removed
            RemoveBanById(bans.First().Id);
            return UserBanType.NotBanned;
        }
    }
}
