using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;
using UnityEngine.UI;

public class PlayfabLogin : MonoBehaviour {

    public InputField emailField;
    public InputField passwordField;
    public InputField passwordConfirmField;

    public MenuNavigationController controller;

    public GameObject alertPopup;

    const int minPassLength = 6;
    const int maxPassLength = 100;

    System.Text.RegularExpressions.Regex mailValidator = new System.Text.RegularExpressions.Regex(@"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|
        [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|
        ((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|
        [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*
        (((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|
        [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|
        [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|
        [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|
        [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$");

    // Use this for initialization
    void Start () {
        if (!controller)
            GetComponent<MenuNavigationController>();

        if (!emailField)
            return;

        emailField.characterValidation = InputField.CharacterValidation.EmailAddress;
    }

    public void AttemptLogin() {
        if (!emailField || !passwordField)
            return;

        string email = emailField.text;
        string pass = passwordField.text;

        if (!ValidateInput(email, pass))
            return;

        var request = new LoginWithEmailAddressRequest { Email = email, Password = pass, TitleId = PlayFabSettings.TitleId };
        PlayFabClientAPI.LoginWithEmailAddress(request, OnLoginSuccess, OnClientApiCallFailure);
    }
	
	void OnLoginSuccess(LoginResult result) {
        print("You made your API call!");

        if (controller)
            controller.LoginToMenu();
    }

    void OnClientApiCallFailure(PlayFabError error) {
        ColorBlock cb;
        switch (error.Error) {
            // Login With Email Error Codes
            case PlayFabErrorCode.InvalidEmailOrPassword:
                print("Invalid Email or Password");
                MakePopup("Invalid Email or Password");
                break;
            case PlayFabErrorCode.AccountNotFound:
                print("Account Not Found");
                break;
            case PlayFabErrorCode.InvalidTitleId:
                print("Invalid Title ID");
                break;
            case PlayFabErrorCode.RequestViewConstraintParamsNotAllowed:
                print("Request View Constraint Params Not Allowed");
                break;

            // Register PlayFab User Error Codes
            case PlayFabErrorCode.EmailAddressNotAvailable:
                print("Email Address not available");
                cb = emailField.colors;
                cb.normalColor = Color.red;
                emailField.colors = cb;
                break;
            case PlayFabErrorCode.InvalidEmailAddress:
                print("Invalid Email Address");
                cb = emailField.colors;
                cb.normalColor = Color.red;
                emailField.colors = cb;
                break;
            case PlayFabErrorCode.InvalidPartnerResponse:
                print("Invalid Partner Response");
                break;
            case PlayFabErrorCode.InvalidPassword:
                print("Invalid Password");
                cb = passwordField.colors;
                cb.normalColor = Color.red;
                passwordField.colors = cb;
                break;
            case PlayFabErrorCode.InvalidUsername:
                print("Invalid Username");
                break;
            case PlayFabErrorCode.NameNotAvailable:
                print("Name not available");
                break;
            case PlayFabErrorCode.ProfaneDisplayName:
                print("Profane Name");
                break;
            case PlayFabErrorCode.UsernameNotAvailable:
                print("Username not available");
                break;

            default:
                Debug.LogWarning("Something went wrong with your API call.");
                Debug.LogError("Here's some debug information:");
                Debug.LogError(error.GenerateErrorReport());
                break;
        }
    }

    public void AttemptCreateAccount() {

        if (!emailField || !passwordConfirmField || !passwordField)
            return;

        string email = emailField.text;
        string pass = passwordField.text;
        string passConfirm = passwordConfirmField.text;

        if (ValidateInput(email, pass, passConfirm))
            return;

        var request = new RegisterPlayFabUserRequest { RequireBothUsernameAndEmail = false, Email = email, Password = pass, TitleId = PlayFabSettings.TitleId };
        PlayFabClientAPI.RegisterPlayFabUser(request, OnRegisterSuccess, OnClientApiCallFailure);
    }

    void OnRegisterSuccess(RegisterPlayFabUserResult result) {
        print("You your API call!");
        print("You also registered a new user: " + result.Username);

        if (controller)
            controller.LoginToMenu();
    }

    bool ValidateInput(string email, string pass, string passConfirm = "") {

        if(passConfirm != "") {
            if (string.Compare(pass, passConfirm) != 0) {
                print("Passwords do not match");
                return  false;
            }
        }

        if (pass.Length < minPassLength || pass.Length > maxPassLength) {
            print("Password needs to be between 6 and 100 characters long");
            return false;
        }

        if (!mailValidator.IsMatch(email)) {
            print("Invalid Email address");
            return false;
        }

        return true;
    }

    void MakePopup(string text) {
        alertPopup.SetActive(true);
        alertPopup.GetComponent<Popup>().SetMessageText(text);
    }
}
