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

public class Register : MonoBehaviour {
    public GameObject username;
    public GameObject password;
    public GameObject email;
    public Text errorText;

    public Button registerButton;

    private string Username;
    private string Password;
    private string Email;
    private string form;

    private string registerUserUrl = "http://nordh.xyz/narKampen/dbFiles/Register.php?";

    private Color errorColor;

    private EventSystem system;

    // Start is called before the first frame update
    void Start() {
        registerButton.onClick.AddListener(RegisterAction);
        system = EventSystem.current;
        errorColor = errorText.color;
    }

    // Update is called once per frame
    void Update() {
        Username = username.GetComponent<InputField>().text;
        Password = password.GetComponent<InputField>().text;
        Email = email.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));  //if it's an input field, also set the text caret

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

    void RegisterAction() {
        string errorMessage = "";
        if (Username == "" || Username.Length < 3) {
            errorMessage = LocalizationManager.Instance.GetText("REGISTER_ERROR_USERNAME_EMPTY");
        }
        if (Password == "") {
            if (errorMessage != "") {
                errorMessage += "\n";
            }
            errorMessage += LocalizationManager.Instance.GetText("REGISTER_ERROR_PASSWORD_EMPTY");
        }
        if (Password.Length < 6) {
            if (errorMessage != "") {
                errorMessage += "\n";
            }
            errorMessage += LocalizationManager.Instance.GetText("REGISTER_ERROR_PASSWORD_TO_SHORT");
        }
        if (Email == "") {
            if (errorMessage != "") {
                errorMessage += "\n";
            }
            errorMessage += LocalizationManager.Instance.GetText("REGISTER_ERROR_EMAIL_EMPTY");
        }


        if (errorMessage != "") {
            errorText.text = errorMessage;
            errorColor.a = 1;
        } else {
            errorColor.a = 0;

            StartCoroutine(RegisterUser());
        }
        errorText.color = errorColor;
    }

    IEnumerator RegisterUser() {
        // TODO register user at server, check for already in use for username and email.

        // TODO - Save OS and device id
        string deviceId = SystemInfo.deviceUniqueIdentifier;
        string os = SystemInfo.operatingSystem;

        string salt = GetSalt();
        byte[] pwd = Encoding.UTF8.GetBytes(salt + Password);
        SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
        byte[] pass = sha1.ComputeHash(pwd);

        string postUrl = registerUserUrl + "name=" + UnityWebRequest.EscapeURL(Username) + "&password=" + UnityWebRequest.EscapeURL(Convert.ToBase64String(pass)) + "&email=" + UnityWebRequest.EscapeURL(Email) + "&s=" + UnityWebRequest.EscapeURL(salt) + "&did=" + deviceId + "&os=" + UnityWebRequest.EscapeURL(os);
        Debug.Log(postUrl);
        UnityWebRequest www = UnityWebRequest.Get(postUrl);
        yield return www.SendWebRequest();

        if (www.error != null) {
            errorText.text = LocalizationManager.Instance.GetText("REGISTER_ERROR_CONNECTION_FAIL");
            errorColor.a = 1;
            errorText.color = errorColor;
        } else {

            string result = www.downloadHandler.text;
            if (int.TryParse(www.downloadHandler.text, out int userId)) {
                errorColor.a = 0;
                errorText.color = errorColor;
                Database.Instance.KeepSignedIn(Username, userId, false);
                SceneManager.LoadScene("MainMenu");
            } else {
                errorText.text = LocalizationManager.Instance.GetText("REGISTER_ERROR_USER_PASS_ALREADY_IN_USE");
                errorColor.a = 1;
                errorText.color = errorColor;
            }
        }
    }

    private string GetSalt() {
        RNGCryptoServiceProvider rnd = new RNGCryptoServiceProvider();

        int saltLength = 32;
        byte[] salt = new byte[saltLength];

        rnd.GetNonZeroBytes(salt);

        return Convert.ToBase64String(salt);
    }
}
