﻿namespace Stove.StoveSDK
{
    using System;
    using System.Collections.Generic;
    using UnityEngine;

    /**
     * Stove's account information
     * @since 2.0.0
     */
    public class AccessToken
    {
        /**
         * To determine if you are a normal user, you can verify with token.
         *
         * Validate using server API.
         *
         * By default, the token expires at 6 hours.
         *
         * The SDK will automatically renew when 80% of the expiration time is reached.
         *
         * Don't cache tokens. Tokens may change.
         * @since 2.0.0
         */
        public string Token { get; }

        private string RefreshToken { get; set; }
        private long ExpiresIn { get; set; }

        /**
         * User information.
         * @since 2.0.0.
         */
        public User User { get; }

        private string RecallToken { get; set; }

        /**
         * Renew token.
         *
         * By default, the token expires at 6 hours.
         *
         * The SDK will automatically renew when 80% of the expiration time is reached.
         * @param action Refresh Result.
         * @since 2.0.0
         */
        public void Refresh(Action<Result> action)
        {
            Debug.Log("AccessToken.Refresh Action(" + action + ")");
            string identifier = StoveSDK.Instance.AddAction(payload =>
            {
                Result result = new Result(payload["result"] as Dictionary<string, object>);
                Debug.Log("AccessToken.Refresh Result(" + result + ")");
                action.Invoke(result);
            });
            AuthInterface.Refresh(identifier);
        }

        public AccessToken(string token, User user)
        {
            Token = token;
            User = user;
        }

        /**
         * Dictionary serialization.
         * @since 2.2.0
         */
        public Dictionary<string, object> ToDictionary()
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            dictionary.Add("token", Token);

#if UNITY_ANDROID
            dictionary.Add("refresh_token", RefreshToken);
            dictionary.Add("expires_in", ExpiresIn);
#endif

#if UNITY_IOS
            dictionary.Add("refreshToken", RefreshToken);
            dictionary.Add("expiresIn", ExpiresIn);
#endif


            dictionary.Add("user", User.ToDictionary());
            
            dictionary.Add("recall_token", RecallToken);

            return dictionary;
        }

        /**
         * Dictionary deserialization.
         * @since 2.0.0
         */
        public AccessToken(Dictionary<string, object> dictionary)
        {
            if (dictionary.ContainsKey("token"))
            {
                Token = dictionary["token"] as string;
            }
            else
            {
                Token = "";
            }
            

#if UNITY_ANDROID
            RefreshToken = dictionary["refresh_token"] as string;
            ExpiresIn = Convert.ToInt64(dictionary["expires_in"]);
#endif

#if UNITY_IOS
            if (dictionary.ContainsKey("refreshToken"))
            {
                RefreshToken = dictionary["refreshToken"] as string;
            }
            else
            {
                RefreshToken = "";
            }

            if (dictionary.ContainsKey("expiresIn"))
            {
                ExpiresIn = Convert.ToInt64(dictionary["expiresIn"]);
            }
            else
            {
                ExpiresIn = 0;
            }
#endif

            if (dictionary.ContainsKey("recall_token"))
            {
                RecallToken = dictionary["recall_token"] as string;
            }
            else
            {
                RecallToken = "";
            }

            if (dictionary.ContainsKey("user"))
            {
                User = new User(dictionary["user"] as Dictionary<string, object>);
            }
            else
            {
                User = new User("", new List<ProviderUser>(), 0, "", false, false, false, false);
            }
        }

        public override string ToString()
        {
            return "AccessToken(Token='" + Token + "', User=" + User + "', RecallToken=" + RecallToken + ")";
        }
    }
}
