using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Firebase.Auth;
using System.Timers;

namespace BodyshopPartner.Utils
{
    public static class Auth
    {
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        public static FirebaseAuthLink authlink;
        static FirebaseAuthProvider ap = new FirebaseAuthProvider(new FirebaseConfig(Utils.AppMetaData.FirebaseAPIKey)); 
        private static Timer tokenTimer = new Timer();
        private static string U;
        private static string P;

        

        public async static Task<(bool, string)> LoginAsync(string Username, string Password)
        {
            U = Username;
            P = Password;
            try
            {
                authlink = await ap.SignInWithEmailAndPasswordAsync(Username, Password);
                authlink.FirebaseAuthRefreshed += Authlink_FirebaseAuthRefreshed;
                
                logger.Trace("Firebase Auth Token {0}.", authlink.FirebaseToken);
                logger.Trace("Firebase Auth Token expires in {0} seconds.", authlink.ExpiresIn);
                tokenTimer.Interval = (authlink.ExpiresIn - 600) * 1000; //Set the token to refresh 10 minutes before it has to. 
                logger.Trace("Refresh timer interval set to {0}ms", (authlink.ExpiresIn - 600) * 1000);
                tokenTimer.Elapsed += TokenTimer_Tick;
                tokenTimer.Start();

                return (true, null);
            }
            catch (FirebaseAuthException Ex)
            {
                switch (Ex.Reason)
                {
                    case AuthErrorReason.WrongPassword:
                        logger.Error("Incorrect password provided for user.");
                        return (false, Properties.Resources.Error_Login);

                    case AuthErrorReason.UnknownEmailAddress:
                        logger.Error("User does not exist.");
                        return (false, Properties.Resources.Error_Login);
                    case AuthErrorReason.TooManyAttemptsTryLater:
                        logger.Error("Too many attempts logging in.");
                        return (false, Properties.Resources.Error_Login_Attempts);
                    default:
                        logger.Error(Ex, "Unknown error occured while logging in. {0}", Ex.Reason);
                        return (false, Properties.Resources.Error_Login_Unknown);
                }
            }
            catch (Exception Ex)
            {
                logger.Error(Ex, "Unknown error encountered while obtaining auth token.");
                return (false, Properties.Resources.Error_Generic);
            }
        }

        public static async Task Refresh()
        {
            logger.Info("Old Token {0}", authlink.RefreshToken);
            await authlink.GetFreshAuthAsync();
            
            authlink = await ap.RefreshAuthAsync(authlink);
            logger.Info("new Token {0}", authlink.FirebaseToken);
        }

        private static void Authlink_FirebaseAuthRefreshed(object sender, FirebaseAuthEventArgs e)
        {
            logger.Debug("Auth token refreshed!");
            logger.Debug("New token: {0}", e.FirebaseAuth.FirebaseToken);
        }

        private static async Task RefreshToken()
        {
            //Gotta do some stuff now that i got a new token! 
            //Maybe the token auto refreshes? 
            logger.Info("Timer Old Token {0}", authlink.FirebaseToken);
            authlink = await authlink.GetFreshAuthAsync();
            logger.Info("new Token {0}", authlink.FirebaseToken);
            tokenTimer.Stop();
            tokenTimer.Interval = (authlink.ExpiresIn - 600) * 1000; //Set the token to refresh 10 minutes before it has to. 
            tokenTimer.Start();
        }

        private static async void TokenTimer_Tick(object sender, ElapsedEventArgs e)
        {
            await RefreshToken();
        }
    }
}
