using System.Collections.Generic;
using System.Linq;

namespace ET.Server
{
    /// <summary>
    /// Proto工具类
    /// </summary>
    public static class ProtoHelper
    {
        /// <summary>
        /// 玩家信息转proto
        /// </summary>
        /// <param name="player"></param>
        /// <returns></returns>
        public static PlayerInfo PlayerToProto(Player player)
        {
            return new PlayerInfo()
            {
                id = player.Id,
                name = player.Name,
                sex = player.Sex,
                exp = player.Exp,
                level = player.Level,
                vip = 0
            };
        }

        /// <summary>
        /// 房间信息转proto
        /// </summary>
        /// <param name="room"></param>
        /// <param name="player"></param>
        /// <param name="opPlayer">当前操作玩家</param>
        /// <returns></returns>
        public static RoomInfo RoomToProto(Room room, Player player, Player opPlayer)
        {
            RoomInfo info = new ();
            info.RoomId = room.RoomId;
            info.Type = room.Type;
            info.OwnerId = room.OwnerId;
            HGHHComponent hghhComponent = room.GetComponent<HGHHComponent>();
            if (hghhComponent != null)
            {
                info.State = hghhComponent.State;
                info.Time = hghhComponent.Time;
                info.Rand1 = hghhComponent.Rand[0];
                info.Rand2 = hghhComponent.Rand[1];
                info.CardNum = hghhComponent.CardList.Count;
                info.OpId = opPlayer?.Id ?? -1;
                info.OpPos = opPlayer?.Pos ?? -1;
                info.CurDisCard = hghhComponent.DisCard;
            }
            // 本人信息
            info.MyInfo = PlayerInfoToProto(room, player, true);
            // 其他玩家信息
            info.OtherInfo = new List<PlayerInfo>();
            foreach (Player p in room.GetAllPlayers().Values.Where(p => p != null && p.Id != player.Id))
            {
                info.OtherInfo.Add(PlayerInfoToProto(room, p, false));
            }
            return info;
        }

        /// <summary>
        /// 房间玩家信息转proto
        /// </summary>
        /// <param name="room">玩家</param>
        /// <param name="player">玩家</param>
        /// <param name="flag">是否本人</param>
        /// <returns></returns>
        private static PlayerInfo PlayerInfoToProto(Room room, Player player, bool flag)
        {
            PlayerInfo info = new ();
            info.id = player.Id;
            info.name = player.Name;
            info.sex = player.Sex;
            info.exp = player.Exp;
            info.level = player.Level;
            info.vip = 0;
            info.pos = player.Pos;
            info.state = player.State;
            info.isAuto = player.IsAuto;
            info.cardInfo = new CardInfo();
            if (flag)
            {
                info.cardInfo.RemainCards = new List<int>(player.RemainCards);
                
                HGHHComponent hghhComponent = room.GetComponent<HGHHComponent>();
                if (hghhComponent != null)
                {
                    info.cardInfo.DrawCard = hghhComponent.DrawCard;
                }
                
                info.cardInfo.Acts = player.Act.ToList();
                
                info.cardInfo.ActInfo = new List<ActInfo>();
                if (player.ActInfo is { Count: > 0 })
                {
                    foreach (Struct.Kezi kezi in player.ActInfo)
                    {
                        info.cardInfo.ActInfo.Add(new ActInfo(){Card = kezi.Card, Type = kezi.Type, PlayerId = kezi.PlayerId});
                    }
                }
            }
            
            info.cardInfo.RemainCardsNum = player.RemainCards.Length;
            
            info.cardInfo.DisCards = new List<int>(player.DisCards);
            
            info.cardInfo.UsedInfo = new List<ActInfo>();
            if (player.KeZi is {Count: > 0})
            {
                foreach (Struct.Kezi kezi in player.KeZi.Where(kezi => kezi != null))
                {
                    info.cardInfo.UsedInfo.Add(new ActInfo(){Card = kezi.Card, Type = kezi.Type, PlayerId = kezi.PlayerId});
                }
            }
            
            return info;
        }
    }
}