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

namespace NB.Chat;

public static class ChatUnitManageComponentSystem
{
    #region 消息缓存

    /// <summary>
    /// 离线消息，进入待领取队列
    /// </summary>
    /// <param name="self"></param>
    /// <param name="targetId"></param>
    /// <param name="message"></param>
    public static void SaveOfflineMessage(this SocialUnitManageComponent self, long targetId, ChatMessageInfo message)
    {
        // self.NotSendMessage.Add(targetId, message);
    }

    #endregion

    #region 上线下线

    /// <summary>
    /// 玩家上线
    /// </summary>
    /// <param name="self"></param>
    /// <param name="scene"></param>
    /// <param name="accountId"></param>
    /// <param name="gateRouteId"></param>
    public static async FTask<SocialUnit?> Online(this SocialUnitManageComponent self, Scene scene,
        long accountId, 
        long gateRouteId)
    {
        // var accountId = roleSimpleInfo.RoleId;
        if (!self.TryGet(accountId, out var account))
        {
            account = ChatUnitFactory.Create(scene, accountId);
            self.Add(account);
        }

        if (account != null)
        {
            await account.TryComponent<MailComponent>();
            account.GateRouteId = gateRouteId;
            // account.Role = roleSimpleInfo;
        }

        await FTask.CompletedTask;
        return account;
    }

    public static async FTask Offline(this SocialUnitManageComponent self, Scene scene, long accountId, long gateRouteId)
    {
        if (self.TryGet(accountId, out var unit) && unit != null)
        {
            if (unit.GateRouteId == gateRouteId)
            {
                Log.Info("退出当前聊天服==");
                self.Remove(accountId); //如果当前网关和下线的网关一致
            }
        }

        await FTask.CompletedTask;
    }

    #endregion

    #region 获取&移除

    public static void Add(this SocialUnitManageComponent self, SocialUnit account)
    {
        self.Units.Add(account.Id, account);
    }

    public static SocialUnit? Get(this SocialUnitManageComponent self, long accountId)
    {
        return self.Units.GetValueOrDefault(accountId);
    }

    public static bool TryGet(this SocialUnitManageComponent self, long accountId, out SocialUnit? account)
    {
        return self.Units.TryGetValue(accountId, out account);
    }

    public static void Remove(this SocialUnitManageComponent self, long accountId, bool isDispose = true)
    {
        if (!self.Units.Remove(accountId, out var account))
        {
            return;
        }

        if (!isDispose)
        {
            return;
        }

        account.Dispose();
    }

    #endregion

    #region 组件

    /// <summary>
    /// 尝试给增加相关组件
    /// </summary>
    /// <param name="socialUnit"></param>
    /// <typeparam name="T"></typeparam>
    public static async FTask TryComponent<T>(this SocialUnit socialUnit) where T : Entity, new()
    {
        if (socialUnit.GetComponent<T>() == null)
        {
            var mailComponent = await socialUnit.Scene.World.DataBase.Query<T>(socialUnit.Id, true);
            if (mailComponent == null)
            {
                //如果没有邮件组件
                socialUnit.AddComponent<T>();
            }
            else
            {
                socialUnit.AddComponent(mailComponent);
            }
        }
    }

    #endregion
}