using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MessagePack;

namespace GameMessage.RCGeBang
{
    public struct GeBanGamePack
    {
        /// <summary>
        /// 牌的内存包
        /// </summary>
        public GeBanCardPack CardPack;

        /// <summary>
        /// 跑得快逻辑内存
        /// </summary>
        public GeBanLogicInfo Info;

        /// <summary>
        /// 规则
        /// </summary>
        public GeBanRule Rule;

        /// <summary>
        /// 初始化包
        /// </summary>
        /// <param name="len"></param>
        public void Init(int len)
        {
            CardPack.Init(len);
            Info.Init(len);
        }
    }

    public struct GeBanCardPack
    {
        /// <summary>
        /// 玩家手牌
        /// </summary>
        public PlayCard[] PlayCard;
        public void Init(int len)
        {
            PlayCard = new PlayCard[len];
            for (int i = 0; i < len; i++)
            {
                this.PlayCard[i].Init(17);
            }
        }
    }

    /// <summary>
    /// 隔板网络包
    /// </summary>
    public struct GeBanLogicInfo
    {
        /// <summary>
        /// 游戏流程 1游戏开始 2游戏发牌 3叫挡 4是否弃牌 5打牌 6结算
        /// </summary>
        public byte GameZT;
        /// <summary>
        /// 最大的出牌内容
        /// </summary>
        public PlayOutCard MaxPlayCard;
        /// <summary>
        /// 当前出牌内容
        /// </summary>
        public PlayOutCard ActivePlayCard;

        /// <summary>
        /// 控制权是哪个位置1-3
        /// </summary>
        public byte WhoPlay;

        /// <summary>
        /// 游戏人数
        /// </summary>
        public byte PlayCount;

        /// <summary>
        /// 第一个出牌人
        /// </summary>
        public byte FistPlay;

        public void Init(int len)
        {

        }

    }

    [MessagePackObject]
    public struct TCardInfo : ICardInfoType1
    {
        /// <summary>
        /// 绝对ID
        /// </summary>
        [Key(0)]
        public byte ID { get; set; }

        /// <summary>
        /// 牌面花色 1黑桃 2红桃 3梅花 4方块 5大小王
        /// </summary>
        [Key(1)] public byte Flower;

        /// <summary>
        /// 牌面大小
        /// 1-13 黑桃A-K
        /// 14-26 红桃A-K
        /// 27-39 梅花A-K
        /// 40-52 方块A-K
        /// 53小王 54大王
        /// </summary>
        [Key(2)] public byte Num;

        /// <summary>
        /// 游戏里大小 3-14（3~A） 16是2  98小王 100大王
        /// </summary>
        [Key(3)]
        public byte GameNum { get; set; }

        /// <summary>
        /// 游戏分值
        /// </summary>
        [Key(4)] public byte Score;

        /// <summary>
        /// 当前在谁手里 1-4
        /// </summary>
        [Key(5)] public byte GameOwer;

        /// <summary>
        /// 状态 0打下去了 1没有打下去
        /// </summary>
        [Key(6)] public byte GameState;

        public override string ToString()
        {
            return
                $"ID:{ID} 花色:{(Flower == 1 ? "黑桃" : Flower == 2 ? "红桃" : Flower == 3 ? "梅花" : Flower == 4 ? "方块" : "王")} 大小:{Num}_{GameNum} 分:{Score} 状态:{(GameState == 1 ? "在手上" : "打下去了")}";
        }

        public bool IsActive()
        {
            return ID > 0 && Flower > 0 && GameNum > 0;
        }

        public override bool Equals(object obj)
        {
            if (!(obj is TCardInfo))
            {
                return false;
            }

            TCardInfo other = (TCardInfo)obj;
            return /*ID == other.ID &&*/
                Flower == other.Flower &&
                Num == other.Num &&
                GameNum == other.GameNum &&
                Score == other.Score &&
                GameOwer == other.GameOwer &&
                GameState == other.GameState;
        }

        public override int GetHashCode()
        {
            int hash = 17;
            //hash = hash * 23 + ID.GetHashCode();
            hash = hash * 22 + Flower.GetHashCode();
            hash = hash * 33 + Num.GetHashCode();
            hash = hash * 24 + GameNum.GetHashCode();
            hash = hash * 11 + Score.GetHashCode();
            hash = hash * 12 + GameOwer.GetHashCode();
            hash = hash * 15 + GameState.GetHashCode();
            return hash;
        }
    }
    
    public struct PlayCard
    {
        /// <summary>
        /// 1个玩家的手牌
        /// </summary>
        public TCardInfo[] CardInfos;
        /// <summary>
        /// 初始化玩家牌
        /// </summary>
        public void Init(int len)
        {
            CardInfos = new TCardInfo[len];
        }
    }

    public struct PlayOutCard
    {
        /// <summary>
        /// 牌的位置从1开始
        /// </summary>
        public byte Pos;

        /// <summary>
        /// 牌的类型
        /// </summary>
        public CardType Type;

        /// <summary>
        /// 牌大小-运算大小
        /// 正的510K 数值是21，副的510K是20
        /// </summary>
        public byte GameNum;

        /// <summary>
        /// 出的牌绝对Id集合
        /// </summary>
        public byte[] Ids;

        public void Init(int len)
        {
            Ids = new byte[len];
        }

        public override string ToString()
        {
            return $"pos:{Pos} type:{Type} num:{GameNum} ids:{(Ids == null || Ids.Length <= 0 ? "不要" : string.Join(",", Ids))}";
        }
    }

    public struct GeBanRule
    {
        /// <summary>
        /// 是否有连对 0没有 1是2连对 2是3连对
        /// </summary>
        public int LianDui;

        /// <summary>
        /// 无人叫挡 1无人叫挡流局 2无人叫挡庄家1分打 3无人叫挡3分打 4无人叫挡6分打
        /// </summary>
        public int WuRenJiaoDang;

        /// <summary>
        /// 0双王无限制 1双王加1挡 2双王满挡
        /// </summary>
        public int ShuangWang;

        /// <summary>
        /// 托管的时间 0不托管 1超过1分钟托管 3超过3分钟托管 5超过5分钟托管
        /// </summary>
        public int TuoGuanNum;

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            if (LianDui > 0)
            {
                sb.Append($"{(LianDui==1?"两对及以上为连对": "三对及以上为连对")} ");
            }
            if(WuRenJiaoDang > 0)
            {
                if (WuRenJiaoDang == 1)
                {
                    sb.Append("无人叫挡流局 ");
                }
                else if (WuRenJiaoDang == 2)
                {
                    sb.Append("先叫者为庄,打1分 ");
                }
                else {
                    sb.Append($"无人叫挡打炸,打{WuRenJiaoDang}分 ");
                }
            }
            if (ShuangWang > 0)
            {
                sb.Append($"{(ShuangWang == 1 ? "双王在手须加1挡" : "双王在手满挡")}");
            }
            return sb.ToString();
        }
    }

    public enum CardType
    {
        /// <summary>
        /// 不要
        /// </summary>
        None = 0,
        /// <summary>
        /// 单张
        /// </summary>
        DanZhang = 1,
        /// <summary>
        /// 对子
        /// </summary>
        DuiZi = 2,
        /// <summary>
        /// 连对
        /// </summary>
        LianDui = 3,
        /// <summary>
        /// 顺子
        /// </summary>
        ShunZi = 4,
        /// <summary>
        /// 小炮炸弹
        /// </summary>
        ZhaDan3 = 5,
        /// <summary>
        /// 大炮炸弹
        /// </summary>
        ZhaDan4 = 6,
        /// <summary>
        /// 小王3821:五张牌固定组合，游戏中第三大牌型
        /// </summary>
        ZhaDanXiaoW = 7,
        /// <summary>
        /// 大王3821:五张牌固定组合，游戏中第二大牌型
        /// </summary>
        ZhaDanDaW = 8,
        /// <summary>
        /// 双王:大王小王两张牌固定组台，游戏中最大牌型
        /// </summary>
        ZhaDanShuangW = 9,
    }
}
