using Fantasy;
using Fantasy.Async;
using Fantasy.Entitas.Interface;
using Fantasy.Helper;

namespace NB.Chat;

public class MailComponentDestroySystem : DestroySystem<MailComponent>
{
    protected override void Destroy(MailComponent self)
    {
        foreach (var (_, mail) in self.Mails)
        {
            mail.Dispose();
        }

        self.Mails.Clear();
        self.Timer.Clear();
    }
}

public static class MailComponentSystem
{
    public static async FTask Add(this MailComponent self, Mail mail, bool sync)
    {
        mail.CreateTime = TimeHelper.Now;
        mail.ExpireTime = TimeHelper.Now + MailComponent.MaxExpireTime;

        if (self.Mails.Count >= MailComponent.MaxMailCount)
        {
            //删除最老的邮件
            var (_, value) = self.Timer.First();
            foreach (var removeId in value)
            {
                await self.Remove(removeId, sync);
            }
        }

        self.Mails.Add(mail.Id, mail);
        self.Timer.Add(mail.ExpireTime, mail.Id);

        if (sync)
        {
            //同步客户端
            self.Scene.NetworkMessagingComponent.SendInnerRoute(0,new S2C_HaveMail()
            {
                Mail = mail.ToMailInfo(),
            });
        }

        await self.Scene.World.DataBase.Save(self);
        Log.Info($"MailComponent Add id:{self.Id} mailId:{mail.Id} count:{self.Mails.Count}");
    }

    public static async FTask<uint> Remove(this MailComponent self, long mailId, bool sync)
    {
        if (!self.Mails.Remove(mailId, out var mail))
        {
            return 1;
        }

        self.Timer.RemoveValue(mail.ExpireTime, mail.Id);
        mail.Dispose();

        if (sync)
        {
            //同步客户端
            self.Scene.NetworkMessagingComponent.SendInnerRoute(0,new S2C_MailState()
            {
                MailState = (int)MailState.Deleted,
                MailId = mailId,
            });
        }

        await self.Scene.World.DataBase.Save(self);
        Log.Info($"MailComponent Remove id:{self.Id} mailId:{mail.Id} count:{self.Mails.Count}");
        return 0;
    }
}