namespace Guru
{
    using System;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// 
    /// 打点管理
    /// 
    public partial class GuruSDK
    {
        /// 
        /// 主线关卡类型
        /// 只有传入此类型时才会进行 Blevel 的累加
        /// 
        public const string LevelTypeMain = "main";
        
        //----------------- 关卡开始类型 ---------------------
        public const string EventLevelStartModePlay = "play";
        public const string EventLevelStartModeReplay = "replay";
        public const string EventLevelStartModeContinue= "continue";
        
        //----------------- 关卡结束类型 ---------------------
        public const string EventLevelEndSuccess = "success";
        public const string EventLevelEndFail = "fail";
        public const string EventLevelEndExit = "exit";
        public const string EventLevelEndTimeout = "timeout";
        #region 通用接口
        /// 
        /// 自定义事件打点
        /// 
        /// 
        /// 
        public static void LogEvent(string eventName, Dictionary data = null)
        {
            if (!IsInitialSuccess)
            {
                UnityEngine.Debug.LogError($"{Tag} :: LogEvent {eventName} :: Please call  first, before you call .");
                return;
            }
            Analytics.Track(eventName, data);
        }
        public static void SetScreen(string screen, string extra = "")
        {
            if (!IsInitialSuccess)
            {
                UnityEngine.Debug.LogError($"{Tag} :: SetScreen {screen} :: Please call  first, before you call .");
                return;
            }
            Analytics.SetCurrentScreen(screen, extra);
        }
        #endregion
        
        #region 游戏打点
        /// 
        /// 游戏启动打点
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void LogLevelStart(int levelId, string startType = EventLevelStartModePlay, 
            string levelType = LevelTypeMain, string levelName = "", string puzzleId = "",
            bool isReplay = false, Dictionary extra = null)
        {
            if (!IsInitialSuccess)
            {
                UnityEngine.Debug.LogError($"{Tag} :: LogLevelStart {levelId} :: Please call  first, before you call .");
                return;
            }
            Analytics.LogLevelStart(levelId, levelName, levelType, puzzleId, startType, isReplay, extra);
        }
        /// 
        /// 游戏点击 Continue 重开始游戏
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void LogLevelContinue(int levelId, string levelType = LevelTypeMain,
            string levelName = "", string puzzleId = "", Dictionary extra = null)
        {
            LogLevelStart(levelId, EventLevelStartModeContinue, levelType, levelName, puzzleId,  true, extra:extra);
        }
        
        /// 
        /// 游戏点击 Continue 重开始游戏
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void LogLevelReplay(int levelId, string levelType = LevelTypeMain,
            string levelName = "", string puzzleId = "", Dictionary extra = null)
        {
            LogLevelStart(levelId, EventLevelStartModeReplay,levelType, levelName, puzzleId,  true, extra:extra);
        }
        
        /// 
        /// 游戏胜利打点
        /// 
        public static void LogLevelEnd(int levelId,  string result = EventLevelEndSuccess,
            string levelType = LevelTypeMain, string levelName = "", string puzzleId = "",
            int? duration = null, int? step = null, int? score = null, Dictionary extra = null )
        {
            if (!IsInitialSuccess)
            {
                UnityEngine.Debug.LogError($"{Tag} :: LogLevelEnd {levelId} :: Please call  first, before you call .");
                return;
            }
            if (InitConfig.AutoRecordFinishedLevels)
            {
                if(result == EventLevelEndSuccess){
                    if(levelType == LevelTypeMain)
                    {
                        if (levelId > Model.SuccessLevelId) Model.SuccessLevelId = levelId; // 自动记录关卡完成次数
                    }
                    Model.TotalPlayedCount++; // 自动记录关卡总次数
                }
                
                Analytics.BLevel = Model.SuccessLevelId; // 记录 BLevel
                Analytics.BPlay = Model.TotalPlayedCount; // 记录 BPlay
            }
            
            Analytics.LogLevelEnd(levelId, result, levelName, levelType, puzzleId, duration, step, score, extra);
        }
        /// 
        /// 关卡首次通关
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void LevelFirstEnd(string levelType, string levelName, int level,
            string result = EventLevelEndSuccess, int? duration = null, Dictionary extra = null)
        {
            Analytics.LevelFirstEnd(levelType, levelName, level, result, duration, extra);
        }
        /// 
        /// 游戏失败打点
        /// 需要为游戏记录详细的失败原因
        /// 
        public static void LogLevelFail(int levelId,
            string levelType = LevelTypeMain, string levelName = "", string puzzleId = "",
            int? duration = null, int? step = null, int? score = null , Dictionary extra = null)
        {
            LogLevelEnd(levelId, EventLevelEndFail, levelType, levelName, puzzleId, duration, step, score, extra);
        }
        /// 
        /// 因退出关卡导致游戏失败
        /// 
        public static void LogLevelFailExit(int levelId,
            string levelType = LevelTypeMain, string levelName = "", string puzzleId = "",
            int? duration = null, int? step = null, int? score = null, Dictionary extra = null)
        {
            LogLevelEnd(levelId, EventLevelEndExit, levelType, levelName, puzzleId, duration, step, score, extra);
        }
        /// 
        /// 因关卡超时导致游戏失败
        /// 
        public static void LogLevelFailTimeout(int levelId,
            string levelType = LevelTypeMain, string levelName = "", string puzzleId = "",
            int? duration = null, int? step = null, int? score = null, Dictionary extra = null)
        {
            LogLevelEnd(levelId, EventLevelEndTimeout, levelType, levelName, puzzleId, duration, step, score, extra);
        }
        /// 
        /// 玩家(角色)升级事件
        /// 
        /// 
        /// 
        public static void LogLevelUp(int playerLevel, string playerName, Dictionary extra = null)
        {
            if (!IsInitialSuccess)
            {
                UnityEngine.Debug.LogError($"{Tag} :: LogLevelUp {playerLevel} :: Please call  first, before you call .");
                return;
            }
            Analytics.LevelUp(playerLevel, playerName, extra);
        }
        /// 
        /// 玩家解锁成就
        /// 
        /// 
        public static void LogAchievement(string achievementName, Dictionary extra = null)
        {
            if (!IsInitialSuccess)
            {
                UnityEngine.Debug.LogError($"{Tag} :: LogAchievement {achievementName} :: Please call  first, before you call .");
                return;
            }
            Analytics.UnlockAchievement(achievementName, extra);
        }
        
        #endregion
        #region 用户属性
        /// 
        /// 提前调用用户属性
        /// 
        private static void InitUserProperties()
        {
            if (!IsInitialSuccess)
            {
                UnityEngine.Debug.LogError($"{Tag} :: InitUserProperties :: Please call  first, before you call .");
                return;
            }
            
            SetUserIsIAP(Model.IsIAPUser); // 预先设置用户的 IAP User 属性
            SetUserBLevel(Model.SuccessLevelId); // 预先设置用户的 BLevel 属性
            SetUserBPlay(Model.TotalPlayedCount);  // 预先设置用户的 BPlay 属性
        }
        /// 
        /// 设置用户属性
        /// 
        /// 
        /// 
        public static void SetUserProperty(string key, string value)
        {
            if (!IsInitialSuccess)
            {
                UnityEngine.Debug.LogError($"{Tag} :: SetUserProperty {key}:{value} ::Please call  first, before you call .");
                return;
            }
            Analytics.SetUserProperty(key, value);
        }
        public static void SetUID(string uid)
        {
            SetUserProperty(Analytics.PropertyUserID, uid);
        }
        public static void SetUserBLevel(int blevel)
        {
            SetUserProperty(Analytics.PropertyLevel, $"{blevel}");
        }
        
        public static void SetUserBPlay(int bplay)
        {
            SetUserProperty(Analytics.PropertyPlay, $"{bplay}");
        }
        public static void SetUserTotalCoins(int totalCoins)
        {
            SetUserProperty(Analytics.PropertyCoin, $"{totalCoins}");        
        }
        
        public static void SetUserCoins(int coins)
        {
            SetUserProperty(Analytics.PropertyNonIAPCoin, $"{coins}");        
        }
        
        public static void SetUserPaidCoins(int paidCoins)
        {
            SetUserProperty(Analytics.PropertyIAPCoin, $"{paidCoins}");        
        }
        
        public static void SetUserExp(int exp)
        {
            SetUserProperty(Analytics.PropertyExp, $"{exp}");        
        }
        
        public static void SetUserHp(int hp)
        {
            SetUserProperty(Analytics.PropertyHp, $"{hp}");        
        }
        public static void SetUserGrade(int grade)
        {
            SetUserProperty(Analytics.PropertyGrade, $"{grade}");        
        }
        public static void SetUserIsIAP(bool isIapUser)
        {
            SetUserProperty(Analytics.PropertyIsIAPUser, isIapUser? "true" : "false");
        }
        #endregion
        #region SDK 打点
        
        /// 
        /// Log SDK boost time
        /// 
        /// 
        private static void LogSDKInitTime(double time)
        {
            Analytics.Track(Consts.EventSDKInfo, new Dictionary()
            {
                { "boost_time", time.ToString("F6") },
                { Consts.PropertyDeviceID, DeviceId },
                { "version", Version}
            }, new Analytics.EventSetting()
            {
                EnableFirebaseAnalytics = true,
            });
            
            SetUserProperty("sdk_version", Version);
        }
        
        #endregion
        #region IAP 打点
        /// 
        /// 当付费页面打开时调用
        /// 
        /// 付费页面名称, 默认为 Store
        /// 列表中首个商品的 ProductId 
        public static void OnIAPPageOpen(string scene = "Store", string productId = "")
        {
            if (string.IsNullOrEmpty(productId))
            {
                if (GuruSettings.Instance != null && (GuruSettings.Instance.Products?.Length ?? 0) > 0)
                {
                    productId = GuruSettings.Instance.Products[0].ProductId;
                }
            }
            Analytics.IAPImp(scene, productId);
        }
        /// 
        /// 当付费页面关闭时调用
        /// 
        /// 
        /// 
        public static void OnIAPPageClose(string scene = "Store", string productId = "")
        {
            if (string.IsNullOrEmpty(productId))
            {
                productId = GuruIAP.Instance.CurrentBuyingProductId;
            }
            Analytics.IAPClose(scene, productId);
        }
        #endregion
        #region 经济打点
        
        // ************************************************************************************************
        // *
        // *                                        经济打点
        // * 内容详参: https://docs.google.com/spreadsheets/d/1xYSsAjbrwqeJm7panoVzHO0PeGRQVDCR4e2CU9OPEzk/edit#gid=0
        // *
        // ************************************************************************************************
        
        //---------------------------------------- EARN ---------------------------------------- 
        /// 
        /// 获取虚拟货币/道具. 
        /// 基础接口, 不推荐项目组直接调用
        /// 请直接调用其他对应场景的统计接口
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void EarnVirtualCurrency(string currencyName, 
            int value, int balance, 
            string category = "", string itemName = "",
            string levelName = "", string scene = "", Dictionary extra = null)
        {
            Analytics.EarnVirtualCurrency(currencyName, value, balance, category, itemName,levelName, scene, extra);
        }
        
        
        
        /// 
        /// 赚取组合: 货币+道具
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        private static void EarnVirtualCurrencyAndProps(string currencyName, 
            int value = 0, int balance = 0,
            string category = "", string itemName = "",
            string levelName = "", string scene = Consts.ParameterDefaultScene,  
            string[] props = null, Dictionary extra = null)
        {
            //---- Currency -----
            if (value > 0)
            {
                EarnVirtualCurrency(currencyName, value, balance, category, itemName, levelName, scene, extra);
            }
            //---- Props --------
            if (null != props)
            {
                int i = 0;
                while (i < props.Length)
                {
                    EarnVirtualCurrency(props[i], 1, 0, category, itemName, levelName, scene, extra);
                    i++;
                }
            }
        }
        /// 
        /// 签到奖励. 获得货币/道具
        /// 通常类型: Coin 收入 
        /// 特殊类型: Coin + Props (道具列表) 
        /// 特殊类型: Props (道具列表) 
        /// 
        /// 货币名称
        /// 赚取金额
        /// 货币总量(累加后)
        /// 当前关卡名称
        /// 应用场景
        /// 获取的道具名称列表
        public static void EarnVirtualCurrencyBySign(string currencyName, 
            int value = 0, int balance = 0, string levelName = "", 
            string scene = "home", string[] props = null, Dictionary extra = null)
        {
            string category = Consts.CurrencyCategoryReward;
            string itemName = "sign";
            EarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, props, extra);
        }
        /// 
        /// IAP 付费购买. 获得货币/道具
        /// 通常类型: Coin 收入 
        /// 特殊类型: Coin + Props (道具列表) 
        /// 特殊类型: Props (道具列表)  
        /// 
        /// IAP 道具名称
        /// IAP 道具商品 ID 
        /// 赚取金额
        /// 货币总量(累加后)
        /// 当前关卡名称
        /// 应用场景
        /// 获取的道具名称列表
        public static void EarnVirtualCurrencyByIAP(string currencyName, string productId, 
            int value = 0, int balance = 0, string levelName = "", 
            string scene = "store", string[] props = null, Dictionary extra = null)
        {
            string category = Consts.CurrencyCategoryIAP;
            string itemName = productId;
            EarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, props, extra);
        }
        /// 
        /// 看广告获取到货币/道具
        /// 通常类型: Coin 收入 
        /// 特殊类型: Coin + Props (道具列表) 
        /// 特殊类型: Props (道具列表)  
        /// 
        /// 货币名称
        /// 赚取金额
        /// 货币总量(累加后)
        /// 当前关卡名称
        /// 应用场景
        /// 获取的道具名称列表
        public static void EarnVirtualCurrencyByAds(string currencyName, 
            int value = 0, int balance = 0, string levelName = "", 
            string scene = "store", string[] props = null, Dictionary extra = null)
        {
            string category = Consts.CurrencyCategoryReward;
            string itemName = "ads";
            EarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, props, extra);
        }
        
        /// 
        /// 使用了金币半价 + 看广告获取到货币/道具
        /// 通常类型: Coin 收入 
        /// 特殊类型: Coin + Props (道具列表) 
        /// 特殊类型: Props (道具列表)  
        /// 
        /// 货币名称
        /// 赚取金额
        /// 货币总量(累加后)
        /// 当前关卡名称
        /// 应用场景
        /// 获取的道具名称列表
        public static void EarnVirtualCurrencyByPaidAds(string currencyName, 
            int value = 0, int balance = 0, string levelName = "", 
            string scene = Consts.ParameterDefaultScene, string[] props = null, Dictionary extra = null)
        {
            string category = Consts.CurrencyCategoryBonus;
            string itemName = "ads";
            EarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, props, extra);
        }
        /// 
        /// 过关奖励获取到货币/道具
        /// 通常类型: Coin 收入 
        /// 特殊类型: Coin + Props (道具列表) 
        /// 特殊类型: Props (道具列表)  
        /// 
        /// 货币名称
        /// 赚取金额
        /// 货币总量(累加后)
        /// 当前关卡名称
        /// 应用场景
        /// 获取的道具名称列表
        public static void EarnVirtualCurrencyByLevelComplete(string currencyName, 
            int value = 0, int balance = 0, string levelName = "", 
            string scene = "store", string[] props = null, Dictionary extra = null)
        {
            string category = Consts.CurrencyCategoryReward;
            string itemName = "level";
            EarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, props, extra);
        }
        /// 
        /// 通过使用 Currency 购买获得 Prop (记录 Prop 增加的打点, 消费游戏内货币)
        /// 
        /// 货币名称
        /// 获取的道具名称列表
        /// 应用场景
        /// 赚取金额
        /// 货币总量(累加后)
        /// 当前关卡名称
        public static void EarnPropsByVirtualCurrency(string currencyName, string[] props,
            string scene = Consts.ParameterDefaultScene,
            int value = 1, int balance = 0, string levelName = "", Dictionary extra = null)
        {
            string category = Consts.CurrencyCategoryIGC;
            string itemName = currencyName;
            EarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, props, extra);
        }
        
        /// 
        /// 通过道具交换/合成或得了其他道具
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void EarnPropByProp(string propName, string otherName,
            string scene = Consts.ParameterDefaultScene,
            int value = 1, int balance = 0, string levelName = "", Dictionary extra = null)
        {
            string category = Consts.CurrencyCategoryIGB;
            EarnVirtualCurrency(propName, value, balance, category, otherName, levelName, scene, extra);
        }
        
        
        /// 
        /// 通过转盘或者抽奖, 获取货币/道具
        /// 通常类型: Coin 收入 
        /// 特殊类型: Coin + Props (道具列表) 
        /// 特殊类型: Props (道具列表)  
        /// 
        /// 货币名称
        /// 赚取金额
        /// 货币总量(累加后)
        /// 当前关卡名称
        /// 应用场景
        /// 获取的道具名称列表
        public static void EarnVirtualCurrencyByLottery(string currencyName, 
            int value = 0, int balance = 0, string levelName = "", 
            string scene = "store", string[] props = null, Dictionary extra = null)
        {
            string category = Consts.CurrencyCategoryIGB;
            string itemName = "lottery";
            EarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, props, extra);
        }
        
        
        //---------------------------------------- EARN ---------------------------------------- 
        /// 
        /// 花费虚拟货币/道具
        /// 基础接口, 不推荐项目组直接调用
        /// 请直接调用其他对应场景的统计接口
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void SpendVirtualCurrency(string currencyName, 
            int value, int balance, 
            string category = "", string itemName = "",
            string levelName = "", string scene = "", Dictionary extra = null)
        {
            Analytics.SpendVirtualCurrency(currencyName, value, balance, category, itemName, levelName, scene, extra);
        }
        /// 
        /// 消耗货币购买道具
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void SpendVirtualCurrencyWithProp(string currencyName, string prop,
            int value, int balance,
            string levelName = "", string scene = "", Dictionary extra = null)
        {
            SpendVirtualCurrencyWithProps(currencyName, new string[] {prop}, value, balance, levelName, scene, extra);
        }
        /// 
        /// 消耗货币购买道具 (含多个)
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void SpendVirtualCurrencyWithProps(string currencyName, string[] props,
            int value, int balance, 
            string levelName = "", string scene = "", Dictionary extra = null)
        {
            string category = Consts.CurrencyCategoryProp;
            if (props != null && props.Length > 0)
            {
                int i = 0;
                while (i < props.Length)
                {
                    SpendVirtualCurrency(currencyName, value, balance, category, props[i], levelName, scene, extra); 
                    i++;
                }
            }
        }
        /// 
        /// 消耗货币购买礼包或组合
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void SpendVirtualCurrencyWithBundle(string currencyName, string bundle,
            int value, int balance,
            string levelName = "", string scene = "", Dictionary extra = null)
        {
            SpendVirtualCurrencyWithBundles(currencyName, new string[] {bundle}, value, balance, levelName, scene, extra);
        }
        /// 
        /// 消耗货币购买礼包或组合  (含多个)
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void SpendVirtualCurrencyWithBundles(string currencyName, string[] bundles,
            int value, int balance, 
            string levelName = "", string scene = "", Dictionary extra = null)
        {
            string category = Consts.CurrencyCategoryBundle;
            if (bundles != null && bundles.Length > 0)
            {
                int i = 0;
                while (i < bundles.Length)
                {
                    SpendVirtualCurrency(currencyName, value, balance, category, bundles[i], levelName, scene, extra); 
                    i++;
                }
            }
        }
        
        /// 
        /// 消耗物品, 交换其他物品
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void SpendPropWithProp(string propName, string otherName,
            int value, int balance, 
            string levelName = "", string scene = "", string extraCategory = "", Dictionary extra = null)
        {
            string category = string.IsNullOrEmpty(extraCategory) ? Consts.CurrencyCategoryProp : extraCategory;
            SpendVirtualCurrency(propName, value, balance, category, otherName, levelName, scene, extra); 
        }
        #endregion
        #region Crashlytics 接口
        public static void CrashLog(string message)
        {
            if (!IsFirebaseReady) return;
            CrashlyticsAgent.Log(message);
        }
        
        public static void CrashException(string message)
        {
            if (!IsFirebaseReady) return;
            CrashlyticsAgent.LogException(message);
        }
        public static void CrashException(Exception ex)
        {
            if (!IsFirebaseReady) return;
            CrashlyticsAgent.LogException(ex);
        }
        public static void CrashCustomKeys(string key, string value)
        {
            if (!IsFirebaseReady) return;
            CrashlyticsAgent.SetCustomKey(key, value);
        }
        #endregion
    }
}