using Nexus.Api.Repositories;

namespace Nexus.Api.Services;

/// <summary>
/// Process-local projection of the persisted, owner-approved OpenClaw
/// management boundary. The database profile remains the durable authority;
/// this projection lets synchronous capability checks use the same decision.
/// </summary>
public interface IOpenClawManagementState
{
    bool Enabled { get; }
    void SetEnabled(bool enabled);
}

public sealed class OpenClawManagementState : IOpenClawManagementState
{
    private int enabled;

    public bool Enabled => Volatile.Read(ref enabled) == 1;

    public void SetEnabled(bool value)
        => Interlocked.Exchange(ref enabled, value ? 1 : 0);
}

/// <summary>
/// Hydrates the local projection from the primary persisted connection profile
/// once application services are available.
/// </summary>
public sealed class OpenClawManagementStateInitializer(
    IServiceScopeFactory scopeFactory,
    IOpenClawManagementState state,
    ILogger<OpenClawManagementStateInitializer> logger) : IHostedService
{
    public async Task StartAsync(CancellationToken cancellationToken)
    {
        state.SetEnabled(false);
        try
        {
            await using var scope = scopeFactory.CreateAsyncScope();
            var profiles = scope.ServiceProvider
                .GetRequiredService<IOpenClawConnectionProfileRepository>();
            var profile = await profiles.GetPrimaryAsync(cancellationToken);
            state.SetEnabled(profile?.ManagementEnabled ?? false);
        }
        catch (Exception exception)
        {
            logger.LogWarning(
                exception,
                "OpenClaw management state could not be hydrated from the primary profile");
        }
    }

    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
