using System;
using System.Collections.Generic;
using _Combo;
using _Core;
using UnityEngine;

namespace Seayoo.ComboSDK.Windows
{
    public class ComboSDKWindows : Singleton<ComboSDKWindows>
    {
        private static ComboSDKWindows _instance;
        private static object _lock = new object();

        public ComboSDKWindows()
        {
            
        }

        #region API
        public void Setup(ComboSDKSetupOptions options, Action<ComboSDKResult<ComboSDKSetupResult>> action)
        {
            Log.I("ComboSDKWindows.Setup");
            Combo.Instance.Setup(options.ToSetupOptions(), result =>
            {
                if (result.IsSuccess)
                {
                    action.Invoke(ComboSDKResult<ComboSDKSetupResult>.Success(new ComboSDKSetupResult()));
                }
                else
                {
                    action.Invoke(ComboSDKResult<ComboSDKSetupResult>.Failure(ComboSDKError.Create(result.Error)));
                }
            });
        }

        public void Login(Action<ComboSDKResult<ComboSDKLoginResult>> action)
        {
            Combo.Instance.Login(result => {
                try
                {
                    var user = result.Data;
                    action.Invoke(ComboSDKResult<ComboSDKLoginResult>.Success(new ComboSDKLoginResult
                    {
                        loginInfo = new ComboSDKLoginInfo
                        {
                            comboId = user.comboId,
                            identityToken = user.identityToken
                        }
                    }));
                } catch (InternalError e)
                {
                    action.Invoke(ComboSDKResult<ComboSDKLoginResult>.Failure(ComboSDKError.Create(e)));
                }
            });
        }

        public void Logout(Action<ComboSDKResult<ComboSDKLogoutResult>> action)
        {
            Combo.Instance.Logout(result => {
                try
                {
                    var user = result.Data;
                    action.Invoke(ComboSDKResult<ComboSDKLogoutResult>.Success(new ComboSDKLogoutResult
                    {
                        comboId = user.comboId
                    }));
                } catch (InternalError e)
                {
                    action.Invoke(ComboSDKResult<ComboSDKLogoutResult>.Failure(ComboSDKError.Create(e)));
                }
            });
        }

        public void KickOut(Action<ComboSDKResult<ComboSDKKickOutResult>> action)
        {
            Combo.Instance.KickOut(result => {
                try
                {
                    action.Invoke(ComboSDKResult<ComboSDKKickOutResult>.Success(new ComboSDKKickOutResult
                    {
                        shouldExit = result.Data
                    }));
                } catch (InternalError e)
                {
                    action.Invoke(ComboSDKResult<ComboSDKKickOutResult>.Failure(ComboSDKError.Create(e)));
                }
            });
        }

        public ComboSDKLoginInfo GetLoginInfo()
        {
            var user = Combo.Instance.GetLoginInfo();
            return new ComboSDKLoginInfo
            {
                comboId = user.comboId,
                identityToken = user.identityToken,
                idp = user.idp
            };
        }

        public Dictionary<string, string> GetParameters() {
            return Combo.Instance.GetParameters();
        }

        public string GetDeviceId() {
            return SystemInfo.deviceUniqueIdentifier;
        }

        public string GetVersion()
        {
            return Version.Version.SDKVersion;
        }

        public string GetDistro()
        {
            return Combo.Instance.GetDistro();
        }

        public void Purchase(string orderToken, Action<ComboSDKResult<ComboSDKPaymentResult>> action)
        {
            Combo.Instance.Purchase(orderToken, result =>{
                try
                {
                    action.Invoke(ComboSDKResult<ComboSDKPaymentResult>.Success(new ComboSDKPaymentResult
                    {
                        orderId = result.Data.orderId,
                    }));
                } catch (InternalError e)
                {
                    action.Invoke(ComboSDKResult<ComboSDKPaymentResult>.Failure(ComboSDKError.Create(e)));
                }
            });
        }

        public bool IsFeatureAvailable(Feature feature)
        {
            return Combo.Instance.IsFeatureAvailable(feature);
        }

        public void GetDownloadUrl(Action<ComboSDKResult<ComboSDKDownloadUrlResult>> action)
        {
            Combo.Instance.GetDownloadUrl(result =>{
                try
                {
                    action.Invoke(ComboSDKResult<ComboSDKDownloadUrlResult>.Success(new ComboSDKDownloadUrlResult
                    {
                        downloadUrl = result.Data.downloadUrl,
                    }));
                } catch (InternalError e)
                {
                    action.Invoke(ComboSDKResult<ComboSDKDownloadUrlResult>.Failure(ComboSDKError.Create(e)));
                }
            });
        }

        public LanguagePreference GetLanguagePreference()
        {
            return Combo.Instance.GetLanguagePreference();
        }

        public void SetLanguagePreference(LanguagePreference language)
        {
            Combo.Instance.SetLanguagePreference(language);
        }

        public string GetLanguageCode()
        {
            return Combo.Instance.GetLanguageCode();
        }

#if UNITY_STANDALONE
        public void ContactSupport()
        {
            Combo.Instance.ContactSupport();
        }

        public void OpenGameUrl(GameUrl gameUrl)
        {
            Combo.Instance.OpenGameUrl(gameUrl);
        }

        public void OpenShortLink(string shortLink, Dictionary<string, string> gameData, Action<ComboSDKResult<OpenShortLinkResult>> action)
        {
            Combo.Instance.OpenShortLink(shortLink, gameData, result =>{
                if(result.IsSuccess)
                {
                    action.Invoke(ComboSDKResult<OpenShortLinkResult>.Success(new OpenShortLinkResult()));
                }
                else
                {
                    action.Invoke(ComboSDKResult<OpenShortLinkResult>.Failure(ComboSDKError.Create(result.Error)));
                }
            });
        }

        public void CheckAnnouncements(ComboSDKCheckAnnouncementsOptions opts, Action<ComboSDKResult<ComboSDKCheckAnnouncementsResult>> action)
        {
            Combo.Instance.CheckAnnouncements(opts, result =>{
                if(result.IsSuccess)
                {
                    action.Invoke(ComboSDKResult<ComboSDKCheckAnnouncementsResult>.Success(new ComboSDKCheckAnnouncementsResult()
                    {
                        NewAnnouncementsAvailable = result.Data.NewAnnouncementsAvailable
                    }));
                }
                else
                {
                    action.Invoke(ComboSDKResult<ComboSDKCheckAnnouncementsResult>.Failure(ComboSDKError.Create(result.Error)));
                }
            });
        }

        public void OpenAnnouncements(ComboSDKOpenAnnouncementsOptions opts, Action<ComboSDKResult<ComboSDKOpenAnnouncementsResult>> action)
        {
            Combo.Instance.OpenAnnouncements(opts, result =>{
                if(result.IsSuccess)
                {
                    action.Invoke(ComboSDKResult<ComboSDKOpenAnnouncementsResult>.Success(new ComboSDKOpenAnnouncementsResult()));
                }
                else
                {
                    action.Invoke(ComboSDKResult<ComboSDKOpenAnnouncementsResult>.Failure(ComboSDKError.Create(result.Error)));
                }
            });
        }

        public void Complain(ComplainOptions opts, Action<ComboSDKResult<ComplainResult>> action)
        {
            Combo.Instance.Complain(opts, result =>{
                if(result.IsSuccess)
                {
                    action.Invoke(ComboSDKResult<ComplainResult>.Success(new ComplainResult()));
                }
                else
                {
                    action.Invoke(ComboSDKResult<ComplainResult>.Failure(ComboSDKError.Create(result.Error)));
                }
            });
        }

        public void RedeemGiftCode(RedeemGiftCodeOptions opts, Action<ComboSDKResult<RedeemGiftCodeResult>> action)
        {
            Combo.Instance.RedeemGiftCode(opts, result =>{
                if(result.IsSuccess)
                {
                    action.Invoke(ComboSDKResult<RedeemGiftCodeResult>.Success(new RedeemGiftCodeResult()));
                }
                else
                {
                    action.Invoke(ComboSDKResult<RedeemGiftCodeResult>.Failure(ComboSDKError.Create(result.Error)));
                }
            });
        }
#endif
        #endregion
    }
}
