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 == "") {
            errorMessage = "Username is obligatory";
        }
        if (Password == "") {
            if (errorMessage != "") {
                errorMessage += "\n";
            }
            errorMessage += "Password is obligatory";
        }
        if (Email == "") {
            if (errorMessage != "") {
                errorMessage += "\n";
            }
            errorMessage += "Email is obligatory";
        }


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

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

    IEnumerator RegisterUser() {
        // register user at server, check for already in use for username and email.
        // TODO - hash+salt password
        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);

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

        if (www.error != null) {
            errorText.text = "There was an error registering this user, try again later";
        }

        string result = www.downloadHandler.text;
        if (int.TryParse(www.downloadHandler.text, out int userId)) {
            errorColor.a = 0;
            errorText.color = errorColor;
            PlayerPrefs.SetInt("UserId", userId);
            SceneManager.LoadScene("MainMenu");
        } else {
            errorText.text = "Failed to register, username/email already exists"; // be more helpful, get message from sever if it is username or email 
            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);
    }
}
