@namespace Oqtane.Modules.Admin.Users
@using System.Text.RegularExpressions;
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IUserService UserService
@inject IProfileService ProfileService
@inject ISettingService SettingService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer

@if (_initialized)
{
    <TabStrip>
        <TabPanel Name="Identity" ResourceKey="Identity">
            @if (profiles != null)
            {
                <div class="container">
                    <div class="row mb-1 align-items-center">
                        <Label Class="col-sm-3" For="username" HelpText="A unique username for a user. Note that this field can not be modified once it is saved." ResourceKey="Username"></Label>
                        <div class="col-sm-9">
                            <input id="username" class="form-control" @bind="@_username" />
                        </div>
                    </div>
                    <div class="row mb-1 align-items-center">
                        <Label Class="col-sm-3" For="email" HelpText="The email address where the user will receive notifications" ResourceKey="Email"></Label>
                        <div class="col-sm-9">
                            <input id="email" class="form-control" @bind="@_email" />
                        </div>
                    </div>
                    <div class="row mb-1 align-items-center">
                        <Label Class="col-sm-3" For="displayname" HelpText="The full name of the user" ResourceKey="DisplayName"></Label>
                        <div class="col-sm-9">
                            <input id="displayname" class="form-control" @bind="@_displayname" />
                        </div>
                    </div>
                    <div class="row mb-1 align-items-center">
                        <Label Class="col-sm-3" For="notify" HelpText="Indicate if new users should receive an email notification" ResourceKey="Notify">Notify? </Label>
                        <div class="col-sm-9">
                            <select id="notify" class="form-select" @bind="@_notify" required>
                                <option value="True">@SharedLocalizer["Yes"]</option>
                                <option value="False">@SharedLocalizer["No"]</option>
                            </select>
                        </div>
                    </div>
                </div>
            }
        </TabPanel>
        <TabPanel Name="Profile" ResourceKey="Profile">
            <div class="container">
                <div class="row mb-1 align-items-center">
                    @foreach (Profile profile in profiles)
                    {
                        var p = profile;
                        if (p.Category != category)
                        {
                            <div class="col text-center pb-2">
                                <strong>@p.Category</strong>
                            </div>
                            category = p.Category;
                        }
                        <div class="row mb-1 align-items-center">
                            <Label Class="col-sm-3" For="@p.Name" HelpText="@p.Description">@p.Title</Label>
                                <div class="col-sm-9">
                                    @if (!string.IsNullOrEmpty(p.Options))
                                {
                                    <select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
                                        @foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                                        {
                                            @if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
                                            {
                                                <option value="@option" selected>@option</option>
                                            }
                                            else
                                            {
                                                <option value="@option">@option</option>
                                            }
                                        }
                                    </select>
                                }
                                else
                                {
                                    @if (p.Rows == 1)
                                    {
                                        <input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
                                    }
                                    else
                                    {
                                        <textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
                                    }
                                }
                            </div>
                        </div>
                    }
                </div>
            </div>
        </TabPanel>
    </TabStrip>
    <br />
    <br />
    <button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
    <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
}


@code {
    private bool _initialized = false;
    private string _username = string.Empty;
    private string _email = string.Empty;
    private string _displayname = string.Empty;
    private string _notify = "True";
    private List<Profile> profiles;
    private Dictionary<string, string> settings;
    private string category = string.Empty;

    public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
            settings = new Dictionary<string, string>();
            _initialized = true;
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message);
            AddModuleMessage(Localizer["Error.Profile.Load"], MessageType.Error);
        }
    }

    private string GetProfileValue(string SettingName, string DefaultValue)
    {
        string value = SettingService.GetSetting(settings, SettingName, DefaultValue);
        if (value.Contains("]"))
        {
            value = value.Substring(value.IndexOf("]") + 1);
        }
        return value;
    }

    private async Task SaveUser()
    {
        try
        {
            if (_username != string.Empty && _email != string.Empty)
            {
                if (ValidateProfiles())
                {
                    var user = new User();
                    user.SiteId = PageState.Site.SiteId;
                    user.Username = _username;
                    user.Password = ""; // will be auto generated
                    user.Email = _email;
                    user.DisplayName = string.IsNullOrWhiteSpace(_displayname) ? _username : _displayname;
                    user.PhotoFileId = null;
                    user.SuppressNotification = !bool.Parse(_notify);

                    user = await UserService.AddUserAsync(user);

                    if (user != null)
                    {
                        await SettingService.UpdateUserSettingsAsync(settings, user.UserId);
                        await logger.LogInformation("User Created {User}", user);
                        NavigationManager.NavigateTo(NavigateUrl());
                    }
                    else
                    {
                        await logger.LogError("Error Adding User {Username} {Email}", _username, _email);
                        AddModuleMessage(Localizer["Error.User.AddCheckPass"], MessageType.Error);
                    }
                }
            }
            else
            {
                AddModuleMessage(Localizer["Message.Required.ProfileInfo"], MessageType.Warning);
            }
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", _username, _email, ex.Message);
            AddModuleMessage(Localizer["Error.User.Add"], MessageType.Error);
        }
    }

    private bool ValidateProfiles()
    {
        foreach (Profile profile in profiles)
        {
            var value = GetProfileValue(profile.Name, string.Empty);
            if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
            {
                settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
            }
            if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
            {
                if (profile.IsRequired && string.IsNullOrEmpty(value))
                {
                    AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
                    return false;
                }
                if (!string.IsNullOrEmpty(profile.Validation))
                {
                    Regex regex = new Regex(profile.Validation);
                    bool valid = regex.Match(value).Success;
                    if (!valid)
                    {
                        AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private void ProfileChanged(ChangeEventArgs e, string SettingName)
    {
        var value = (string)e.Value;
        settings = SettingService.SetSetting(settings, SettingName, value);
    }
}
