#if UNITY_STANDALONE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using _Core;
using Microsoft.Win32;
using Seayoo.ComboSDK.Windows;
using UnityEngine;

namespace _Combo
{
    internal class GamerManager : Singleton<GamerManager>
    {
        private Action<ComboResult<OpenShortLinkResult>> OpenShortLinkAction;
        private string endpoint = "";
        private string gameId = "";
        private string version = "v1";

        private GamerManager() {
            EventSystem.Register(this);
        }

        public void Setup(string gameId)
        {
            this.gameId = gameId;
            endpoint = GlobalParameters.Instance.GameGamerApiEndpoint;
        }

        public void OpenShortLink(string link, Dictionary<string, string> gameData, Action<ComboResult<OpenShortLinkResult>> action)
        {
            OpenShortLinkAction = action;
            
            UIController.Instance.ShowLoading(0.5f);
            ComboClient.OpenShortLink(endpoint, version, link, resp => {
                try
                {
                    var linkInfo = resp.Data;
                    if(!linkInfo.idTokenNotRequired)
                    {
                        if(!IdPManager.Instance.GetUser().IsLogin())
                        {
                            UIController.Instance.HideLoading();
                            var error = new InternalError(I18n.T("login_required_error"));
                            OpenShortLinkAction?.Invoke(ComboResult<OpenShortLinkResult>.CreateFail(error));
                            return;
                        }
                    }
                    if(linkInfo.linkType == "weixin")
                    {
                        if(!IsWeChatInstalled())
                        {
                            UIController.Instance.HideLoading();
                            var error = new InternalError(I18n.T("weixin_not_installed_error"));
                            OpenShortLinkAction?.Invoke(ComboResult<OpenShortLinkResult>.CreateFail(error));
                            return;
                        }
                    }
                    if(gameId == linkInfo.gameId)
                    {
                        GotoLink(link, gameData, linkInfo);
                    }
                    else
                    {
                        UIController.Instance.HideLoading();
                        var invalidArgumentsError = new InvalidArgumentsError("shortLink", link, InvalidArgumentsErrorType.INVALID_SHORT_LINK);
                        var error = new InternalError(I18n.T("short_link_invalid_error"), invalidArgumentsError);
                        OpenShortLinkAction?.Invoke(ComboResult<OpenShortLinkResult>.CreateFail(error));
                    }
                    
                } catch (InternalError e)
                {
                    UIController.Instance.HideLoading();
                    OpenShortLinkAction?.Invoke(ComboResult<OpenShortLinkResult>.CreateFail(e));
                }
            }, (error) =>{
                UIController.Instance.HideLoading();
                OpenShortLinkAction?.Invoke(ComboResult<OpenShortLinkResult>.CreateFail(error));
            });
        }

        public void GotoLink(string link, Dictionary<string, string> gameData, ShortLink.Response response)
        {
            var missingGameData = GetMissingGameData(gameData, response);
            if(missingGameData.Count != 0)
            {
                UIController.Instance.HideLoading();
                var detail = $"Missing: {string.Join(", ", missingGameData)}";
                var invalidArgumentsError = new InvalidArgumentsError("gameData", detail, InvalidArgumentsErrorType.INVALID_GAME_DATA);
                var error = new InternalError(I18n.T("short_link_game_data_error"), invalidArgumentsError);
                OpenShortLinkAction?.Invoke(ComboResult<OpenShortLinkResult>.CreateFail(error));
                return;
            }
            string url = GetUrl(link, response.idTokenNotRequired, gameData);
            UIController.Instance.ShowLoading(0.5f);
            ComboClient.GetGoToLink(endpoint, version, url, resp => {
                if(response.linkType == "winxin")
                {
                    UIController.Instance.HideLoading();
                    Application.OpenURL(resp.Data.webUrl);
                    return;
                }
                if(response.openWith == "browser")
                {
                    UIController.Instance.HideLoading();
                    Application.OpenURL(resp.Data.webUrl);
                }
                else
                {
                    if(response.showNavigationBar)
                    {
                        UIController.Instance.ShowWebView(resp.Data.webUrl, WebViewType.General, 100, 100);
                    }
                    else
                    {
                        UIController.Instance.ShowWebView(resp.Data.webUrl, WebViewType.General, 100, 100, false);
                    }
                }

                var result = new OpenShortLinkResult();
                OpenShortLinkAction?.Invoke(ComboResult<OpenShortLinkResult>.CreateSuccess(result));
            }, (error) => {
                UIController.Instance.HideLoading();
                OpenShortLinkAction?.Invoke(ComboResult<OpenShortLinkResult>.CreateFail(error));
            }); 
        }

        private List<string> GetMissingGameData(Dictionary<string, string> gameData, ShortLink.Response response)
        {
            Dictionary<string, string> nonNullGameData = gameData ?? new Dictionary<string, string>();
            IEnumerable<string> missingKeys = response.requiredGameData.Except(nonNullGameData.Keys);
            return missingKeys.ToList();
        }

        private string GetUrl(string link, bool idTokenNotRequired, Dictionary<string, string> gameData)
        {
            string otherDataStr = "";
            if (!idTokenNotRequired)
            {
                string identityToken = Combo.Instance.GetLoginInfo().identityToken;
                var otherData = new Dictionary<string, string>
                {
                    { "id_token", identityToken }
                };
                otherDataStr = string.Join("&", otherData.Select(kv => $"{kv.Key}={WebUtility.UrlEncode(kv.Value)}"));
            }

            string gameDataStr = string.Join("&", gameData.Select(kv => $"game.{kv.Key}={WebUtility.UrlEncode(kv.Value)}"));
            string languageStr = $"lang={WebUtility.UrlEncode(I18n.GetLanguageCode())}";

            // 拼装 URL 时避免多余的 "&"
            var queryParams = new List<string>();

            if (!string.IsNullOrEmpty(otherDataStr))
            {
                queryParams.Add(otherDataStr);
            }
            if (!string.IsNullOrEmpty(gameDataStr))
            {
                queryParams.Add(gameDataStr);
            }
            queryParams.Add(languageStr);

            string url = $"{link}?{string.Join("&", queryParams)}";
            return url;
        }

        public bool IsWeChatInstalled()
        {
            string[] registryKeyPaths = new[]
            {
                @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
                @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
            };

            foreach (var registryKeyPath in registryKeyPaths)
            {
                using (RegistryKey baseKey = Registry.LocalMachine.OpenSubKey(registryKeyPath))
                {
                    if (baseKey != null)
                    {
                        try
                        {
                            var subKeyNames = baseKey.GetSubKeyNames();
                            foreach (string subKeyName in subKeyNames)
                            {
                                using (RegistryKey subKey = baseKey.OpenSubKey(subKeyName))
                                {
                                    object displayName = subKey?.GetValue("DisplayName");
                                    if (displayName != null && (displayName.ToString().Contains("WeChat") || displayName.ToString().Contains("微信")))
                                    {
                                        return true;
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            UIController.Instance.HideLoading();
                            Log.E(ex.Message);
                        }
                    }
                }
            }
            return false;
        }
    }
}
#endif