@namespace Oqtane.Installer
@using Oqtane.Interfaces
@using Oqtane.Installer.Controls

@inject NavigationManager NavigationManager
@inject IInstallationService InstallationService
@inject ISiteService SiteService
@inject IUserService UserService
@inject IJSRuntime JSRuntime
@inject IStringLocalizer<Installer> Localizer

<div class="container">
    <div class="row">
        <div class="mx-auto text-center">
            <img src="oqtane-black.png" />
            <div style="font-weight: bold">@Localizer["Version:"] @Constants.Version</div>
        </div>
    </div>
    <hr class="app-rule" />
    <div class="row justify-content-center">
        <div class="col text-center">
            <h2>@Localizer["Database Configuration"]</h2><br />
            <table class="form-group" cellpadding="4" cellspacing="4" style="margin: auto;">
                <tbody>
                <tr>
                    <td>
                        <label class="control-label" style="font-weight: bold">@Localizer["Database Type:"]</label>
                    </td>
                    <td>
                        <select class="custom-select" value="@_databaseName" @onchange="(e => DatabaseChanged(e))">
                            @foreach (var database in _databases)
                            {
                                <option value="@database.Name">@Localizer[@database.FriendlyName]</option>
                            }
                        </select>
                    </td>
                </tr>
                @{
                    if (_databaseConfigType != null)
                    {
                        @DatabaseConfigComponent;
                    }
                }
                </tbody>
            </table>
        </div>
        <div class="col text-center">
            <h2>@Localizer["Application Administrator"]</h2><br />
            <table class="form-group" cellpadding="4" cellspacing="4" style="margin: auto;">
                <tbody>
                    <tr>
                        <td>
                            <label class="control-label" style="font-weight: bold">@Localizer["Username:"] </label>
                        </td>
                        <td>
                            <input type="text" class="form-control" @bind="@_hostUsername" readonly />
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <label class="control-label" style="font-weight: bold">@Localizer["Password:"] </label>
                        </td>
                        <td>
                            <input type="password" class="form-control" @bind="@_hostPassword" />
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <label class="control-label" style="font-weight: bold">@Localizer["Confirm:"] </label>
                        </td>
                        <td>
                            <input type="password" class="form-control" @bind="@_confirmPassword" />
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <label class="control-label" style="font-weight: bold">@Localizer["Email:"] </label>
                        </td>
                        <td>
                            <input type="text" class="form-control" @bind="@_hostEmail" />
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
    <hr class="app-rule" />
    <div class="row">
        <div class="mx-auto text-center">
            <button type="button" class="btn btn-success" @onclick="Install">@Localizer["Install Now"]</button><br /><br />
            <ModuleMessage Message="@_message" Type="MessageType.Error"></ModuleMessage>
        </div>
        <div class="app-progress-indicator" style="@_loadingDisplay"></div>
    </div>
</div>

@code {
    private IList<Database> _databases;
    private string _databaseName = "LocalDB";
    private Type _databaseConfigType;
    private object _databaseConfig;
    private RenderFragment DatabaseConfigComponent { get; set; }

    private string _hostUsername = UserNames.Host;
    private string _hostPassword = string.Empty;
    private string _confirmPassword = string.Empty;
    private string _hostEmail = string.Empty;
    private string _message = string.Empty;
    private string _loadingDisplay = "display: none;";

    protected override void OnInitialized()
    {
        base.OnInitialized();

        _databases = new List<Database>
        {
            new()
            {
                Name = "LocalDB",
                FriendlyName = "Local Database",
                Type = "Oqtane.Installer.Controls.LocalDBConfig, Oqtane.Client"
            },
            new()
            {
                Name = "SqlServer",
                FriendlyName = "SQL Server",
                Type = "Oqtane.Installer.Controls.SqlServerConfig, Oqtane.Client"
            },
            new()
            {
                Name = "Sqlite",
                FriendlyName = "Sqlite",
                Type = "Oqtane.Installer.Controls.SqliteConfig, Oqtane.Client"
            },
            new()
            {
                Name = "MySQL",
                FriendlyName = "MySQL",
                Type = "Oqtane.Installer.Controls.MySQLConfig, Oqtane.Client"
            },
            new()
            {
                Name = "PostgreSQL",
                FriendlyName = "PostgreSQL",
                Type = "Oqtane.Installer.Controls.PostgreSQLConfig, Oqtane.Client"
            }
        };
        
        LoadDatabaseConfigComponent();
    }

    private void DatabaseChanged(ChangeEventArgs eventArgs)
    {
        try
        {
            _databaseName = (string)eventArgs.Value;

            LoadDatabaseConfigComponent();
        }
        catch (Exception exception)
        {
            _message = Localizer["Error loading Database Configuration Control"];
        }
    }

    private void LoadDatabaseConfigComponent()
    {
        var database = _databases.SingleOrDefault(d => d.Name == _databaseName);
        if (database != null)
        {
            _databaseConfigType = Type.GetType(database.Type);
            DatabaseConfigComponent = builder =>
            {
                builder.OpenComponent(0, _databaseConfigType);
                builder.AddAttribute(1, "IsInstaller", true);
                builder.AddComponentReferenceCapture(2, inst => { _databaseConfig = Convert.ChangeType(inst, _databaseConfigType); });
                builder.CloseComponent();
            };
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            var interop = new Interop(JSRuntime);
            await interop.IncludeLink("app-stylesheet", "stylesheet", "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css", "text/css", "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T", "anonymous", "");
        }
    }

    private async Task Install()
    {
        var connectionString = String.Empty;
        if (_databaseConfig is IDatabaseConfigControl databaseConfigControl)
        {
            connectionString = databaseConfigControl.GetConnectionString();
        }

        if (connectionString != "" && _hostUsername != "" && _hostPassword.Length >= 6 && _hostPassword == _confirmPassword && _hostEmail != "")
        {
            _loadingDisplay = "";
            StateHasChanged();

            Uri uri = new Uri(NavigationManager.Uri);

            var config = new InstallConfig
            {
                DatabaseType = _databaseName,
                ConnectionString = connectionString,
                Aliases = uri.Authority,
                HostEmail = _hostEmail,
                HostPassword = _hostPassword,
                HostName = UserNames.Host,
                TenantName = TenantNames.Master,
                IsNewTenant = true,
                SiteName = Constants.DefaultSite
            };

            var installation = await InstallationService.Install(config);
            if (installation.Success)
            {
                NavigationManager.NavigateTo(uri.Scheme + "://" + uri.Authority, true);
            }
            else
            {
                _message = installation.Message;
                _loadingDisplay = "display: none;";
            }
        }
        else
        {
            _message = Localizer["Please Enter All Fields And Ensure Passwords Match And Are Greater Than 5 Characters In Length"];
        }
    }

}
