using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories;

namespace ErsatzTV.Application.Configuration;

public class UpdateLoggingSettingsHandler : IRequestHandler<UpdateLoggingSettings, Either<BaseError, Unit>>
{
    private readonly IConfigElementRepository _configElementRepository;
    private readonly LoggingLevelSwitches _loggingLevelSwitches;

    public UpdateLoggingSettingsHandler(
        LoggingLevelSwitches loggingLevelSwitches,
        IConfigElementRepository configElementRepository)
    {
        _loggingLevelSwitches = loggingLevelSwitches;
        _configElementRepository = configElementRepository;
    }

    public async Task<Either<BaseError, Unit>> Handle(
        UpdateLoggingSettings request,
        CancellationToken cancellationToken) => await ApplyUpdate(request.LoggingSettings, cancellationToken);

    private async Task<Unit> ApplyUpdate(LoggingSettingsViewModel loggingSettings, CancellationToken cancellationToken)
    {
        await _configElementRepository.Upsert(ConfigElementKey.MinimumLogLevel, loggingSettings.DefaultMinimumLogLevel, cancellationToken);
        _loggingLevelSwitches.DefaultLevelSwitch.MinimumLevel = loggingSettings.DefaultMinimumLogLevel;

        await _configElementRepository.Upsert(
            ConfigElementKey.MinimumLogLevelScanning,
            loggingSettings.ScanningMinimumLogLevel, cancellationToken);
        _loggingLevelSwitches.ScanningLevelSwitch.MinimumLevel = loggingSettings.ScanningMinimumLogLevel;

        await _configElementRepository.Upsert(
            ConfigElementKey.MinimumLogLevelScheduling,
            loggingSettings.SchedulingMinimumLogLevel, cancellationToken);
        _loggingLevelSwitches.SchedulingLevelSwitch.MinimumLevel = loggingSettings.SchedulingMinimumLogLevel;

        await _configElementRepository.Upsert(
            ConfigElementKey.MinimumLogLevelSearching,
            loggingSettings.SearchingMinimumLogLevel, cancellationToken);
        _loggingLevelSwitches.SearchingLevelSwitch.MinimumLevel = loggingSettings.SearchingMinimumLogLevel;

        await _configElementRepository.Upsert(
            ConfigElementKey.MinimumLogLevelStreaming,
            loggingSettings.StreamingMinimumLogLevel, cancellationToken);
        _loggingLevelSwitches.StreamingLevelSwitch.MinimumLevel = loggingSettings.StreamingMinimumLogLevel;

        await _configElementRepository.Upsert(
            ConfigElementKey.MinimumLogLevelHttp,
            loggingSettings.HttpMinimumLogLevel, cancellationToken);
        _loggingLevelSwitches.HttpLevelSwitch.MinimumLevel = loggingSettings.HttpMinimumLogLevel;

        return Unit.Default;
    }
}
