using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Bitrix.Components;
using Bitrix.Security;
using System.Collections.Generic;
using System.Configuration.Provider;
using Bitrix.Modules;
using Bitrix.UI;

using Bitrix.Services;
using Bitrix;
using Bitrix.DataTypes;
using Bitrix.Configuration;
using System.Threading;

public partial class RegisterComponent : BXComponent
{
	public bool RequiresQuestionAndAnswer
	{
		get { return BXUserManager.Provider.RequiresQuestionAndAnswer; }
	}

    protected void Page_Load(object sender, EventArgs e)
    {
		Results["CacheMode"] = "None";

		IncludeComponentTemplate();
    }

    public string GetRedirectUrl() 
    {
        string redirectUrl = Request.QueryString["ReturnUrl"];
        if (string.IsNullOrEmpty(redirectUrl))
            redirectUrl = Request.QueryString[BXConfigurationUtility.Constants.BackUrl];
        if (string.IsNullOrEmpty(redirectUrl))
            redirectUrl = Parameters.Get<string>("RedirectUrl");
        if (string.IsNullOrEmpty(redirectUrl))
            redirectUrl = "~/";
        return redirectUrl;
    }

	public FieldMode FirstNameFieldMode
	{
		get
		{
			return GetFieldMode(Parameters.GetString("FirstNameFieldMode"));
		}
	}
	public FieldMode LastNameFieldMode
	{
		get
		{
			return GetFieldMode(Parameters.GetString("LastNameFieldMode"));
		}
	}
	public FieldMode DisplayNameFieldMode
	{
		get
		{
			return GetFieldMode(Parameters.GetString("DisplayNameFieldMode"));
		}
	}


    protected override void PreLoadComponentDefinition()
	{
		base.Title = GetMessage("Componemt.Title");
		base.Description = GetMessage("Component.Description");
		base.Icon = "images/user_authform.gif";

		Group = new BXComponentGroup("Auth", GetMessage("User"), 100, BXComponentGroup.Utility);

		BXCategory fields = new BXCategory(GetMessageRaw("FieldSettings"), "fields", 200);

        ParamsDefinition.Add(
            "DoAuthentication",
            new BXParamYesNo(
                GetMessageRaw("DoAuthentication"),
                false,
                BXCategory.Main
                )
            );

        ParamsDefinition.Add(
            "RedirectUrl",
            new BXParamText(
                GetMessageRaw("RedirectUrl"),
                string.Empty,
                BXCategory.Main
                )
            );


		ParamsDefinition.Add(
			"FirstNameFieldMode",
			new BXParamSingleSelection(
				GetMessageRaw("FirstNameFieldMode"),
				"require",
				fields
				)
			);

		ParamsDefinition.Add(
			"LastNameFieldMode",
			new BXParamSingleSelection(
				GetMessageRaw("LastNameFieldMode"),
				"require",
				fields
				)
			);

		ParamsDefinition.Add(
			"DisplayNameFieldMode",
			new BXParamSingleSelection(
				GetMessageRaw("DisplayNameFieldMode"),
				"hide",
				fields
				)
			);
	}
	protected override void LoadComponentDefinition()
	{
		ParamsDefinition["FirstNameFieldMode"].Values = new List<BXParamValue>(new BXParamValue[] {
				new BXParamValue(GetMessageRaw("Field.Hide"), "hide"),
				new BXParamValue(GetMessageRaw("Field.Show"), "show"),
				new BXParamValue(GetMessageRaw("Field.Require"), "require")
		});
		ParamsDefinition["LastNameFieldMode"].Values = new List<BXParamValue>(new BXParamValue[] {
				new BXParamValue(GetMessageRaw("Field.Hide"), "hide"),
				new BXParamValue(GetMessageRaw("Field.Show"), "show"),
				new BXParamValue(GetMessageRaw("Field.Require"), "require")
		});
		ParamsDefinition["DisplayNameFieldMode"].Values = new List<BXParamValue>(new BXParamValue[] {
				new BXParamValue(GetMessageRaw("Field.Hide"), "hide"),
				new BXParamValue(GetMessageRaw("Field.Show"), "show"),
				new BXParamValue(GetMessageRaw("Field.Require"), "require")
		});
	}

    public bool DoAuthentication
    {
        get { return Parameters.GetBool("DoAuthentication", false); }
    }

	private string GetErrorMessage(MembershipCreateStatus status)
	{
		switch (status)
		{
			case MembershipCreateStatus.DuplicateUserName:
				return GetMessage("Error.UserWithLoginYouSpecifiedAlreadyExists");

			case MembershipCreateStatus.DuplicateEmail:
				return GetMessage("Error.UserWithEmailYouSpecifiedAlreadyExists");

			case MembershipCreateStatus.InvalidPassword:
				return GetMessage("Error.PasswordContraveneSiteRules") +
					(BXUserManager.Provider.MinRequiredPasswordLength > 0 ? String.Format(GetMessage("Error.FormatPasswordMustNotBeShorterThan"), BXUserManager.Provider.MinRequiredPasswordLength) : "") +
					(BXUserManager.Provider.MinRequiredNonAlphanumericCharacters > 0 ? String.Format(GetMessage("Error.FormatPasswordMustContain"), BXUserManager.Provider.MinRequiredNonAlphanumericCharacters) : "");

			case MembershipCreateStatus.InvalidEmail:
				return GetMessage("Error.EmailYouSpecifiedIsInvalid");

			case MembershipCreateStatus.InvalidAnswer:
				return GetMessage("Error.AnswerForSecretQuestionContraveneSiteRules");

			case MembershipCreateStatus.InvalidQuestion:
				return GetMessage("Error.SecretQuestionContraveneSiteRules");

			case MembershipCreateStatus.InvalidUserName:
				return GetMessage("Error.LoginContraveneSiteRules");

			case MembershipCreateStatus.ProviderError:
				return GetMessage("Error.AuthenticationProviderError");

			case MembershipCreateStatus.UserRejected:
				return GetMessage("Error.RegistrationAttemptHasBeenRejected");

			default:
				return GetMessage("Error.AnUnknownErrorHasOccurred");
		}
	}
	private FieldMode GetFieldMode(string val)
	{
		val = val != null ? val.ToLowerInvariant() : val;
		switch (val)
		{
			case "hide":
				return FieldMode.Hide;
			case "require":
				return FieldMode.Require;
			default:
				return FieldMode.Show;
		}
	}

	public override bool ProcessCommand(string commandName, BXParamsBag<object> commandParameters, List<string> commandErrors)
	{
		if (commandName.Equals("register", StringComparison.InvariantCultureIgnoreCase))
		{
			string firstName = (string)commandParameters["FirstName"];
			string lastName = (string)commandParameters["LastName"];
			string displayName = (string)commandParameters["DisplayName"];
			string login = (string)commandParameters["Login"];
			string val1 = (string)commandParameters["Password"];
			string email = (string)commandParameters["Email"];
			string question = (string)commandParameters["Question"];
			string answer = (string)commandParameters["Answer"];

			//MembershipCreateStatus status;

			try
			{
				try
				{
					BXUser user = new BXUser();

					user.UserName = login;
					user.ProviderName = BXUserManager.Provider.Name;
					user.Password = val1;
					user.Email = email;
					user.PasswordQuestion = (BXUserManager.Provider.RequiresQuestionAndAnswer ? question : null);
					user.PasswordAnswer = (BXUserManager.Provider.RequiresQuestionAndAnswer ? answer : null);
					user.IsApproved = true;
					if (firstName != null)
						user.FirstName = firstName;
					if (lastName != null)
						user.LastName = lastName;
					if (displayName != null)
						user.DisplayName = displayName;
					user.SiteId = DesignerSite;

					user.Save();
				}
				catch (MembershipCreateUserException ex)
				{
					throw new ProviderException(GetErrorMessage(ex.StatusCode));
				}

                if (DoAuthentication)
                {
                    string providerName = null;
                    if (BXAuthentication.Authenticate(login, val1, out providerName))
                        BXAuthentication.SetAuthCookie(login, providerName, false);
                    else
                        throw new InvalidOperationException(GetMessage("Error.InvalidLoginOrPassword"));
                }

                try
                {
                    Response.Redirect(GetRedirectUrl(), true);
                }
                catch (ThreadAbortException /*exc*/) { }

				return true;
			}
			catch (BXEventException e)
			{
				foreach (string s in e.Messages)
					commandErrors.Add(s);
			}
			catch (Exception e)
			{
				commandErrors.Add(e.Message);
			}
		}
		return false;
	}


	public enum FieldMode
	{
		Hide, 
		Show,
		Require
	}
}
