using Fantasy;
using Fantasy.Entitas;
using Fantasy.Entitas.Interface;

namespace NB.Map;

public class RoomManageComponentAwakeSystem : AwakeSystem<RoomManageComponent>
{
    protected override void Awake(RoomManageComponent self)
    {
        for (int i = 1; i <= 65535; i++)
        {
            self.FreeIds.Enqueue(i, i);
        }
    }
}

public class RoomManageComponentDestroySystem : DestroySystem<RoomManageComponent>
{
    protected override void Destroy(RoomManageComponent self)
    {
        foreach (var (_, room) in self.Rooms)
        {
            room.Dispose();
        }

        self.Rooms.Clear();
    }
}

public static class RoomManageComponentSystem
{
    #region 增删

    public static MapRoom? Create(this RoomManageComponent self, long ownerId)
    {
        var roomId = self.AllocateId();
        if (roomId < 1)
        {
            return null;
        }

        // roomManageComponent.on
        var room = Entity.Create<MapRoom>(self.Scene, true, true);
        room.Owner = ownerId;
        room.RoomId = roomId;
        room.Code = RoomHelper.GenerateCode(self.Scene.SceneConfigId, roomId);
        self.Add(room);

        return room;
    }

    public static void Add(this RoomManageComponent self, MapRoom room)
    {
        self.Rooms[room.RoomId] = room;
    }

    public static bool Remove(this RoomManageComponent self, int roomId)
    {
        if (self.Rooms.TryGetValue(roomId, out var room))
        {
            self.ReleaseId(room.RoomId);
            room.Dispose();
        }

        return true;
    }

    public static void Check(this RoomManageComponent self, int roomId)
    {
        if (self.Rooms.TryGetValue(roomId, out var room))
        {
            if (room.Units.Count < 1)
            {
                Log.Info($"房间没人了，解散房间，id={roomId}");
                // self.Remove(roomId);
            }
        }
    }

    public static MapRoom? Get(this RoomManageComponent self, int roomId)
    {
        return self.Rooms.GetValueOrDefault(roomId);
    }

    // public static MapRoom? Get(this RoomManageComponent self, long roomId)
    // {
    //     return self.Rooms.GetValueOrDefault(roomId);
    // }

    #endregion

    #region 房间Id

    /// <summary>
    /// 分配一个新的房间ID
    /// </summary>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public static int AllocateId(this RoomManageComponent self)
    {
        if (self.FreeIds.Count == 0) return 0;
        int id = self.FreeIds.Dequeue();
        self.InUseID.Add(id);
        return id;
    }

    /// <summary>
    /// 释放房间ID
    /// </summary>
    /// <param name="self"></param>
    /// <param name="id"></param>
    public static void ReleaseId(this RoomManageComponent self, int id)
    {
        if (self.InUseID.Remove(id))
        {
            self.FreeIds.Enqueue(id, id);
        }
    }

    #endregion
}