using ExperionCrawler.Core.Application.Interfaces;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace ExperionCrawler.Infrastructure.OpcUa;

/// <summary>
/// 주기적으로 realtime_table 전체를 history_table 에 스냅샷 저장하는 BackgroundService.
/// 간격은 appsettings.json: "HistoryIntervalSeconds" (기본 60초).
/// </summary>
public class ExperionHistoryService : BackgroundService
{
    private readonly IServiceScopeFactory _scopeFactory;
    private readonly ILogger<ExperionHistoryService> _logger;
    private readonly IExperionRealtimeService _realtimeService;
    private readonly int _intervalSeconds;

    public ExperionHistoryService(
        IServiceScopeFactory scopeFactory,
        ILogger<ExperionHistoryService> logger,
        IExperionRealtimeService realtimeService,
        IConfiguration config)
    {
        _scopeFactory    = scopeFactory;
        _logger          = logger;
        _realtimeService = realtimeService;
        _intervalSeconds = config.GetValue<int>("HistoryIntervalSeconds", 60);
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("[HistoryService] 시작 — 간격: {Interval}초", _intervalSeconds);

        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                await Task.Delay(TimeSpan.FromSeconds(_intervalSeconds), stoppingToken);

                // 실시간 구독이 OFF 상태이면 스냅샷 건너뜀
                if (!_realtimeService.GetStatus().Running)
                {
                    _logger.LogDebug("[HistoryService] 구독 중지 상태 — 스냅샷 건너뜀");
                    continue;
                }

                using var scope = _scopeFactory.CreateScope();
                var db = scope.ServiceProvider.GetRequiredService<IExperionDbService>();
                var count = await db.SnapshotToHistoryAsync();
                _logger.LogInformation("[HistoryService] 스냅샷 저장: {Count}건", count);
            }
            catch (OperationCanceledException) { break; }
            catch (Exception ex)
            {
                _logger.LogError(ex, "[HistoryService] 스냅샷 저장 실패");
            }
        }

        _logger.LogInformation("[HistoryService] 종료");
    }
}
