using Microsoft.EntityFrameworkCore;
using TeleWave.Application.Common.Interfaces;
using TeleWave.Application.Settings;
using TeleWave.Domain.Settings;

namespace TeleWave.Infrastructure.Settings;

/// <summary>Настройки сайта поверх key-value таблицы AppSetting. Запись не сохраняет сама —
/// сохранение выполняет UnitOfWorkBehavior команды (используется общий scoped-контекст).</summary>
public sealed class SiteSettings(IAppDbContext dbContext) : ISiteSettings
{
    public Task<bool> IsRegistrationEnabledAsync(CancellationToken cancellationToken) =>
        dbContext.GetBoolSettingAsync(SettingKeys.RegistrationEnabled, false, cancellationToken);

    public async Task SetRegistrationEnabledAsync(bool enabled, CancellationToken cancellationToken)
    {
        await UpsertAsync(
            SettingKeys.RegistrationEnabled,
            enabled ? "true" : "false",
            cancellationToken
        );
    }

    public Task<string> GetPreferredAudioLanguagesAsync(CancellationToken cancellationToken) =>
        dbContext.GetStringSettingAsync(SettingKeys.PreferredAudioLanguages, "", cancellationToken);

    public Task SetPreferredAudioLanguagesAsync(
        string value,
        CancellationToken cancellationToken
    ) => UpsertAsync(SettingKeys.PreferredAudioLanguages, value, cancellationToken);

    public Task<bool> AreChannelNumbersEnabledAsync(CancellationToken cancellationToken) =>
        dbContext.GetBoolSettingAsync(SettingKeys.ChannelNumbersEnabled, false, cancellationToken);

    public Task SetChannelNumbersEnabledAsync(bool enabled, CancellationToken cancellationToken) =>
        UpsertAsync(
            SettingKeys.ChannelNumbersEnabled,
            enabled ? "true" : "false",
            cancellationToken
        );

    private async Task UpsertAsync(string key, string value, CancellationToken cancellationToken)
    {
        var existing = await dbContext.AppSettings.FirstOrDefaultAsync(
            s => s.Key == key,
            cancellationToken
        );
        if (existing is null)
            dbContext.AppSettings.Add(AppSetting.Create(key, value));
        else
            existing.SetValue(value);
    }
}
