using Microsoft.AspNetCore.Components;

namespace Guestlist.Components.Pages;

public partial class Admin
{
    [Inject]
    protected SetupStatusService SetupStatusService { get; set; } = default!;

    [Inject]
    protected UserService UserService { get; set; } = default!;
    
    [Inject]
    protected AccessCodeService AccessCodeService { get; set; } = default!;

    [Inject]
    protected DatabaseBackupService DatabaseBackupService { get; set; } = default!;

    [Inject]
    protected GuestEntryService GuestEntryService { get; set; } = default!;
    
    protected string Message { get; set; } = "";
    
    protected string NewGuestAccessCode { get; set; } = "";
    protected string AccessCodeMessage { get; set; } = "";
    protected string RecoveryMessage { get; set; } = "";

    protected string MaintainerUsername { get; set; } = "";
    protected string MaintainerDisplayName { get; set; } = "";
    protected string MaintainerPassword { get; set; } = "";
    protected string MaintainerMessage { get; set; } = "";
    protected List<UserDocument>? Maintainers { get; set; }

    [SupplyParameterFromQuery(Name = "message")]
    public string? IncomingMessage { get; set; }

    [SupplyParameterFromQuery(Name = "accessCodeMessage")]
    public string? IncomingAccessCodeMessage { get; set; }

    [SupplyParameterFromQuery(Name = "maintainerMessage")]
    public string? IncomingMaintainerMessage { get; set; }

    [SupplyParameterFromQuery(Name = "recoveryMessage")]
    public string? IncomingRecoveryMessage { get; set; }

    protected override async Task OnInitializedAsync()
    {
        Message = IncomingMessage ?? "";
        AccessCodeMessage = IncomingAccessCodeMessage ?? "";
        MaintainerMessage = IncomingMaintainerMessage ?? "";
        RecoveryMessage = IncomingRecoveryMessage ?? "";

        try
        {
            Maintainers = await UserService.GetMaintainersAsync();
        }
        catch
        {
            MaintainerMessage = "Maintainers could not be loaded.";
            Maintainers = [];
        }
    }
    
    protected async Task ResetSetup()
    {
        Message = "";

        try
        {
            var backupResult = await DatabaseBackupService.BackupAndDropActiveDatabaseAsync("Setup reset from admin panel");
            await SetupStatusService.ResetSetupAsync();
            await UserService.EnsureIndexesAsync();
            await GuestEntryService.EnsureIndexesAsync();
            await AccessCodeService.EnsureIndexesAsync();
            Message = $"Setup has been reset. The old database was copied to {backupResult.BackupDatabaseName}.";
        }
        catch
        {
            Message = "Setup could not be reset.";
            return;
        }
    }
    
    protected async Task UpdateGuestAccessCode()
    {
        AccessCodeMessage = "";

        if (string.IsNullOrWhiteSpace(NewGuestAccessCode))
        {
            AccessCodeMessage = "Provide a guest access code.";
            return;
        }

        try
        {
            await AccessCodeService.SetGuestAccessCodeAsync(NewGuestAccessCode);
        }
        catch (InvalidOperationException exception)
        {
            AccessCodeMessage = exception.Message;
            return;
        }
        catch
        {
            AccessCodeMessage = "Guest access code could not be updated.";
            return;
        }

        NewGuestAccessCode = "";
        AccessCodeMessage = "Guest access code has been updated.";
    }

    protected async Task CompleteSetupRecovery()
    {
        RecoveryMessage = "";

        try
        {
            if (!await AccessCodeService.HasGuestAccessCodeAsync())
            {
                RecoveryMessage = "Set a guest access code before completing recovery.";
                return;
            }

            await SetupStatusService.MarkSetupCompleteAsync();
        }
        catch
        {
            RecoveryMessage = "Setup recovery could not be completed.";
            return;
        }

        RecoveryMessage = "Setup recovery has been completed.";
    }

    protected async Task CreateMaintainer()
    {
        MaintainerMessage = "";

        if (string.IsNullOrWhiteSpace(MaintainerUsername))
        {
            MaintainerMessage = "Provide a username.";
            return;
        }

        if (string.IsNullOrWhiteSpace(MaintainerPassword))
        {
            MaintainerMessage = "Provide a password.";
            return;
        }

        if (MaintainerPassword.Length < 8)
        {
            MaintainerMessage = "Password must be at least 8 characters long.";
            return;
        }

        var displayName = string.IsNullOrWhiteSpace(MaintainerDisplayName)
            ? MaintainerUsername
            : MaintainerDisplayName;

        try
        {
            await UserService.CreateMaintainerAsync(displayName, MaintainerUsername, MaintainerPassword);
        }
        catch (InvalidOperationException exception)
        {
            MaintainerMessage = exception.Message;
            return;
        }
        catch
        {
            MaintainerMessage = "Maintainer could not be created.";
            return;
        }

        MaintainerUsername = "";
        MaintainerDisplayName = "";
        MaintainerPassword = "";
        MaintainerMessage = "Maintainer has been created.";
        Maintainers = await UserService.GetMaintainersAsync();
    }

    protected async Task DeleteMaintainer(string? id)
    {
        MaintainerMessage = "";

        if (string.IsNullOrWhiteSpace(id))
        {
            MaintainerMessage = "Maintainer is missing an id.";
            return;
        }

        try
        {
            await UserService.DeleteMaintainerAsync(id);
        }
        catch
        {
            MaintainerMessage = "Maintainer could not be deleted.";
            return;
        }

        MaintainerMessage = "Maintainer has been deleted.";
        Maintainers = await UserService.GetMaintainersAsync();
    }
}
