using FL.Data.Items;
using System;
using System.Collections.Generic;
using UnityEngine;
using XGame;
using XGame.Database;
using XGame.Framework.Data;
using Random = UnityEngine.Random;

namespace FL.Data
{
    public class DragonEggService : DataSingleton<DragonEggService>, IDisposable
    {
        /// <summary>
        /// 升级龙蛋
        /// </summary>
        public void UpgradeDragonEgg(long nowTime, int upgradeTime)
        {
            // 测试
            DragonEggData.Instance.UpgradeEndTime = nowTime + upgradeTime;
            EventSingle.Instance.Notify(EventDefine.UpgradeDragonEgg);
        }

        /// <summary>
        /// 填充龙蛋能量
        /// </summary>
        /// <param name="expend"></param>
        public void FillDragonEggEnergy(int[] expend)
        {
            int index = DragonEggData.Instance.EggEnergy * 2;
            int itemId = expend[index];
            var needCount = expend[index + 1];
            var itemCount = ItemData.Instance.GetItemNum(itemId); // 拥有的道具数量
            if (itemCount < needCount) // 道具数量不足，道具来源弹窗
            {

            }
            else
            {
                // 测试
                ItemData.Instance.OnChangeItemData(itemId, itemCount - needCount);
                DragonEggData.Instance.EggEnergy += 1;
                EventSingle.Instance.Notify(EventDefine.FillEnergy);
            }
        }
        /// <summary>
        /// 观看广告减少龙蛋升级时间
        /// </summary>
        public void ReduceTimeByWatchAd(long nowTime)
        {
            if (DragonEggData.Instance.WatchAdCount > 0)
            {
                // 测试
                DragonEggData.Instance.WatchAdCount -= 1;
                ReduceUpgradeEggTime(DragonEggData.Instance.AdReduceTime * 1000, nowTime);
            }
        }

        // 本地测试UI升级时间显示用
        private void ReduceUpgradeEggTime(int reduceTime, long nowTime)
        {
            DragonEggData.Instance.UpgradeEndTime -= reduceTime;
            if (DragonEggData.Instance.UpgradeEndTime - nowTime > 0)
            {
                EventSingle.Instance.Notify(EventDefine.ReduceDragonEggTime);
            }
            else
            {
                DragonEggData.Instance.UpgradeEndTime = 0;
                DragonEggData.Instance.EggEnergy = 0;
                DragonEggData.Instance.EggLv += 1;
                EventSingle.Instance.Notify(EventDefine.UpgradeDragonEggSucess);
            }
        }

        /// <summary>
        /// 使用龙蛋升阶加速卡道具
        /// </summary>
        public void UseAcceleratorCard(int id, int count, long nowTime)
        {
            // 测试
            ReduceUpgradeEggTime(DragonEggData.Instance.ReduceTime * 1000 * count, nowTime);
        }

        /// <summary>
        /// 需要的升级卡数量
        /// </summary>
        public int GetAccelerationCardNum(int id, long needTime, bool bMax = true)
        {
            int needNum = 0;
            if (needTime > 0)
            {
                float second = Mathf.CeilToInt(needTime / 1000.0f);// 转化为秒
                int reduceTime = 0;
                var itemInfo = ItemTableRepo.Get(id);
                if (itemInfo?.Effect[0] == (int)EPropEffect.AccelerationTime) reduceTime = itemInfo.Effect[1];
                if (reduceTime > 0)
                {
                    needNum = bMax ? Mathf.CeilToInt(second / reduceTime) : Mathf.FloorToInt(second / reduceTime);
                }
            }
            return needNum;
        }

        /// <summary>
        /// 请求打造装备
        /// </summary>
        public void MakeEquip()
        {
            var id = ItemData.Instance.GetNewEquipId();
            if (id > 0)
            {
                EventSingle.Instance.Notify(EventDefine.DropEquip, id);
                return;
            }
            if (DragonEggData.Instance.EggCount > 0)
            {
                AnalogDropEquip();
            }
            else
            {
                EventSingle.Instance.Notify(EventDefine.ShowTips, StringDefine.dragonEggsEmpty);
            }
        }
        private void AnalogDropEquip()
        {
            // 模拟装备掉落
            EnergyTable dragonEggInfo = EnergyTableRepo.Get(DragonEggData.Instance.EggLv);
            if (dragonEggInfo == null) return;
            var weightedList = new List<int>();
            var weightedQualityList = new List<EQualityLevel>();
            for (int i = 0; i < dragonEggInfo.Pro_quality.Length; i += 2)
            {
                int weightedValue = dragonEggInfo.Pro_quality[i + 1];
                if (weightedValue > 0)
                {
                    weightedList.Add(weightedValue);
                    weightedQualityList.Add((EQualityLevel)dragonEggInfo.Pro_quality[i]);
                }
            }

            int qualityIndex = MathUtils.Random(weightedList);
            EQualityLevel quality = weightedQualityList[qualityIndex];
            var dropEquipIds = EquipmentDropTableRepo.GetEquipIds(quality, PlayerData.Instance.Level);
            int equipId = dropEquipIds[MathUtils.Random(dropEquipIds)];
            EquipItem equipData = AnalogEquipData(equipId, UIDDefine.New(), false);
            ItemData.Instance.AddNewEquip(equipData);
            // 测试
            EventSingle.Instance.Notify(EventDefine.DropEquip, equipData.Id);
        }

        /// <summary>
        /// 请求替换装备
        /// </summary>
        /// <param name="equipType"></param>
        /// <param name="equipData"></param>
        public void OnChangeEquip(EEquipType equipType, EquipItem equipData)
        {
            EquipItem wearEquip = ItemData.Instance.GetEquipData(equipType);
            if (wearEquip != null)
            {
                wearEquip.Dispose();
            }
            // 测试模拟
            ItemData.Instance.OnChangeEquip(equipType, equipData);
            ChangeEquipParam param = new ChangeEquipParam();
            param.equipUid = equipData.Id;
            param.equipType = equipType;
            EventSingle.Instance.Notify(EventDefine.OnChangeEquip, param);
            DragonEggData.Instance.EggCount -= 1;
            ItemData.Instance.RemoveNewEquip(equipData.Id);
        }

        /// <summary>
        /// 出售装备
        /// </summary>
        /// <param name="equipData"></param>
        public void SellEquip(EquipItem equipData)
        {
            DragonEggData.Instance.EggCount -= 1;
            ItemData.Instance.RemoveNewEquip(equipData.Id);
            equipData.Dispose();
            Log.Debug($"出售装备:{equipData.Name}");
        }

        #region 测试数据
        public void TestDragonQualityBoxData()
        {
            // 测试龙蛋品质宝箱数量
            for (int i = 0; i < 5; i++)
            {
                OnchangeDragonEgg((EQualityLevel)i, (5 - i) * 100);
            }
            DragonEggData.Instance.DragonEggSocre = 0;
            DragonEggData.Instance.MaxDragonEggSocre = 10;
        }


        // 测试道具、装备、龙蛋数据
        public void TestData()
        {
            OnTestEquipIdDic();
            TestItemDic();
            TestDragonQualityBoxData();
        }

        // 背包拥有的道具数据
        public void TestItemDic()
        {
            ItemData.Instance.OnChangeItemData(1, 1000000);
            ItemData.Instance.OnChangeItemData(6, 100);
        }
        // 身上部位穿戴的装备测试数据
        public void OnTestEquipIdDic()
        {
            TestDragonEggData();
            ItemData.Instance.OnChangeEquip(EEquipType.Weapon, AnalogEquipData(110101, UIDDefine.New(), false));
            ItemData.Instance.OnChangeEquip(EEquipType.Helmet, AnalogEquipData(210201, UIDDefine.New(), false));
            ItemData.Instance.OnChangeEquip(EEquipType.Clothes, AnalogEquipData(310101, UIDDefine.New(), false));
            ItemData.Instance.OnChangeEquip(EEquipType.Hand, AnalogEquipData(410101, UIDDefine.New(), false));
            //ItemData.Instance.OnChangeEquip(EEquipType.Pants, AnalogEquipData(510501, UIDDefine.New(), false));
            //ItemData.Instance.OnChangeEquip(EEquipType.Boots, AnalogEquipData(610101, UIDDefine.New(), false));
        }
        // 测试龙蛋
        private void TestDragonEggData()
        {
            PlayerData.Instance.Level = 5;
            PlayerData.Instance.Exp = 156;
            PlayerData.Instance.Title = "Title_001";
            DragonEggData.Instance.EggLv = 6;
            DragonEggData.Instance.EggCount = 30;
            DragonEggData.Instance.EggEnergy = 0;
            DragonEggData.Instance.AddUnlockQualityDic(10, 1);
            DragonEggData.Instance.AddUnlockQualityDic(11, 2);
            DragonEggData.Instance.MaxWatchAdCount = 4;
            DragonEggData.Instance.WatchAdCount = 4;
            DragonEggData.Instance.AdReduceTime = 180;
            DragonEggData.Instance.AccelerateId = 6;
            DragonEggData.Instance.ReduceTime = 300;
        }
        /// <summary>
        /// 模拟装备数据
        /// </summary>
        /// <param name="tableId"></param>
        /// <param name="id"></param>
        /// <param name="bShowName"></param>
        /// <returns></returns>
        public EquipItem AnalogEquipData(int tableId, long id, bool bShowName = true)
        {
            EquipmentTable equipInfo = EquipmentTableRepo.Get(tableId);
            int level = equipInfo.Level == 0 ? GetEquipLv() : equipInfo.Level;
            EquipItem _equipItem = new EquipItem();
            _equipItem.Init(equipInfo, id);
            _equipItem.Level = level;
            bool bWeapon = _equipItem.EquipType == EEquipType.Weapon;
            SetEquipBaseAttributes(_equipItem, level, bWeapon);
            if (equipInfo.Quality > EQualityLevel.Green)
            {
                SetEquipPeculiarAttributes(_equipItem, level, bWeapon);
            }

            //装备的属性列表
            var equipAttributes = new List<EAttributeType>();
            _equipItem.Attributes.GetAll(ref equipAttributes, 0);

            _equipItem.FightingPower = GetFightingPower(equipAttributes, _equipItem);
            return _equipItem;
        }
        /// <summary>
        /// 获取装备的属性转化的战斗力值
        /// </summary>
        /// <param name="attrMap"></param>
        /// <returns></returns>
        public long GetFightingPower(List<EAttributeType> attributeList, EquipItem equipItem)
        {
            long fightPower = 0;
            foreach (var item in attributeList)
            {
                fightPower += GetAttrToFightingPower(item, equipItem.Attributes.GetValue(item));
            }
            return fightPower;
        }
        /// <summary>
        /// 属性类型转化为战力值
        /// </summary>
        /// <returns></returns>
        private int GetAttrToFightingPower(EAttributeType attributeType, long attributeVal)
        {
            AttrDescTable attrInfo = AttrDescTableRepo.Get((int)attributeType);
            Debug.Assert(attrInfo != null, $"AttrDescTable表不存在属性类型{attributeType}");
            bool bRatio = attrInfo.Num_type == 1 || attributeType == EAttributeType.AtkSpeed;
            return Mathf.CeilToInt(attrInfo.PowerConversion.ToReal() * (bRatio ? (float)attributeVal.ToRealDouble() : attributeVal));
        }


        /// <summary>
        /// 下限等级：当前等级-3
        //   特殊情1. 等级<=3级前，不触发等级下限的逻辑，直接取当前等级 2. 15>等级>3，触发的下限等级逻辑为当前等级-2
        /// </summary>
        /// <returns></returns>
        private int GetEquipLv()
        {
            int playerLv = PlayerData.Instance.Level;
            int minLv = playerLv < 4 ? playerLv : (playerLv < 15 ? (playerLv - 2) : (playerLv - 3));
            return Random.Range(minLv, playerLv + 1);//随机生成最小值到最大值之间的整数。包含最小值，但不包含最大值
        }
        private void SetEquipBaseAttributes(EquipItem _equipItem, int level, bool bWeapon)
        {
            Attributes attr = _equipItem.Attributes;
            EquipmentBaseAttrTable baseAttrs = EquipmentBaseAttrTableRepo.GetEquipmentBaseAttrTable(_equipItem.Quality, level, bWeapon);
            if (baseAttrs == null) return;
            attr.SetValue(EAttributeType.Hp, GetRandomAttrVal(baseAttrs.Hp));
            attr.SetValue(EAttributeType.Atk, GetRandomAttrVal(baseAttrs.Atk));
            attr.SetValue(EAttributeType.Def, GetRandomAttrVal(baseAttrs.Def));
            if (bWeapon)
            {
                attr.SetValue(EAttributeType.AtkSpeed, baseAttrs.AtkSpeek);
            }
        }
        //随机生成最小值到最大值之间的整数。包含最小值，但不包含最大值
        private int GetRandomAttrVal(int[] attrValList)
        {
            return Random.Range(attrValList[0], attrValList[1] + 1);
        }
        private void SetEquipPeculiarAttributes(EquipItem _equipItem, int level, bool bWeapon)
        {
            if (_equipItem.Quality < EQualityLevel.Blue) return;
            // 蓝品装备开启第一条特殊属性，黄品装备开启第二条
            Attributes attr = _equipItem.Attributes;
            EquipmentPeculiarAttrTable specialAttrs1 = EquipmentPeculiarAttrTableRepo.GetEquipmentSpecialAttrTable(_equipItem.Quality, 1);
            if (specialAttrs1 != null)
            {
                EAttributeType[] attrTypeList1 = { EAttributeType.Crit, EAttributeType.DoubleHit, EAttributeType.Counter, EAttributeType.Verti, EAttributeType.Eva };
                int[] weightedList = { specialAttrs1.CritRate, specialAttrs1.DoubleHitRate, specialAttrs1.CounterRate, specialAttrs1.VertiRate, specialAttrs1.EvaRate };
                EAttributeType specialType1 = attrTypeList1[MathUtils.Random(weightedList)];
                attr.SetValue(specialType1, GetSpecialAttrVal(specialType1, specialAttrs1));
            }
            if (_equipItem.Quality < EQualityLevel.Yellow) return;
            EquipmentPeculiarAttrTable specialAttrs2 = EquipmentPeculiarAttrTableRepo.GetEquipmentSpecialAttrTable(_equipItem.Quality, 2);
            if (specialAttrs2 != null)
            {
                EAttributeType[] attrTypeList2 = { EAttributeType.CritRes, EAttributeType.VertigoRes, EAttributeType.EvaRes, EAttributeType.DoubleHitRes, EAttributeType.CounterRes };
                int[] weightedList = { specialAttrs2.CritResRate, specialAttrs2.VertigoResRate, specialAttrs2.EvaResRate, specialAttrs2.DoubleHitResRate, specialAttrs2.CounterResRate };
                EAttributeType specialType2 = attrTypeList2[MathUtils.Random(weightedList)];
                attr.SetValue(specialType2, GetSpecialAttrVal(specialType2, specialAttrs2));
            }
        }

        private int GetSpecialAttrVal(EAttributeType attrType, EquipmentPeculiarAttrTable specialAttrs)
        {
            switch (attrType)
            {
                case EAttributeType.Crit:
                    return GetRandomAttrVal(specialAttrs.Crit);
                case EAttributeType.DoubleHit:
                    return GetRandomAttrVal(specialAttrs.DoubleHit);
                case EAttributeType.Counter:
                    return GetRandomAttrVal(specialAttrs.Counter);
                case EAttributeType.Verti:
                    return GetRandomAttrVal(specialAttrs.Verti);
                case EAttributeType.Eva:
                    return GetRandomAttrVal(specialAttrs.Eva);
                case EAttributeType.CritRes:
                    return GetRandomAttrVal(specialAttrs.CritRes);
                case EAttributeType.VertigoRes:
                    return GetRandomAttrVal(specialAttrs.VertigoRes);
                case EAttributeType.EvaRes:
                    return GetRandomAttrVal(specialAttrs.EvaRes);
                case EAttributeType.DoubleHitRes:
                    return GetRandomAttrVal(specialAttrs.DoubleHitRes);
                case EAttributeType.CounterRes:
                    return GetRandomAttrVal(specialAttrs.CounterRes);
                default:
                    return 0;
            }
        }

        #endregion


        /// <summary>
        /// 龙裔宝卵数量变化
        /// </summary>
        /// <param name="quality"></param>
        /// <param name="num"></param>
        public void OnchangeDragonEgg(EQualityLevel quality, int num)
        {
            DragonEggData.Instance.OnchangeDragonEgg(quality, num);
        }

        void IDisposable.Dispose()
        {

        }
    }
}
