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

namespace GameMessage.YGLiuFu
{
    [MessagePackObject]
    public struct PlayOutCard : IPlayOutCardType1
    {
        /// <summary>
        /// 牌的位置从1开始
        /// </summary>
        [Key(0)]
        public byte Pos { get; set; }

        /// <summary>
        /// 牌的类型
        /// </summary>
        [Key(1)]
        public CardType1 Type { get; set; }

        /// <summary>
        /// 牌大小-运算大小
        /// 正的510K 数值是21，副的510K是20
        /// </summary>
        [Key(2)]
        public byte GameNum { get; set; }

        /// <summary>
        /// 出的牌绝对Id集合
        /// </summary>
        [Key(3)]
        public byte[] Ids { get; set; }

        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 ? "不要" :($"len:{Ids.Length}--{string.Join(",", Ids)}"))}";
        }
    }
    
    /// <summary>
    /// 一手牌
    /// </summary>
    [MessagePackObject]
    public struct OneHandCard
    {
        /// <summary>
        /// 大小
        /// </summary>
        [Key(0)]
        public byte GameNum;

        /// <summary>
        /// 这一手牌的牌Id集合
        /// </summary>
        [Key(1)]
        public List<byte> Ids;

        public override string ToString()
        {
            return $"num:{GameNum} len:{(Ids != null ? Ids.Count : 0)}";
        }
    }

    /// <summary>
    /// 问答包
    /// </summary>
    [MessagePackObject]
    public class WenDaPack
    {
        /// <summary>
        /// 哪个位置发送的,位置从1开始
        /// </summary>
        [Key(0)]
        public int pos;

        /// <summary>
        /// 发送类型 1问 2答 3商量亮牌
        /// </summary>
        [Key(1)]
        public byte type;

        /// <summary>
        /// 问 答内容的下标 ，需要亮牌的玩家
        /// </summary>
        [Key(2)]
        public int idx;

        /// <summary>
        /// 是否亮牌 0无效值 1亮 2不亮
        /// </summary>
        [Key(3)]
        public byte IsLiang;

        public override string ToString()
        {
            return $"pos:{pos} type:{type} idx:{idx} isLiang:{IsLiang}";
        }
    }

    /// <summary>
    /// 余干六副网络包
    /// </summary>
    [MessagePackObject]
    public struct YuGanLiuFuPack
    {
        /// <summary>
        /// 包逻辑内容
        /// </summary>
        [Key(0)]
        public YuGanLiuFuLogic Info;
        /// <summary>
        /// 游戏规则
        /// </summary>
        [Key(1)]
        public YuGanLiuFuRule Rule;
        /// <summary>
        /// 玩家手牌 --玩家手牌可以拆，删除的时候注意这个逻辑需要判断长度是不是想等
        /// </summary>
        [Key(2)]
        public List<OneHandCard>[] CardPack;

        public void Init()
        {
            CardPack = new List<OneHandCard>[4];
            for (int i = 0; i < CardPack.Length; i++)
            {
                CardPack[i] = new List<OneHandCard>();
            }
            Info.Init();
        }
    }

    [MessagePackObject]
    public struct YuGanLiuFuLogic
    {
        /// <summary>
        /// 游戏流程 1游戏开始 2游戏发牌 3游戏打牌 4游戏结束 5比奖流程
        /// </summary>
        [Key(0)]
        public byte GameZT;

        /// <summary>
        /// 本局总分
        /// </summary>
        [Key(1)]
        public int ScoreSum;

        /// <summary>
        /// 控制权是哪个位置1-4
        /// </summary>
        [Key(2)]
        public byte WhoPlay;

        /// <summary>
        /// 第一个出牌位置，庄
        /// </summary>
        [Key(3)]
        public byte FirstPlay;

        /// <summary>
        /// 最大的出牌内容
        /// </summary>
        [Key(4)]
        public PlayOutCard MaxPlayCard;

        /// <summary>
        /// 当前出牌内容
        /// </summary>
        [Key(5)]
        public PlayOutCard ActivePlayCard;

        /// <summary>
        /// 一轮的分数
        /// </summary>
        [Key(6)]
        public ushort LunScore;

        /// <summary>
        /// 记录打完牌的位置 下标从0开始记录头游位置 里面的位置是从1开始的 
        /// </summary>
        [Key(7)]
        public byte[] OverPos;

        /// <summary>
        /// 存储队友位置 0和1是一队 2和3是一队
        /// </summary>
        [Key(8)]
        public byte[] DuiYou;

        /// <summary>
        /// 玩家自己有几个奖
        /// </summary>
        [Key(9)]
        public byte[] JiangNum;

        /// <summary>
        /// 玩家最后自己奖得分
        /// </summary>
        [Key(10)]
        public short[] JiangScore;

        /// <summary>
        /// 玩家捡分
        /// </summary>
        [Key(11)]
        public short[] JianScore;

        /// <summary>
        /// 玩家输赢得分
        /// </summary>
        [Key(12)]
        public short[] PlayScore;

        /// <summary>
        /// 冲关分
        /// </summary>
        [Key(13)]
        public short[] ChongGuanSocre;

        /// <summary>
        /// 玩家剩余牌
        /// </summary>
        [Key(14)]
        public byte[] ShengYuCard;

        /// <summary>
        /// 玩家托管标识 0没有托管 1托管1次 2托管2次，托管中
        /// </summary>
        [Key(15)]
        public byte[] PlayTuoGauan;

        /// <summary>
        /// 出完牌的人数
        /// </summary>
        [Key(16)]
        public byte OverCount;

        /// <summary>
        /// 轮人数
        /// </summary>
        [Key(17)]
        public byte LunPlayCount;

        /// <summary>
        /// 存储2个亮牌玩家的位置
        /// </summary>
        [Key(18)]
        public byte[] LiangPos;

        /// <summary>
        /// 存储4个玩家的奖牌
        /// </summary>
        [Key(19)]
        public List<OneHandCard>[] JiangCards;

        /// <summary>
        /// 每轮亮奖的牌
        /// </summary>
        [Key(20)]
        public List<byte>[] LunJiangCards;

        public void Init()
        {
            OverPos = new byte[4];
            JiangNum = new byte[4];
            JianScore = new short[4];
            ShengYuCard = new byte[4];
            DuiYou = new byte[4];
            PlayTuoGauan = new byte[4];
            ChongGuanSocre = new short[4];
            JiangScore = new short[4];
            PlayScore = new short[4];
            LiangPos = new byte[2];
            LunPlayCount = 0;
            MaxPlayCard = new PlayOutCard();
            ActivePlayCard = new PlayOutCard();
            LunScore = 0;
            ScoreSum = 0;
            OverCount = 0;
            FirstPlay = 0;
            JiangCards = new List<OneHandCard>[4];
        }
    }

    /// <summary>
    /// 余干六副规则
    /// </summary>
    [MessagePackObject]
    public struct YuGanLiuFuRule
    {
        /// <summary>
        /// 0无效值 1六副牌玩法 2八副牌玩法
        /// --发牌，算奖分6副牌8个头算奖，8副牌10个头算奖
        /// </summary>
        [Key(0)]
        public byte PlayType;

        /// <summary>
        /// 底分 0无效值 具体数值就是具体的底分，这个底分等同于牌局结束的输赢分
        /// 一般是5分 或者10分
        /// </summary>
        [Key(1)]
        public byte DiFen;

        /// <summary>
        /// 封顶 true一关封顶 false不封顶
        /// </summary>
        [Key(2)]
        public bool FengDing;

        /// <summary>
        /// true奖算两家  false奖算三家
        /// </summary>
        [Key(3)]
        public bool JiangTwo;

        /// <summary>
        /// 0无效值 8-8个奖开始算冲关 10-10个奖开始算冲关
        /// </summary>
        [Key(4)]
        public byte ChongGuanNum;

        /// <summary>
        /// 0无效值 8：8-2是一种算法 3-7是一种算法  10：10-2是一种算法，3-9是一种算法
        /// </summary>
        [Key(5)]
        public byte JiangNum;

        /// <summary>
        /// true固定对家 false大小王对家
        /// </summary>
        [Key(6)]
        public bool IsFixed;

        /// <summary>
        /// true炸弹玩法 false普通玩法
        /// </summary>
        [Key(7)]
        public bool IsBomb;

        /// <summary>
        /// true解散算奖 false解散不算奖
        /// </summary>
        [Key(8)]
        public bool IsDisband;

        /// <summary>
        /// true显示2手 false不显示2手  --显示两手就是玩家手牌数小于等于15张牌必显
        /// </summary>
        [Key(9)]
        public bool IsShowTwo;

        /// <summary>
        /// 0无效值 具体数值是具体的托管时间 单位是分
        /// </summary>
        [Key(10)]
        public byte TuoGuanNum;
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(PlayType == 1 ? "六副牌 " : "八副牌 ");
            sb.Append($"底分{DiFen} ");
            sb.Append(FengDing ? "一关封顶 " : "冲关不封顶 ");
            sb.Append(JiangTwo ? "奖算两家 " : "奖算三家 ");
            sb.Append($"{ChongGuanNum}开始算冲关 ");
            sb.Append($"{JiangNum}开始算奖 ");
            sb.Append(IsBomb ? "炸弹玩法 " : "普通玩法 ");
            sb.Append(IsDisband ? "解散算奖 " : "解散不算奖 ");
            sb.Append(IsShowTwo ? "显示2手 " : "不显示2手 ");
            if (TuoGuanNum > 0) sb.Append($"托管时间{TuoGuanNum}分钟 ");
            return sb.ToString();
        }
    }

    
}