namespace Guru.Editor
{
    using System;
    using System.IO;
    using UnityEditor;
    using UnityEngine;
    using System.Collections.Generic;
    using System.Linq;
    
    public class GuruServiceConverterHelper
    {
        const string K_APP_SETTINGS = "app_settings";
        const string K_ADJUST_SETTINGS = "adjust_settings";
        const string K_FB_SETTINGS = "fb_settings";
        const string K_AD_SETTINGS = "ad_settings";
        const string K_IAP_SETTINGS = "iap_settings";
        const char K_SPLITTER_TAB = '\t';
        const char K_SPLITTER_COMMA = ',';
        
        #region Export JSON
        
        /// 
        /// 从 TSV 文件进行转化
        /// 
        /// 
        /// 
        public static void ConvertFromTSV(string tsvPath, string savePath = "")
        {
            if (!File.Exists(tsvPath))
            {
                EditorUtility.DisplayDialog("FILE NOT FOUND!", $"File not exist:\n{tsvPath}", "OK");
                return;
            }
            
            var guru_service = EditorGuruServiceIO.CreateEmpty();
                
            var lines = File.ReadAllLines(tsvPath);
            string line = "";
            for (int index = 0; index < lines.Length; index++)
            {
                line = lines[index];
                if (!IsInvalidLine(line))
                {
                    //---------------- app_settings ----------------
                    if (line.StartsWith(K_APP_SETTINGS))
                    {
                        index++;
                        while (!line.StartsWith(K_ADJUST_SETTINGS))
                        {
                            line = lines[index];
                            FillAppSettings(guru_service, line);
                            index++;
                            line = lines[index];
                        }
                    }
                    //---------------- adjust_settings ----------------
                    if (line.StartsWith(K_ADJUST_SETTINGS))
                    {
                        index++;
                        FillAdjustSettings(guru_service, lines, ref index);
                    }
                    //---------------- fb_settings ----------------
                    if (line.StartsWith(K_FB_SETTINGS))
                    {
                        index++;
                        FillFacebookSettings(guru_service, lines, ref index);
                    }
                    //---------------- ad_settings ----------------
                    if (line.StartsWith(K_AD_SETTINGS))
                    {
                        index++;
                        FillAdSettings(guru_service, lines, ref index);
                    }
                    //---------------- iap_settings ----------------
                    if (line.StartsWith(K_IAP_SETTINGS))
                    {
                        index++;
                        FillProducts(guru_service, lines, ref index);
                    }
                }
                
            }
            
            EditorGuruServiceIO.SourceServiceFilePath = savePath;
            EditorGuruServiceIO.SaveConfig(guru_service, savePath);
            if (EditorUtility.DisplayDialog("CONVERT SUCCESS!", $"Export Json to:\n{savePath}", "OK"))
            {
                GuruEditorHelper.OpenPath(Directory.GetParent(savePath)?.FullName ?? Application.dataPath);
            }
        }
        /// 
        /// AppSettings 填充
        /// 
        /// 
        /// 
        private static void FillAppSettings(GuruServicesConfig settings, string line)
        {
            // 对于空行和空值直接跳过
            if (IsInvalidLine(line)) return;
            string value = "";
            if (settings.app_settings == null) settings.app_settings = new GuruAppSettings();
            // 拾取值和注入
            if (GetValue(line, "app_id", out value))
            {
                settings.app_settings.app_id = value;
            }
            else if (GetValue(line, "product_name", out value))
            {
                settings.app_settings.product_name = value;
            }
            else if (GetValue(line, "bundle_id", out value))
            {
                settings.app_settings.bundle_id = value;
            }
            else if (GetValue(line, "support_email", out value))
            {
                settings.app_settings.support_email = value;
            }
            else if (GetValue(line, "privacy_url", out value))
            {
                settings.app_settings.privacy_url = value;
            }
            else if (GetValue(line, "terms_url", out value))
            {
                settings.app_settings.terms_url = value;
            }
            else if (GetValue(line, "android_store", out value))
            {
                settings.app_settings.android_store = value;
            }
            else if (GetValue(line, "ios_store", out value))
            {
                settings.app_settings.ios_store = value;
            }
            else if (GetValue(line, "enable_firebase", out value))
            {
                settings.app_settings.enable_firebase = GetBool(value);
            }
            else if (GetValue(line, "enable_facebook", out value))
            {
                settings.app_settings.enable_facebook = GetBool(value);
            }
            else if (GetValue(line, "enable_adjust", out value))
            {
                settings.app_settings.enable_adjust = GetBool(value);
            }
            else if (GetValue(line, "enable_iap", out value))
            {
                settings.app_settings.enable_iap = GetBool(value);
            }
            else if (GetValue(line, "custom_keystore", out value))
            {
                settings.app_settings.custom_keystore = GetBool(value);
            }
        }
        /// 
        /// AdjustSettings 填充
        /// 
        /// 
        /// 
        private static void FillAdjustSettings(GuruServicesConfig settings, string[] lines, ref int index)
        {
            if(settings.adjust_settings == null) settings.adjust_settings = new GuruAdjustSettings();
            string[] list = null;
            string line = lines[index];
            bool pass = false;
            List events = new List(40);
            
            while (!lines[index].StartsWith(K_FB_SETTINGS))
            {
                line = lines[index];
                if (!IsInvalidLine(line))
                {
                    if (line.StartsWith("app_token"))
                    {
                        list = GetStringArray(line, 1, 2);
                        settings.adjust_settings.app_token = list;
                    }
                    else
                    {
                        list = GetStringArray(line, 0, 3);
                        pass = list != null && !string.IsNullOrEmpty(list[0]) 
                                            && (!string.IsNullOrEmpty(list[1]) || !string.IsNullOrEmpty(list[2]));
                        if( pass) events.Add(string.Join(",", list));
                    }
                }
                index++;
            }
            settings.adjust_settings.events = events.ToArray();
            index--;
        }
        
        private static void FillFacebookSettings(GuruServicesConfig settings, string[] lines, ref int index)
        {
            string value = "";
            if(settings.fb_settings == null) settings.fb_settings = new GuruFbSettings();
            var line = "";
            while (!lines[index].StartsWith(K_AD_SETTINGS))
            {
                line = lines[index];
                if (!IsInvalidLine(line))
                {
                    // 拾取值和注入
                    if (GetValue(line, "fb_app_id", out value))
                    {
                        settings.fb_settings.fb_app_id = value;
                    }
                    else if (GetValue(line, "fb_client_token", out value))
                    {
                        settings.fb_settings.fb_client_token = value;
                    }
                }
                index++;
            }
            
            index--;
        }
        
        private static void FillAdSettings(GuruServicesConfig settings, string[] lines, ref int index)
        {
            string value = "";
            if(settings.ad_settings == null) settings.ad_settings = new GuruAdSettings();
            
            
            var line = lines[index];
            // SDK Key
           
            string[] max_ids_android = new string[3];
            string[] max_ids_ios = new string[3];
            string[] amazon_ids_android = new string[4];
            string[] amazon_ids_ios = new string[4];
            string[] pubmatic_ids_android = new string[3];
            string[] pubmatic_ids_ios = new string[3];
            string[] moloco_ids_android = new string[3];
            string[] moloco_ids_ios = new string[3];
            string[] tradplus_ids_android = new string[3];
            string[] tradplus_ids_ios = new string[3];
            
            
            //------- 开始记录广告配置;
            string[] arr;
            while (!lines[index].StartsWith(K_IAP_SETTINGS))
            {
                line = lines[index];
                
                if (GetValue(line, "sdk_key", out value))
                {
                    settings.ad_settings.sdk_key = value;
                }
                else if (line.StartsWith("admob_app_id"))
                {
                    settings.ad_settings.admob_app_id = GetStringArray(line, 1, 2);
                }
                else if (line.StartsWith("max_bads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    max_ids_android[0] = arr[0];
                    max_ids_ios[0] = arr[1];
                }
                else if (line.StartsWith("max_iads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    max_ids_android[1] = arr[0];
                    max_ids_ios[1] = arr[1];
                }
                else if (line.StartsWith("max_rads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    max_ids_android[2] = arr[0];
                    max_ids_ios[2] = arr[1];
                }
                else if (line.StartsWith("amazon_app_id"))
                {
                    arr = GetStringArray(line, 1, 2);
                    amazon_ids_android[0] = arr[0];
                    amazon_ids_ios[0] = arr[1];
                }
                else if (line.StartsWith("amazon_bads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    amazon_ids_android[1] = arr[0];
                    amazon_ids_ios[1] = arr[1];
                }
                else if (line.StartsWith("amazon_iads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    amazon_ids_android[2] = arr[0];
                    amazon_ids_ios[2] = arr[1];
                }
                else if (line.StartsWith("amazon_rads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    amazon_ids_android[3] = arr[0];
                    amazon_ids_ios[3] = arr[1];
                }
                else if (line.StartsWith("pubmatic_bads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    pubmatic_ids_android[0] = arr[0];
                    pubmatic_ids_ios[0] = arr[1];
                }
                else if (line.StartsWith("pubmatic_iads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    pubmatic_ids_android[1] = arr[0];
                    pubmatic_ids_ios[1] = arr[1];
                }
                else if (line.StartsWith("pubmatic_rads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    pubmatic_ids_android[2] = arr[0];
                    pubmatic_ids_ios[2] = arr[1];
                }
                else if (line.StartsWith("moloco_bads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    moloco_ids_android[0] = arr[0];
                    moloco_ids_ios[0] = arr[1];
                }
                else if (line.StartsWith("moloco_iads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    moloco_ids_android[1] = arr[0];
                    moloco_ids_ios[1] = arr[1];
                }
                else if (line.StartsWith("moloco_rads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    moloco_ids_android[2] = arr[0];
                    moloco_ids_ios[2] = arr[1];
                }
                else if (line.StartsWith("tradplus_bads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    tradplus_ids_android[0] = arr[0];
                    tradplus_ids_ios[0] = arr[1];
                }
                else if (line.StartsWith("tradplus_iads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    tradplus_ids_android[1] = arr[0];
                    tradplus_ids_ios[1] = arr[1];
                }
                else if (line.StartsWith("tradplus_rads"))
                {
                    arr = GetStringArray(line, 1, 2);
                    tradplus_ids_android[2] = arr[0];
                    tradplus_ids_ios[2] = arr[1];
                }
                index++;
            }
            
            //-------- Fill all data -----------
            settings.ad_settings.max_ids_android = max_ids_android;
            settings.ad_settings.max_ids_ios = max_ids_ios;
            settings.ad_settings.amazon_ids_android = amazon_ids_android;
            settings.ad_settings.amazon_ids_ios = amazon_ids_ios;
            settings.ad_settings.pubmatic_ids_android = pubmatic_ids_android;
            settings.ad_settings.pubmatic_ids_ios = pubmatic_ids_ios;
            settings.ad_settings.moloco_ids_android = moloco_ids_android;
            settings.ad_settings.moloco_ids_ios = moloco_ids_ios;
            settings.ad_settings.tradplus_ids_android = tradplus_ids_android;
            settings.ad_settings.tradplus_ids_ios = tradplus_ids_ios;
            
            index--;
        }
        
        private static void FillProducts(GuruServicesConfig settings, string[] lines, ref int index)
        {
            string line = "";
            List iaps = new List(30);
            
            string[] arr;
            while (index < lines.Length)
            {
                line = lines[index];
                if(IsInvalidLine(line)) continue;
                arr = GetStringArray(line, 0, 7);
                if(string.IsNullOrEmpty(arr[5])) arr[5] = "Store";
                if(string.IsNullOrEmpty(arr[6])) arr[6] = "0";
                iaps.Add(string.Join("," , arr));
                index++;
            }
            settings.products = iaps.ToArray();
            index--;
        }
    
        
        #endregion
        #region Utils
        
        private static bool GetBool(string value)
        {
            return value.ToLower() == "true" || value == "1";
        }
        
        private static int GetInt(string value)
        {
            int val = 0;
            int.TryParse(value, out val);
            return val;
        }
        
        private static double GetDouble(string value)
        {
            double val = 0;
            double.TryParse(value, out val);
            return val;
        }
        private static bool IsInvalidLine(string line)
        {
            return string.IsNullOrEmpty(line) || line.StartsWith(K_SPLITTER_TAB.ToString());
        }
        private static bool GetValue(string line, string key, out string value)
        {
            value = ""; // default  
            if (line.StartsWith(key))
            {
                value = line.Split(K_SPLITTER_TAB)[1];
                if (string.IsNullOrEmpty(value)) value = "empty";
                return true;
            }
            return false;
        }
        private static string[] GetStringArray(string line, int startIndex = 0, int length = 0, char spliter = K_SPLITTER_TAB)
        {
            if (IsInvalidLine(line)) return null;
            
            var raw = line.Split(spliter);
            if (length == 0) length = raw.Length;
            
            var a = new List(length);
            for (int i = startIndex; i < length + startIndex; i++)
            {
                if (i < raw.Length)
                {
                    a.Add(raw[i]);
                }
                else
                {
                    a.Add("");
                }
            }
            return a.ToArray();
        }
        #endregion
        
        #region Menu Items
#if GURU_SDK_DEV
        [MenuItem("Tools/Export Guru Service", false, 0 )]
#endif
        private static void ExportJsonFile()
        {
            string saveDir = Path.GetFullPath($"{Application.dataPath}/../output");
            string saveFile = Path.Combine(saveDir,$"guru-service____{DateTime.Now:yyyy-M-d-HH-mm}.json");
            
            if(!Directory.Exists(saveDir)) Directory.CreateDirectory(saveDir);
            
            string searchPath = "~/Downloads/";
            string tsv = EditorUtility.OpenFilePanel("Load Guru Service TSV", searchPath, ".tsv");
            if (!string.IsNullOrEmpty(tsv))
            {
                GuruServiceConverterHelper.ConvertFromTSV(tsv, saveFile);
            }
        }
        #endregion
        
    }
}