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

namespace NB.Chat;

public class MailConversationDeserializeSystem : DeserializeSystem<MailConversation>
{
    protected override void Deserialize(MailConversation self)
    {
        self.Key = $"{self.FirstId}-{self.SecondId}";
    }
}

public class MailConversationDestroySystem : DestroySystem<MailConversation>
{
    protected override void Destroy(MailConversation self)
    {
        foreach (var mail in self.Mails)
        {
            mail.Dispose();
        }

        self.Mails.Clear();
        self.FirstId = 0;
        self.SecondId = 0;
        self.Key = string.Empty;
    }
}

public static class MailConversationSystem
{
    public static async FTask Add(this MailConversation self, Mail mail)
    {
        self.Mails.Add(mail);
        if (self.Mails.Count > AppConfig.MaxConversationCount)
        {
            self.Mails.RemoveAt(0);
        }

        if (mail.Items != null && mail.Items.Count > 0)
        {
            //有附件需要立马保存
            await self.Save(true);
        }
        else
        {
            await self.Save(false);
        }
    }
    
    public static async FTask Save(this MailConversation self, bool forceSave = true)
    {
        // self.NeedSave = true;
        // self.NeedSaveTime = TimeHelper.Now + AppConfig.PlayerDataAutoSaveTime;
        if (forceSave)
        {
            self.UpdateTime = TimeHelper.Now;
            await self.Scene.World.DataBase.Save(self);
        }
        else
        {
            self.NeedSave = true;
            self.NeedSaveTime = TimeHelper.Now + AppConfig.ChatDataAutoSaveTime;
        }
    }

    /// <summary>
    /// 是否可以发送邮件
    /// </summary>
    /// <param name="self"></param>
    /// <param name="sendId"></param>
    /// <returns></returns>
    public static bool CanSend(this MailConversation self, long sendId)
    {
        if (self.Mails.Count < 1) return true;
        foreach (var mail in self.Mails)
        {
            if (mail.Sender != sendId)
            {
                return true;
            }
        }

        return false;
    }

    #region 转换

    public static async FTask<List<ConversationInfo>> ToInfo(this List<MailConversation> self, Scene scene, long selfId)
    {
        List<ConversationInfo> ret = new List<ConversationInfo>();
        HashSet<long> ids = new HashSet<long>();
        foreach (var conversation in self)
        {
            if (conversation.RemoveId.Contains(selfId)) continue;
            ids.Add(conversation.FirstId);
            ids.Add(conversation.SecondId);
        }

        ids.Remove(selfId);

        var infos = await CacheHandler.GetPlayerBasicCacheInfos(scene, ids.ToList());
        foreach (var conversation in self)
        {
            if (conversation.RemoveId.Contains(selfId)) continue;
            var item = new ConversationInfo();
            item.List = conversation.Mails.ToMailInfo();
            var otherId = conversation.FirstId == selfId ? conversation.SecondId : conversation.FirstId;
            var info = infos.Find(t => t.RoleId == otherId);
            if (info != null)
            {
                item.RoleInfo = info;
            }

            ret.Add(item);
        }


        return ret;
    }

    #endregion
}