using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

using Bitrix;
using Bitrix.DataLayer;
using Bitrix.Modules;
using Bitrix.Services;
using Bitrix.UI;
using Bitrix.Security;
using Bitrix.Services.Text;

public partial class bitrix_admin_UsersList : BXAdminPage
{
	bool currentUserCanDeleteUser = false;
	bool currentUserCanModifyUser = false;
	bool currentUserCanModifySelfUser = false;
	bool currentUserCanCreateUser = false;

	protected void Page_Init(object sender, EventArgs e)
	{
		if (!this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserView))
			BXAuthentication.AuthenticationRequired();

		currentUserCanModifyUser = this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserModify);
		currentUserCanModifySelfUser = this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserModifySelf);
		currentUserCanCreateUser = this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserCreate);
		currentUserCanDeleteUser = this.BXUser.IsCanOperate(BXRoleOperation.Operations.UserDelete);

		InitPage();
	}

	private void InitPage()
	{
		filterSite.Values.Add(new ListItem(GetMessage("ListItemText.All"), ""));
		BXSiteCollection siteColl = BXSite.GetList(null, null);
		foreach (BXSite site in siteColl)
			filterSite.Values.Add(new ListItem("[" + HttpUtility.HtmlEncode(site.Id) + "] " + HttpUtility.HtmlEncode(site.Name), HttpUtility.HtmlEncode(site.Id)));
	}

	protected void Page_Load(object sender, EventArgs e)
	{
		((BXAdminMasterPage)Page.Master).Title = Page.Title;
		AddButton.Visible = currentUserCanCreateUser;
	}
	protected void AuthUserGridView_RowDataBound(object sender, GridViewRowEventArgs e)
	{
		BXGridView grid = (BXGridView)sender;
		BXGridViewRow row = (BXGridViewRow)e.Row;
		Bitrix.Security.BXUser u = (Bitrix.Security.BXUser)row.DataItem;
		if (e.Row.RowType != DataControlRowType.DataRow)
			return;
		List<string> allowed = new List<string>();

		BXIdentity user = (BXIdentity)BXUser.Identity;
		if (user.Id == u.UserId && currentUserCanModifySelfUser || currentUserCanModifyUser)
			allowed.Add("edit");
		else
			allowed.Add("view");

		if (currentUserCanDeleteUser)
		{
			allowed.Add("");
			allowed.Add("delete");
			allowed.Add("deleteProvider");
		}

		row.AllowedCommandsList = allowed.ToArray();
	}
	protected void AuthUserGridView_Select(object sender, Bitrix.UI.BXSelectEventArgs e)
	{
		e.Data = Bitrix.Security.BXUser.GetList(
			new BXFilter(BXAdminFilter1.CurrentFilter, Bitrix.Security.BXUser.Fields),
			new BXOrderBy(Bitrix.Security.BXUser.Fields, e.SortExpression),
			null, 
			new BXQueryParams(e.PagingOptions),
			BXTextEncoder.EmptyTextEncoder
		);
	}
	protected void AuthUserGridView_SelectCount(object sender, BXSelectCountEventArgs e)
	{
		e.Count = Bitrix.Security.BXUser.Count(
			new BXFilter(BXAdminFilter1.CurrentFilter, Bitrix.Security.BXUser.Fields)
		);
	}
	protected void AuthUserGridView_PopupMenuClick(object sender, Bitrix.UI.BXPopupMenuClickEventArgs e)
	{
		successMessage.Visible = false;
		e.Cancel = true;
		BXGridView grid = AuthUserGridView;
		DataKey drv = grid.DataKeys[e.EventRowIndex];

		int userId = 0;
		try
		{
			userId = (int)drv.Value;
		}
		catch
		{
			errorMessage.AddErrorMessage(GetMessage("ErrorMessage.CodeOfUserIsNotFound"));
			return;
		}


		if (e.CommandName == "edit" || e.CommandName == "view")
		{
			Response.Redirect(string.Format("AuthUsersEdit.aspx?id={0}", userId));
			return;
		}

		if (e.CommandName != "delete" && e.CommandName != "deleteProvider")
			return;

		//Delete
		try
		{
			if (!currentUserCanDeleteUser)
				throw new PublicException(GetMessageRaw("ExceptionText.YouDontHaveRightsToDeleteUsers"));

			BXUserCollection users = new BXUserCollection();
			users.Add(Bitrix.Security.BXUser.GetById(userId));
			DeleteUsers(users, e.CommandName == "deleteProvider");
			successMessage.Visible = true;
		}
		catch (Exception ex)
		{
			ProcessException(ex);
		}
		grid.MarkAsChanged();
	}
	protected void AuthUserGridView_MultiOperationActionRun(object sender, UserMadeChoiceEventArgs e)
	{
		if (e.CommandOfChoice.CommandName != "delete" && e.CommandOfChoice.CommandName != "deleteProvider")
			return;
		successMessage.Visible = false;
		e.Cancel = true;
		BXGridView grid = AuthUserGridView;
		try
		{
			if (!currentUserCanDeleteUser)
				throw new PublicException(GetMessageRaw("ExceptionText.YouDontHaveRightsToDeleteUsers"));

			BXUserCollection users; 
				if (e.ApplyForAll)
				{
					users = Bitrix.Security.BXUser.GetList(
						new BXFilter(BXAdminFilter1.CurrentFilter, Bitrix.Security.BXUser.Fields),
						null
					);
				}
				else
				{
					List<object> keys = new List<object>();
					foreach(int index in grid.GetSelectedRowsIndices())
						keys.Add(grid.DataKeys[index]["UserId"]);

					users = Bitrix.Security.BXUser.GetList(
						new BXFilter(
							new BXFilterItem(Bitrix.Security.BXUser.Fields.UserId, BXSqlFilterOperators.In, keys)
						),
						null
					);
				}

			DeleteUsers(users, e.CommandOfChoice.CommandName == "deleteProvider");
			successMessage.Visible = true;
		}
		catch (Exception ex)
		{
			ProcessException(ex);
		}
		grid.MarkAsChanged();
	}

	private void DeleteUsers(BXUserCollection users, bool deleteProvider)
	{
		if (!currentUserCanDeleteUser)
			throw new PublicException(GetMessageRaw("ExceptionText.YouDontHaveRightsToDeleteUsers"));

		foreach (Bitrix.Security.BXUser u in users)
		{
			if (u == null)
				throw new PublicException(GetMessageRaw("ExceptionText.UserIsNotFound"));

			try
			{
				u.Delete(deleteProvider);
			}
			catch (Exception ex)
			{
				throw new PublicException(GetMessageRaw("ExceptionText.DeletionOfUserFailed"), ex);
			}
		}
	}
	private void ProcessException(Exception ex)
	{
		if (ex is PublicException)
		{
			errorMessage.AddErrorMessage(Encode(ex.Message));
			if (ex.InnerException != null)
				BXLogService.LogAll(ex.InnerException, 0, BXLogMessageType.Error, AppRelativeVirtualPath);
			return;
		}
		
		BXEventException eventException = ex as BXEventException;
		if (eventException != null)
		{
			foreach (string msg in eventException.Messages)
				errorMessage.AddErrorMessage(Encode(msg));
			return;
		}

		errorMessage.AddErrorMessage(GetMessage("Kernel.UnknownError"));
		BXLogService.LogAll(ex, 0, BXLogMessageType.Error, AppRelativeVirtualPath);
	}
}
