using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using System;
using System.Security.Cryptography;
using System.Text;
using UnityEngine.Events;

public class Login : MonoBehaviour {

    public GameObject username;
    public GameObject password;

    public Button loginButton;
    public Button SwedishButton;
    public Button EnglishButton;

    public Toggle keepSignedIn;

    public Text errorText;

    private string Username;
    private string Password;
    private string loginUrl = "http://nordh.xyz/narKampen/dbFiles/Login.php?";
    private Color errorColor;
    private EventSystem system;

    private Firebase.Auth.FirebaseAuth auth;

    [Serializable]
    public class User {
        public string userId;
        public string pass;
        public string salt;
    }

    private void CheckFirebaseGoogleDependencies() {
        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
            var dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available) {
                // Create and hold a reference to your FirebaseApp,
                // where app is a Firebase.FirebaseApp property of your application class.
                //   app = Firebase.FirebaseApp.DefaultInstance;

                // Set a flag here to indicate whether Firebase is ready to use by your app.
            } else {
                UnityEngine.Debug.LogError(System.String.Format(
                  "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
                // Firebase Unity SDK is not safe to use here.
            }
        });
    }

    private void Start() {
        // CheckFirebaseGoogleDependencies();
        if (Database.Instance.IsKeepSignedIn()) {
            SceneManager.LoadScene("MainMenu");
        }
        loginButton.onClick.AddListener(loginAction);
        errorColor = errorText.color;
        system = EventSystem.current;

        SwedishButton.onClick.AddListener(() => SwitchLanguage(0));
        EnglishButton.onClick.AddListener(() => SwitchLanguage(1));
        auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
    }

    private void SwitchLanguage(int langId) {
        LocalizationManager.Instance.currentLanguageID = langId;
        TextLocalization[] texts = FindObjectsOfType(typeof(TextLocalization)) as TextLocalization[];
        foreach (TextLocalization tl in texts) {
            tl.UpdateText();
        }

        InputFieldLocalization[] inputFields = FindObjectsOfType(typeof(InputFieldLocalization)) as InputFieldLocalization[];
        foreach (InputFieldLocalization ifl in inputFields) {
            ifl.UpdateText();
        }

        ButtonLocalization[] buttonLocale = FindObjectsOfType(typeof(ButtonLocalization)) as ButtonLocalization[];
        foreach (ButtonLocalization bl in buttonLocale) {
            bl.UpdateText();
        }
    }

    private void Update() {
        Username = username.GetComponent<InputField>().text;
        Password = password.GetComponent<InputField>().text;

        if (Input.GetKeyDown(KeyCode.Tab)) {
            Selectable next = system.currentSelectedGameObject.GetComponent<Selectable>().FindSelectableOnDown();

            if (next != null) {

                InputField inputfield = next.GetComponent<InputField>();
                if (inputfield != null) inputfield.OnPointerClick(new PointerEventData(system));

                system.SetSelectedGameObject(next.gameObject, new BaseEventData(system));
            }
        }
    }

    void loginAction() {
        string errorMessage = "";
        if (Username == "") {
            errorMessage = LocalizationManager.Instance.GetText("REGISTER_ERROR_USERNAME_EMPTY");
        }
        if (Password == "") {
            if (errorMessage != "") {
                errorMessage += "\n";
            }
            errorMessage += LocalizationManager.Instance.GetText("REGISTER_ERROR_PASSWORD_EMPTY");
        }

        if (errorMessage == "") {
            errorColor.a = 0;

            firebaseLogin(Username, Password);

            StartCoroutine(loginCall());
        } else {
            errorText.text = errorMessage;
            errorColor.a = 1;
        }
        errorText.color = errorColor;
    }

    private void firebaseLogin(string email, string password) {
        auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task => {
            if (task.IsCanceled) {
                Debug.LogError("SignInWithEmailAndPasswordAsync was canceled.");
                return;
            }
            if (task.IsFaulted) {
                Debug.LogError("SignInWithEmailAndPasswordAsync encountered an error: " + task.Exception);
                return;
            }

            Firebase.Auth.FirebaseUser newUser = task.Result;
            Debug.LogFormat("User signed in successfully: {0} ({1})",
                newUser.DisplayName, newUser.UserId);
        });
    }

    IEnumerator loginCall() {
        string postUrl = loginUrl + "name=" + UnityWebRequest.EscapeURL(Username);

        UnityWebRequest www = UnityWebRequest.Get(postUrl);
        yield return www.SendWebRequest();

        if (www.error != null) {
            errorText.text = "There was an error logging in " + www.error;
        }
        string result = www.downloadHandler.text;

        User u = new User();
        if (!result.Equals("")) {
            JsonUtility.FromJsonOverwrite(result, u);
        }

        if (!u.userId.Equals("")) {
            byte[] pwd = Encoding.UTF8.GetBytes(u.salt + Password);
            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
            string pass = Convert.ToBase64String(sha1.ComputeHash(pwd));
            if (pass.Equals(u.pass)) {
                errorColor.a = 0;
                errorText.color = errorColor;
                Int32.TryParse(u.userId, out int userId);
                Database.Instance.KeepSignedIn(Username, userId, keepSignedIn.isOn);
                SceneManager.LoadScene("MainMenu");
            } else {
                errorText.text = LocalizationManager.Instance.GetText("LOGIN_WRONG_USERNAME_PASSWORD");
                errorColor.a = 1;
                errorText.color = errorColor;
            }
        } else {
            errorText.text = LocalizationManager.Instance.GetText("LOGIN_USER_NOT_FOUND");
            errorColor.a = 1;
            errorText.color = errorColor;
        }
    }
}
