//**********************************************//
//作者:#何健#
//日期:#2016.10.12#
//简述:#物品数据结构#
//*********************************************//
using Thousandto.Code.Global;
using Thousandto.Code.Center;
using Thousandto.Cfg.Data;
using MSG_backpack;
using UnityEngine;
using MSG_HolyEquip;
using System;
using Thousandto.Plugins.Common;
using XLua;

namespace Thousandto.Code.Logic
{
    public class ItemBase : UIItemShow
    {
        #region Member
        private int _cfgId;          //物品表ID
        private int _index;          //背包位置
        private long _count;          //堆叠数
        private ulong _dbid;           //服务器数据库ID
        private int _lostTime;       //过期时间
        private bool _isBind;         //是否绑定
        private ContainerType _containerType;  //所在容器
        private int _itemType;       //物品类型
        private bool _isClear;        //是否正在清理
        private float _cdTime;         //CD冷却
        #endregion

        #region 属性获取公有接口
        /// <summary>
        /// 物品表ID
        /// </summary>
        public int CfgID
        {
            get
            {
                return _cfgId;
            }
            set
            {
                if (value < 0)
                {
                    return;
                }
                _cfgId = value;
            }
        }

        /// <summary>
        /// 服务器数据库ID
        /// </summary>
        public ulong DBID
        {
            get { return _dbid; }
            set { _dbid = value; }
        }

        /// <summary>
        /// 背包位置
        /// </summary>
        public int Index
        {
            get
            {
                return _index;
            }
            set
            {
                if (value < 0)
                {
                    return;
                }
                _index = value;
            }
        }

        /// <summary>
        /// 堆叠数
        /// </summary>
        public long Count
        {
            get
            {
                return _count;
            }
            set
            {
                if (value < 0)
                {
                    //TODO 写日志
                    return;
                }
                _count = value;
            }
        }

        /// <summary>
        /// 过期时间
        /// </summary>
        public int LostTime
        {
            get
            {
                return _lostTime;
            }
            set
            {
                _lostTime = value;
            }
        }

        /// <summary>
        /// 是否绑定
        /// </summary>
        public bool IsBind
        {
            get
            {
                return _isBind && Type != ItemType.Money;
            }
            set
            {
                _isBind = value;
            }
        }

        public float CDTime
        {
            get { return _cdTime; }
            set { _cdTime = value; }
        }

        /// <summary>
        /// 所在容器
        /// </summary>
        public ContainerType ContainerType
        {
            get
            {
                return _containerType;
            }
            set
            {
                _containerType = value;
            }
        }

        /// <summary>
        /// 物品类型
        /// </summary>
        public int Type
        {
            get
            {
                return GetItemType();
            }
            set { _itemType = value; }
        }

        public bool IsClear { get; set; }

        public bool IsNew { get; set; }

        #endregion

        #region 私有接口
        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        public virtual bool Initialization()
        {
            _isClear = false;
            _itemType = GetItemTypeByModelID(CfgID);
            return true;
        }

        /// <summary>
        /// 反初始化
        /// </summary>
        /// <returns></returns>
        public virtual void UnInitialization()
        {
        }
        #endregion

        #region 公有接口       
        public ItemBase(int cfgId, ulong dbid = 0)
        {
            _cfgId = cfgId;
            _dbid = dbid;
            Initialization();
        }

        public ItemBase(ItemInfo info)
        {
            CfgID = info.itemModelId;
            DBID = info.itemId;
            Count = info.num;
            Index = info.gridId;
            IsBind = info.isbind;
            LostTime = info.lostTime;
            CDTime = info.cdTime;
            if (LostTime < 0)
            {
                LostTime = 0;
            }
            ContainerType = ContainerType.UnDefine;
            Initialization();
        }

        public ItemBase(HolyEquipItem info)
        {
            CfgID = info.itemId;
            DBID = info.uid;
            Count = 1;
            Index = 0;
            IsBind = info.isBind;
            LostTime = 0;
            CDTime = 0;
            if (LostTime < 0)
            {
                LostTime = 0;
            }
            ContainerType = ContainerType.UnDefine;
            Initialization();
        }

        public ItemBase(ItemBase info)
        {
            if (null != info)
            {
                CfgID = info.CfgID;
                DBID = info.DBID;
                Count = info.Count;
                Index = info.Index;
                IsBind = info.IsBind;
                LostTime = info.LostTime;
                CDTime = info.CDTime;
                ContainerType = info.ContainerType;
                Initialization();
            }
        }

        public ItemBase(LuaTable msgTable)
        {
            var msg = new ItemInfo();
            if (!msgTable.TryGet("itemId", out msg.itemId))//物品唯一ID值
                return;
            if (!msgTable.TryGet("itemModelId", out msg.itemModelId))//物品模板ID值
                return;
            if (!msgTable.TryGet("num", out msg.num))//数量
                return;
            msgTable.TryGet("gridId", out msg.gridId);//所在格子编号
            msgTable.TryGet("isbind", out msg.isbind);//是否绑定 1是0否
            msgTable.TryGet("lostTime", out msg.lostTime);//过期时间
            msgTable.TryGet("cdTime", out msg.cdTime);//物品CD
            msgTable.TryGet("suitId", out msg.suitId);//套装Id
            msgTable.TryGet("strengLv", out msg.strengLv);//强化等级
            CfgID = msg.itemModelId;
            DBID = msg.itemId;
            Count = msg.num;
            Index = msg.gridId;
            IsBind = msg.isbind;
            LostTime = msg.lostTime;
            CDTime = msg.cdTime;
            if (LostTime < 0)
            {
                LostTime = 0;
            }
            ContainerType = ContainerType.UnDefine;
            Initialization();
        }

        /// <summary>
        /// 判断一个物品是否可用,但是除开等级,职业,性别,和时间CD判断,
        /// 如需要上述判断需要自己自行调用
        /// </summary>
        /// <param name="useType"></param>
        /// <returns></returns>
        public virtual bool IsCanUse(int useType = ItemOpertion.Use)
        {
            return true;
        }

        public virtual bool CheckClass()
        {
            return false;
        }

        /// <summary>
        /// 检测物品是否满足等级
        /// </summary>
        /// <param name="level">用于检测的等级</param>
        /// <returns></returns>
        public virtual bool CheckLevel(int level)
        {
            return true;
        }

        /// <summary>
        /// 检测物品是否满足特定职业
        /// </summary>
        /// <param name="career">检测的职业</param>
        /// <returns></returns>
        public virtual bool CheckCareer(int career)
        {
            return GameCenter.GameSceneSystem.GetLocalPlayer().Occ == career;
        }

        /// <summary>
        /// 检测是否过期
        /// </summary>
        /// <returns></returns>
        public virtual bool isTimeOut()
        {
            if (LostTime > 0)
                return LostTime < GameCenter.HeartSystem.ServerTime;
            return false;
        }

        /// <summary>
        /// 检测是否满足性别
        /// </summary>
        /// <param name="sex">检测的性别</param>
        /// <returns></returns>
        public virtual bool CheackOcc(int sex)
        {
            return true;
        }

        //检测是否比身上穿的战斗力高
        public virtual bool CheckBetterThanDress()
        {
            return false;
        }
        //检测是否可以装备
        public virtual bool CheckCanEquip()
        {
            return false;
        }
        //检测是否可以上架
        public virtual bool CanAuction()
        {
            return false;
        }

        /// <summary>
        /// 检测是否需要二次确认,这里的二次确认就是会弹出一个确认框
        /// </summary>
        /// <param name="useType">操作类型</param>
        /// <returns></returns>
        public virtual bool IsNeedSecond(int useType = ItemOpertion.Use)
        {
            return false;
        }

        /// <summary>
        ///是否可以批量使用
        /// </summary>
        /// <returns></returns>
        public virtual bool IsUsedInBatches()
        {
            return false;
        }

        //是否有效
        public virtual bool IsValid()
        {
            return false;
        }

        public virtual int GetItemType()
        {
            return _itemType;
        }

        //使用物品
        public virtual void UseItem()
        {

        }

        //获取和已穿戴装备的战斗力差
        public virtual int GetDressPowerDiff()
        {
            return 0;
        }
        #endregion

        #region static Methods
        static public string GetQualityString(int quality)
        {
            string ret = "";
            switch (quality)
            {
                case QualityCode.White:
                    ret = Thousandto.Cfg.Data.DeclareMessageString.Get(Thousandto.Cfg.Data.DeclareMessageString.C_QUALITY_1);
                    break;
                case QualityCode.Green:
                    ret = Thousandto.Cfg.Data.DeclareMessageString.Get(Thousandto.Cfg.Data.DeclareMessageString.C_QUALITY_2);
                    break;
                case QualityCode.Blue:
                    ret = Thousandto.Cfg.Data.DeclareMessageString.Get(Thousandto.Cfg.Data.DeclareMessageString.C_QUALITY_3);
                    break;
                case QualityCode.Violet:
                    ret = Thousandto.Cfg.Data.DeclareMessageString.Get(Thousandto.Cfg.Data.DeclareMessageString.C_QUALITY_4);
                    break;
                case QualityCode.Orange:
                    ret = Thousandto.Cfg.Data.DeclareMessageString.Get(Thousandto.Cfg.Data.DeclareMessageString.C_QUALITY_5);
                    break;
                case QualityCode.Golden:
                    ret = Thousandto.Cfg.Data.DeclareMessageString.Get(Thousandto.Cfg.Data.DeclareMessageString.C_QUALITY_6);
                    break;
                case QualityCode.Red:
                    ret = Thousandto.Cfg.Data.DeclareMessageString.Get(Thousandto.Cfg.Data.DeclareMessageString.C_QUALITY_7);
                    break;
                case QualityCode.Pink:
                    ret = Thousandto.Cfg.Data.DeclareMessageString.Get(Thousandto.Cfg.Data.DeclareMessageString.C_QUALITY_8);
                    break;
            }
            return ret;
        }

        /// <summary>
        /// 获取物品品质color
        /// </summary>
        /// <param name="quality">物品品质</param>
        /// <returns></returns>
        static public Color GetQualityColor(int quality)
        {
            Color retColor;
            switch (quality)
            {
                case QualityCode.White:
                    retColor = Color.white;
                    break;
                case QualityCode.Green:
                    retColor = new Color(31 / 255.0f, 127 / 255.0f, 26 / 255.0f);
                    break;
                case QualityCode.Blue:
                    retColor = new Color(46 / 255.0f, 115 / 255.0f, 255 / 255.0f);
                    break;
                case QualityCode.Violet:
                    retColor = new Color(165 / 255.0f, 14 / 255.0f, 243 / 255.0f);
                    break;
                case QualityCode.Orange:
                    retColor = new Color(246 / 255.0f, 133 / 255.0f, 0 / 255.0f);
                    break;
                case QualityCode.Golden:
                    retColor = new Color(255 / 255.0f, 145 / 255.0f, 16 / 255.0f);
                    break;
                case QualityCode.Red:
                    retColor = new Color(255 / 255.0f, 42 / 255.0f, 42 / 255.0f);
                    break;
                case QualityCode.Pink:
                    retColor = new Color(254 / 255.0f, 60 / 255.0f, 179 / 255.0f);
                    break;
                case QualityCode.DarkGolden:
                    retColor = new Color(166 / 255.0f, 105 / 255.0f, 0 / 255.0f);
                    break;
                case QualityCode.Colorful:
                    retColor = Color.white;
                    break;
                default:
                    retColor = Color.black;
                    break;
            }
            return retColor;
        }

        /// <summary>
        /// 获取物品品质RGB值
        /// </summary>
        /// <param name="quality">物品品质</param>
        /// <returns></returns>
        static public string GetQualityStrColor(int quality)
        {
            switch (quality)
            {
                case QualityCode.White:
                    return "FFFFFF";
                case QualityCode.Green:
                    return "1f7f1a";
                case QualityCode.Blue:
                    return "2e73ff";
                case QualityCode.Violet:
                    return "a50ef3";
                case QualityCode.Orange:
                    return "f68500";
                case QualityCode.Golden:
                    return "ff9110";
                case QualityCode.Red:
                    return "ff2a2a";
                case QualityCode.Pink:
                    return "fe3cb3";
                case QualityCode.DarkGolden:
                    return "a66900";
                case QualityCode.Colorful:
                    return "FFFFFF";
                default:
                    return "FFFFFF";
            }
        }

        /// <summary>
        /// 根据品质获取品质框图片名
        /// </summary>
        /// <param name="quality"></param>
        /// <returns></returns>
        static public string GetQualitySpriteName(int quality)
        {
            switch (quality)
            {
                case QualityCode.Green:
                    return "bag_back_green";
                case QualityCode.Blue:
                    return "n_pinzhikuang_1";
                case QualityCode.Violet:
                    return "n_pinzhikuang_2";
                case QualityCode.Orange:
                    return "n_pinzhikuang_3";
                case QualityCode.Golden:
                    return "n_pinzhikuang_3";
                case QualityCode.Red:
                    return "n_pinzhikuang_4";
                case QualityCode.Pink:
                    return "n_pinzhikuang_5";
                case QualityCode.DarkGolden:
                    return "n_pinzhikuang_6";
                case QualityCode.Colorful:
                    return "n_pinzhikuang_7";
                default:
                    return "";
            }
        }

        //TIPS上背景图需要根据物品品质修改
        public static Color GetQualityBackColor(int quality)
        {
            Color retColor;
            switch (quality)
            {
                case QualityCode.White:
                    retColor = Color.white;
                    break;
                case QualityCode.Green:
                    retColor = new Color(57 / 255.0f, 160 / 255.0f, 161 / 255.0f);
                    break;
                case QualityCode.Blue:
                    retColor = new Color(69 / 255.0f, 94 / 255.0f, 173 / 255.0f);
                    break;
                case QualityCode.Violet:
                    retColor = new Color(120 / 255.0f, 58 / 255.0f, 169 / 255.0f);
                    break;
                case QualityCode.Orange:
                    retColor = new Color(193 / 255.0f, 92 / 255.0f, 18 / 255.0f);
                    break;
                case QualityCode.Golden:
                    retColor = new Color(197 / 255.0f, 151 / 255.0f, 32 / 255.0f);
                    break;
                case QualityCode.Red:
                    retColor = new Color(178 / 255.0f, 21 / 255.0f, 38 / 255.0f);
                    break;
                case QualityCode.Pink:
                    retColor = new Color(231 / 255.0f, 27 / 255.0f, 121 / 255.0f);
                    break;
                case QualityCode.DarkGolden:
                    retColor = new Color(139 / 255.0f, 65 / 255.0f, 31 / 255.0f);
                    break;
                case QualityCode.Colorful:
                    retColor = Color.white;
                    break;
                default:
                    retColor = Color.black;
                    break;
            }
            return retColor;
        }

        //物品名称
        public static string GetItemName(int id)
        {
            var item = DeclareItem.Get(id);
            if (item != null)
            {
                int length = item.Name.LastIndexOf("_");
                if (length == -1)
                {
                    return item.Name;
                }
                else
                {
                    return item.Name.Substring(0, length + 1);
                }
            }

            var equip = DeclareEquip.Get(id);
            if (equip != null)
            {
                int length = equip.Name.LastIndexOf("_");
                if (length == -1)
                {
                    return equip.Name;
                }
                else
                {
                    return equip.Name.Substring(0, length + 1);
                }
            }
            return "Unknow";
        }

        public static int GetItemTypeByModelID(int cfgID)
        {
            if (cfgID >= 2000000 && cfgID < 3000000)
                return ItemType.Equip;
            if (cfgID >= 4000000 && cfgID < 5000000)
                return ItemType.HolyEquip;
            if (cfgID >= 5000000 && cfgID < 6000000)
                return ItemType.ImmortalEquip;
            if (cfgID >= 6000000 && cfgID < 7000000)
                return ItemType.LingPo;
            if (cfgID >= 7000000 && cfgID < 7010000)
                return ItemType.PetEquip;
            if (cfgID >= 7010000)
                return ItemType.SoulPearl;

            DeclareItem item = DeclareItem.Get(cfgID);
            if (null != item)
            {
                return item.Type;
            }

            return ItemType.UnDefine;
        }

        /// <summary>
        /// 根据配置表ID,生成模板数据
        /// </summary>
        /// <param name="cfgID"></param>
        /// <returns></returns>
        public static ItemBase CreateItemBase(int cfgID, bool callLua = false)
        {
            var type = GetItemTypeByModelID(cfgID);
            switch (type)
            {
                case ItemType.Equip:
                    return new Equipment(cfgID);
                case ItemType.MonsterSoulEquip:
                case ItemType.MonsterSoulMaterial:
                    return new MonsterSoulEquipData(cfgID);
                case ItemType.HolyEquip:
                    return new HolyEquip(cfgID);
                case ItemType.ImmortalEquip:
                    return new ImmortalEquip(cfgID);
                case ItemType.LingPo:
                    return new ItemLingPo(cfgID);
                case ItemType.UnDefine:
                    return null;
                default:
                    if(callLua)
                    {
                        var result = GameCenter.LuaSystem.Adaptor.CreateItembaseByCfgId(cfgID);
                        if(result != null)
                        {
                            return result;
                        }
                    }
                    return new ItemModel(cfgID);
            }
        }
        /// <summary>
        /// 根据lua端msgitem,生成模板数据
        /// </summary>
        /// <param name="msgTable"></param>
        /// <returns></returns>
        public static ItemBase CreateItemBaseByLuaMsg(LuaTable msgTable)
        {
            var msg = new ItemInfo();
            if (!msgTable.TryGet("itemId", out msg.itemId))//物品唯一ID值
                return null;
            if (!msgTable.TryGet("itemModelId", out msg.itemModelId))//物品模板ID值
                return null;
            if (!msgTable.TryGet("num", out msg.num))//数量
                return null;
            msgTable.TryGet("gridId", out msg.gridId);//所在格子编号
            msgTable.TryGet("isbind", out msg.isbind);//是否绑定 1是0否
            msgTable.TryGet("lostTime", out msg.lostTime);//过期时间
            msgTable.TryGet("cdTime", out msg.cdTime);//物品CD
            msgTable.TryGet("suitId", out msg.suitId);//套装Id
            msgTable.TryGet("strengLv", out msg.strengLv);//强化等级

            var type = GetItemTypeByModelID(msg.itemModelId);
            switch (type)
            {
                case ItemType.Equip:
                    return new Equipment(msg);
                case ItemType.MonsterSoulEquip:
                    return new MonsterSoulEquipData(msg);
                case ItemType.HolyEquip:
                    return new HolyEquip(msg);
                case ItemType.ImmortalEquip:
                    return new ImmortalEquip(msg);
                case ItemType.LingPo:
                    return new ItemLingPo(msg);
                case ItemType.UnDefine:
                    return null;
                default:
                    return new ItemModel(msg);
            }
        }

        public static ItemBase ToItemBase(string str)
        {
            ItemBase result = null;
            byte[] message = Convert.FromBase64String(str);
            ItemInfo itemInfo = new ItemInfo();
            ProtoBufUtils.Deserialize(itemInfo, message);
            var itembase = new ItemBase(itemInfo);
            switch(itembase.Type)
            {
                case ItemType.Equip:
                    result = new Equipment(itemInfo);
                    break;
                case ItemType.ImmortalEquip:
                    result = new ImmortalEquip(itemInfo);
                    break;
                case ItemType.HolyEquip:
                    result = new HolyEquip(itemInfo);
                    break;
                case ItemType.MonsterSoulEquip:
                    result = new MonsterSoulEquipData(itemInfo);
                    break;
                default:
                    result = GameCenter.LuaSystem.Adaptor.CreateItembaseByCfgId(itemInfo.itemModelId);
                    if(result == null)
                    {
                        result = new ItemModel(itemInfo);
                    }
                    break;
            }
            return result;
        }
        #endregion
    }
}