using _Combo;
using _Core;
using Seayoo.ComboSDK.Windows.Store.Networking.Model;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace Seayoo.ComboSDK.Windows.Store.Networking
{
    internal static class SeayooStoreClient
    {
        private static string gameId = "";
        private static string distro = "";
        private static string publishableKey = "";
        private static string endpoint = "";
        private static string unitySdkVersion = "";
        private static string unityVersion = "";
        private static string version = "/v1";
        public static void Setup(StoreParameters storeParameters)
        {
            gameId = storeParameters.GameId;
            distro = storeParameters.Distro;
            publishableKey = storeParameters.PublishableKey;
            endpoint = storeParameters.Endpoint;
            unitySdkVersion = storeParameters.UnitySdkVersion;
            unityVersion = storeParameters.UnityVersion;
        }

        public static void RequestPayment(string orderToken, string paymentMethod, Action<SeatooStoreResponse<RequestPayment.Response>> onResp, Action<InternalError> onError)
        {
            var request = new RequestPayment.Request
            {
                orderToken = orderToken,
                paymentMethod = paymentMethod,
            };
            var url = RequestUrl("/client/request-payment");

             HttpRequest.Post(
                new HttpRequestOptions
                {
                    auth = new HttpBasicAuth(gameId, publishableKey),
                    url = url,
                    headers = Headers(),
                    body = request,
                }, httpResp =>
                {
                    if (httpResp.IsSuccess) Log.D(httpResp.ToString());
                    else Log.D(httpResp.ToString()); 
                    
                    var resp = SeatooStoreResponse<RequestPayment.Response>.CreateResponse(httpResp, url);

                    if(resp.IsSuccess)
                    {
                        onResp.Invoke(resp);
                    }
                    else
                    {
                        HandleError("RequestPayment", resp.Error);
                        onError(resp.Error);
                    }
                });
        }

        public static void QueryPayment(string orderToken, string paymentMethod, Action<SeatooStoreResponse<QueryPayment.Response>> onResp, Action<InternalError> onError)
        {
            var request = new QueryPayment.Request
            {
                orderToken = orderToken,
                paymentMethod = paymentMethod,
            };
            var url = RequestUrl("/client/query-payment");

            HttpRequest.Post(
                new HttpRequestOptions
                {
                    auth = new HttpBasicAuth(gameId, publishableKey),
                    url = url,
                    headers = Headers(),
                    body = request,
                }, httpResp =>
                {
                    if (httpResp.IsSuccess) Log.D(httpResp.ToString());
                    else Log.D(httpResp.ToString()); 

                     
                    var resp = SeatooStoreResponse<QueryPayment.Response>.CreateResponse(httpResp, url);

                    if(resp.IsSuccess)
                    {
                        onResp.Invoke(resp);
                    }
                    else
                    {
                        HandleError("QueryPayment", resp.Error, false);
                        onError(resp.Error);
                    }
                });
        }

        private static string RequestUrl(string urlPath)
        {
            return $"{endpoint}{version}{urlPath}";
        }

        private static Dictionary<string, string> Headers()
        {
            return new Dictionary<string, string>()
            {
                {"Accept-Language", I18n.GetLanguageCode()},
                {"x-timestamp-unix", Utils.UnixTimeStamp()},
                {"x-game-distro", distro},
                {"x-game-platform", "windows"},
                {"x-sdk-version", $"combo-sdk-windows/{Version.Version.SDKVersion} combo-sdk-unity/{unitySdkVersion} (unity/{unityVersion})"},
                {"x-bundle-id", string.IsNullOrEmpty(Application.identifier) ? gameId : Application.identifier },
                {"x-bundle-version", Application.version},
                {"x-device-id", Device.UUID},
                {"x-device-name", HttpUtils.UrlEncode(_Core.Device.DeviceName)},
                {"x-device-model", HttpUtils.UrlEncode(_Core.Device.Model)},
                {"x-os-type", _Core.Device.OSType},
                {"x-os-version", _Core.Device.OSVersion}
            };
        }        
        
        private static void HandleError(string operationName, InternalError error, bool isShowToast = true)
        {
            var serverError = ErrorExtensions.Convert<ServerError>(error);
            var networkError = ErrorExtensions.Convert<NetworkError>(error);
            if(networkError != null)
            {
                if(isShowToast)
                {
                    UIController.Instance.ShowToast(I18n.T("network_error"));
                }
                Log.I($"Failed to {operationName}, status_code = NetworkError, error = {error.Message}");
            }
            if(serverError != null)
            {
                if(isShowToast)
                {
                    UIController.Instance.ShowToast(serverError.ErrorMsg);
                }
                Log.I($"Failed to {operationName}, status_code = ServerError, error = {serverError.Error}, error_message = {serverError.ErrorMsg}");

            }
        }
    }
}