using FairyGUI;
using System.Linq;
 
using UnityEngine;

namespace BingoBrain
{
    using System;
    using System.Collections.Generic;
    
    [Flags]
     
    public enum RewardDisplayType
    {
        None = 0b_0000_0000,


        Number = 0b_0000_0001,


        ValueChange = 0b_0000_0010,


        Dialog = 0b_0000_0100,


        RewardFly = 0b_0000_1000,
    }


     
    public enum RewardOrigin
    {
        None,
        Ballon,
        MoreCard,
        PickBox,
        PlayBallon,
        Slot,
        PlayCard,
        Wheel,
        Redeem,


        Naive,


        GameWin,


        H5Icon,


        H5Fly102,


        Invite,


        SignIn,


        Play,


        OpenReward,

        DailyTask,

        LuckyWheel,

        BuyGold,
        AdTask
    }


     
    public enum RewardCondition
    {
        None,


        AD,
    }

     
    public class Goda
    {
        public int id;


        public int type;


        public decimal value;


        public decimal multiRate;


        public decimal rate;


        public decimal GetTotalValue()
        {
            return Math.Round(value * rate, 2);
        }


        public RewardOrigin origin;


        public Vector2 startPosition;


        public Vector2 endPosition;

        public Goda(int id, decimal value, RewardOrigin origin)
        {
            this.id = id;
            this.value = value;
            this.origin = origin;
            InitData();
        }
        public Goda(int id, decimal value, RewardOrigin origin, Vector2 startPosition) : this(id, value,
            origin)
        {
            this.startPosition = startPosition;
        }


        private void InitData()
        {
            InitRate();
            InitMultiRate();
        }


        private void InitRate()
        {
            if (rate == 0)
            {
                rate = 1;
            }
        }


        private void InitMultiRate()
        {
            if (multiRate == 0)
            {
                multiRate = 1;
            }
        }

        public void InitFlyPosition()
        {
            InitStartPosition();
            InitEndPosition();
        }

        private void InitStartPosition()
        {
            if (startPosition == Vector2.zero)
            {
                startPosition = GRoot.inst.size / 2;
            }
        }

        private void InitEndPosition()
        {
            if (endPosition == Vector2.zero && id != 0)
            {
                var itemUI = GameHelper.GetItemUI(id);
                var gObject = itemUI?.GetChildAt(1);
                if (gObject != null)
                {
                    endPosition = itemUI.LocalToRoot((Vector2)gObject.position + gObject.size / 2, GRoot.inst);
                }
            }
        }


        public bool IsCanFly()
        {
            return IsCanFly(id);
        }


        public static bool IsCanFly(int id)
        {
            if (id == 101 || id == 102 || id == 105 || id == 106)
            {
                return true;
            }

            return false;
        }
    }

     
    public class RewardData
    {
        public List<Goda> rewardDataList;


        public RewardDisplayType displayType;


        public RewardCondition condition;


        private Action<bool> mOnCompleted;


        public bool isSingle;

        public decimal ctRate;

        public RewardData()
        {
            InitData();
        }

        public RewardData(int rewardId, decimal rewardValue, RewardOrigin origin, int rate) : this()
        {
            AddReward(rewardId, rewardValue, origin, rate);
        }

        public RewardData(int rewardId, decimal rewardValue, RewardOrigin origin, int rate,
            Action<bool> onCompleted) : this(
            rewardId, rewardValue, origin, rate)
        {
            mOnCompleted = onCompleted;
        }

        private RewardData(List<Goda> rewardDataList)
        {
            AddRewardList(rewardDataList);
        }

        private RewardData(List<Goda> rewardDataList, Action<bool> onCompleted) : this(rewardDataList)
        {
            mOnCompleted = onCompleted;
        }


        private void AddRewardList(List<Goda> rewardDataList)
        {
            if (rewardDataList != null)
            {
                foreach (var rewardData in rewardDataList)
                {
                    AddReward(rewardData);
                }
            }
        }


        public void SetCompleted(Action<bool> onCompleted)
        {
            mOnCompleted = onCompleted;
        }


        public void AddCompleted(Action<bool> onCompleted)
        {
            mOnCompleted += onCompleted;
        }


        public void OnCompleted(bool isSuccess)
        {
            mOnCompleted?.Invoke(isSuccess);
        }

        public Action<bool> GetCompleted()
        {
            return mOnCompleted;
        }


        public void AddReward(Goda goda)
        {
            rewardDataList ??= new List<Goda>();

            var isNeedAdd = true;

            foreach (var data in rewardDataList.Where(data => data.id == goda.id))
            {
                data.value += goda.value;
                isNeedAdd = false;
                break;
            }

            if (isNeedAdd)
            {
                rewardDataList.Add(goda);
            }
        }


        public void AddReward(int rewardId, decimal rewardValue, RewardOrigin origin, int rate = 1)
        {
            var rewardSingleData = new Goda(rewardId, rewardValue, origin)
            {
                rate = rate
            };
            AddReward(rewardSingleData);
        }


        public bool IsContainReward(int rewardId)
        {
            return rewardDataList.Any(data => data.id == rewardId);
        }


        private void InitData()
        {
            if (rewardDataList != null)
            {
                rewardDataList.Clear();
            }
            else
            {
                rewardDataList = new List<Goda>();
            }
        }

        public List<Goda> GetRewardDataList()
        {
            return rewardDataList;
        }

        public int GetRewardFlyCount()
        {
            return GetRewardDataList().Count(rewardSingleData => rewardSingleData.IsCanFly());
        }
    }
}