@namespace Oqtane.Modules.Admin.Themes
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IThemeService ThemeService
@inject IModuleService ModuleService
@inject IPageModuleService PageModuleService
@inject ISystemService SystemService
@inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer
@using System.Text.RegularExpressions
@using System.IO;

@if (_systeminfo != null && _templates != null)
{
    <table class="table table-borderless">
        <tr>
            <td>
                <Label For="owner" HelpText="Enter the name of the organization who is developing this theme. It should not contain spaces or punctuation." ResourceKey="OwnerName">Owner Name: </Label>
            </td>
            <td>
                <input id="owner" class="form-control" @bind="@_owner" />
            </td>
        </tr>
        <tr>
            <td>
                <Label For="module" HelpText="Enter a name for this theme. It should not contain spaces or punctuation." ResourceKey="ThemeName">Theme Name: </Label>
            </td>
            <td>
                <input id="module" class="form-control" @bind="@_theme" />
            </td>
        </tr>
        <tr>
            <td>
                <Label For="template" HelpText="Select a theme template. Templates are located in the wwwroot/Themes/Templates folder on the server." ResourceKey="Template">Template: </Label>
            </td>
            <td>
                <select id="template" class="form-control" @onchange="(e => TemplateChanged(e))">
                    <option value="-">&lt;@Localizer["Select Template"]&gt;</option>
                    @foreach (string template in _templates)
                    {
                        <option value="@template">@template</option>
                    }
                </select>
            </td>
        </tr>
        <tr>
            <td>
                <Label For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
            </td>
            <td>
                <select id="reference" class="form-control" @bind="@_reference">
                    @foreach (string version in Constants.ReleaseVersions.Split(','))
                    {
                        if (Version.Parse(version).CompareTo(Version.Parse("2.0.0")) >= 0)
                        {
                            <option value="@(version)">@(version)</option>
                        }
                    }
                    <option value="local">@Localizer["Local Version"]</option>
                </select>
            </td>
        </tr>
        @if (!string.IsNullOrEmpty(_location))
        {
            <tr>
                <td>
                    <Label For="location" HelpText="Location where the theme will be created" ResourceKey="Location">Location: </Label>
                </td>
                <td>
                    <input id="module" class="form-control" @bind="@_location" readonly />
                </td>
            </tr>
        }
    </table>
    <button type="button" class="btn btn-success" @onclick="CreateTheme">@Localizer["Create Theme"]</button>
    <NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
}

@code {
    private string _owner = string.Empty;
    private string _theme = string.Empty;
    private string _template = "-";
    private string _reference = Constants.Version;
    private string _location = string.Empty;

    private Dictionary<string, string> _systeminfo;
    private List<string> _templates;

    public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;

    protected override async Task OnParametersSetAsync()
    {
        try
        {
            _systeminfo = await SystemService.GetSystemInfoAsync();
            _templates = await ThemeService.GetThemeTemplatesAsync();
            AddModuleMessage(Localizer["Please Note That The Theme Creator Is Only Intended To Be Used In A Development Environment"], MessageType.Info);
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Loading Theme Creator");
        }
    }

    private async Task CreateTheme()
    {
        try
        {
            if (IsValid(_owner) && IsValid(_theme) && _owner != _theme && _template != "-")
            {
                var theme = new Theme { Owner = _owner, Name = _theme, Template = _template, Version = _reference };
                theme = await ThemeService.CreateThemeAsync(theme);
                GetLocation();

                AddModuleMessage(Localizer["The Source Code For Your Theme Has Been Created At The Location Specified Below And Must Be Compiled In Order To Make It Functional. Once It Has Been Compiled You Must <a href=\"{0}\">Restart</a> Your Application To Activate The Module.", NavigateUrl("admin/system")], MessageType.Success);
            }
            else
            {
                AddModuleMessage(Localizer["You Must Provide A Valid Owner Name And Theme Name ( ie. No Punctuation Or Spaces And The Values Cannot Be The Same ) And Choose A Template"], MessageType.Warning);
            }
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Creating Theme");
        }
    }

    private bool IsValid(string name)
    {
        // must contain letters, underscores and digits and first character must be letter or underscore
        return !string.IsNullOrEmpty(name) && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
    }

    private void TemplateChanged(ChangeEventArgs e)
    {
        _template = (string)e.Value;
        GetLocation();
    }

    private void GetLocation()
    {
        _location = string.Empty;
        if (_template != "-" && _systeminfo != null && _systeminfo.ContainsKey("serverpath"))
        {
            string[] path = _systeminfo["serverpath"].Split(Path.DirectorySeparatorChar);
            _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 2) +
                Path.DirectorySeparatorChar + _owner + "." + _theme;
        }
        StateHasChanged();
    }
}
