@namespace Oqtane.Modules.Admin.Files
@inherits ModuleBase
@inject IFolderService FolderService
@inject IFileService FileService
@inject NavigationManager NavigationManager
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer

@if (_folders != null)
{
    <TabStrip>
        <TabPanel Name="Settings" ResourceKey="Settings" Heading="Settings">
            <form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
                <div class="container">
                    <div class="row mb-1 align-items-center">
                        <Label Class="col-sm-3" For="parent" HelpText="Select the parent folder" ResourceKey="Parent">Parent: </Label>
                        <div class="col-sm-9">
                            <select id="parent" class="form-select" @bind="@_parentId" required>
                                @if (PageState.QueryString.ContainsKey("id"))
                                {
                                    <option value="-1">&lt;@Localizer["NoParent"]&gt;</option>
                                }
                                @foreach (Folder folder in _folders)
                                {
                                    <option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
                                }
                            </select>
                        </div>
                    </div>
                    <div class="row mb-1 align-items-center">
                        <Label Class="col-sm-3" For="name" HelpText="Enter the folder name" ResourceKey="Name">Name: </Label>
                        <div class="col-sm-9">
                            <input id="name" class="form-control" @bind="@_name" maxlength="256" required />
                        </div>
                    </div>
                    <div class="row mb-1 align-items-center">
                        <Label Class="col-sm-3" For="type" HelpText="Select the folder type. Private folders are only accessible by authorized users. Public folders can be accessed by all users" ResourceKey="Type">Type: </Label>
                        <div class="col-sm-9">
                            @if (PageState.QueryString.ContainsKey("id"))
                            {
                                <input id="type" class="form-control" readonly @bind="@_type" />
                            }
                            else
                            {
                                <select id="type" class="form-select" @bind="@_type" required>
                                    <option value="@FolderTypes.Private">@Localizer[FolderTypes.Private]</option>
                                    <option value="@FolderTypes.Public">@Localizer[FolderTypes.Public]</option>
                                </select>
                            }
                        </div>
                    </div>
                    <div class="row mb-1 align-items-center">
                        <Label Class="col-sm-3" For="imagesizes" HelpText="Enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,400x400). Use * to indicate the folder supports all image sizes." ResourceKey="ImageSizes">Image Sizes: </Label>
                        <div class="col-sm-9">
                            <input id="imagesizes" class="form-control" @bind="@_imagesizes" maxlength="512" />
                        </div>
                    </div>
                    <div class="row mb-1 align-items-center">
                        <Label Class="col-sm-3" For="capacity" HelpText="Enter the maximum folder capacity (in megabytes). Specify zero if the capacity is unlimited." ResourceKey="Capacity">Capacity: </Label>
                        <div class="col-sm-9">
                            <input id="capacity" class="form-control" @bind="@_capacity" required />
                        </div>
                    </div>
                </div>
                @if (PageState.QueryString.ContainsKey("id"))
                {
                    <br />
                    <AuditInfo CreatedBy="@_createdBy" CreatedOn="@_createdOn" ModifiedBy="@_modifiedBy" ModifiedOn="@_modifiedOn"></AuditInfo>
                }
            </form>
        </TabPanel>
        <TabPanel Name="Permissions" ResourceKey="Permissions" Heading="Permissions">
            <div class="container">
                <div class="row mb-1 align-items-center">
                    <PermissionGrid EntityName="@EntityNames.Folder" PermissionNames="@(PermissionNames.Browse + "," + PermissionNames.View + "," + PermissionNames.Edit)" PermissionList="@_permissions" @ref="_permissionGrid" />
                </div>
            </div>
        </TabPanel>
    </TabStrip>

    <br />
    @if (!_isSystem)
    {
        <button type="button" class="btn btn-success" @onclick="SaveFolder">@SharedLocalizer["Save"]</button>
        @((MarkupString)"&nbsp;")
    }
    <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
    @if (!_isSystem && PageState.QueryString.ContainsKey("id"))
    {
        @((MarkupString)"&nbsp;")
        <ActionDialog Header="Delete Folder" Message="Are You Sure You Wish To Delete This Folder?" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFolder())" ResourceKey="DeleteFolder" />
    }
}

@code {
    private ElementReference form;
    private bool validated = false;
    private List<Folder> _folders;
    private int _folderId = -1;
    private int _parentId = -1;
    private string _name;
    private string _type = FolderTypes.Private;
    private string _imagesizes = string.Empty;
    private string _capacity = "0";
    private bool _isSystem;
    private List<Permission> _permissions = null;
    private string _createdBy;
    private DateTime _createdOn;
    private string _modifiedBy;
    private DateTime _modifiedOn;

#pragma warning disable 649
    private PermissionGrid _permissionGrid;
#pragma warning restore 649

    public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;

    public override string Title => "Folder Management"; 

    protected override async Task OnInitializedAsync()
    {
        try
        {
            _folders = await FolderService.GetFoldersAsync(PageState.Site.SiteId);

            if (PageState.QueryString.ContainsKey("id"))
            {
                _folderId = Int32.Parse(PageState.QueryString["id"]);
                Folder folder = await FolderService.GetFolderAsync(_folderId);
                if (folder != null)
                {
                    _parentId = folder.ParentId ?? -1;
                    _name = folder.Name;
                    _type = folder.Type;
                    _imagesizes = folder.ImageSizes;
                    _capacity = folder.Capacity.ToString();
                    _isSystem = folder.IsSystem;
                    _permissions = folder.PermissionList;
                    _createdBy = folder.CreatedBy;
                    _createdOn = folder.CreatedOn;
                    _modifiedBy = folder.ModifiedBy;
                    _modifiedOn = folder.ModifiedOn;
                }
            }
            else
            {
                _parentId = _folders[0].FolderId;
            }
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Loading Folder {FolderId} {Error}", _folderId, ex.Message);
            AddModuleMessage(Localizer["Error.Folder.Load"], MessageType.Error);
        }
    }

    private async Task SaveFolder()
    {
        validated = true;
        var interop = new Interop(JSRuntime);
        if (await interop.FormValid(form))
        {
            if (_name == string.Empty || _parentId == -1)
            {
                AddModuleMessage(Localizer["Message.Required.FolderParent"], MessageType.Warning);
                return;
            }

            if (!_name.IsPathOrFileValid())
            {
                AddModuleMessage(Localizer["Message.Folder.InvalidName"], MessageType.Warning);
                return;
            }

            try
            {
                Folder folder;

                if (_folderId != -1)
                {
                    folder = await FolderService.GetFolderAsync(_folderId);
                }
                else
                {
                    folder = new Folder();
                }

                if (_parentId == -1)
                {
                    folder.ParentId = null;
                }
                else
                {
                    folder.ParentId = _parentId;
                }
                
                // check for duplicate folder names
                if (_folders.Any(item => item.ParentId == folder.ParentId && item.Name == _name && item.FolderId != _folderId))
                {
                    AddModuleMessage(Localizer["Message.Folder.Duplicate"], MessageType.Warning);
                    return;
                }

                folder.SiteId = PageState.Site.SiteId;
                folder.Name = _name;
                folder.Type = _type;
                folder.ImageSizes = _imagesizes;
                folder.Capacity = int.Parse(_capacity);
                folder.IsSystem = _isSystem;
                folder.PermissionList = _permissionGrid.GetPermissionList();

                if (_folderId != -1)
                {
                    folder = await FolderService.UpdateFolderAsync(folder);
                }
                else
                {
                    folder = await FolderService.AddFolderAsync(folder);
                }

                if (folder != null)
                {
                    await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId);
                    await logger.LogInformation("Folder Saved {Folder}", folder);
                    NavigationManager.NavigateTo(NavigateUrl());
                }
                else
                {
                    AddModuleMessage(Localizer["Error.Folder.Save"], MessageType.Error);
                }
            }
            catch (Exception ex)
            {
                await logger.LogError(ex, "Error Saving Folder {FolderId} {Error}", _folderId, ex.Message);
                AddModuleMessage(Localizer["Error.Folder.Save"], MessageType.Error);
            }
        }
        else
        {
            AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
        }
    }

    private async Task DeleteFolder()
    {
        try
        {
            bool isparent = false;
            foreach (Folder folder in _folders)
            {
                if (folder.ParentId == _folderId)
                {
                    isparent = true;
                    break;
                }
            }
            if (!isparent)
            {
                var files = await FileService.GetFilesAsync(_folderId);
                if (files.Count == 0)
                {
                    await FolderService.DeleteFolderAsync(_folderId);
                    await logger.LogInformation("Folder Deleted {Folder}", _folderId);
                    NavigationManager.NavigateTo(NavigateUrl());
                }
                else
                {
                    AddModuleMessage(Localizer["Message.Folder.Files.InvalidDelete"], MessageType.Warning);
                }
            }
            else
            {
                AddModuleMessage(Localizer["Message.Folder.Subfolders.InvalidDelete"], MessageType.Warning);
            }
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Deleting Folder {Folder} {Error}", _folderId, ex.Message);
            AddModuleMessage(Localizer["Error.Folder.Delete"], MessageType.Error);
        }
    }
}