using Hangfire;
using KArtSell.BuildingBlocks.Time;
using Microsoft.Extensions.Logging;

namespace KArtSell.Modules.ModelOperations.ShadowRun.Features.ImportMarketData;

/// <summary>
/// Hangfire job that runs daily import for KRX, OpenDart, and KIS APIs.
/// Scheduled: 16:30-20:30 KST (Phase 1 market data window).
/// Queue: q-evaluation (Phase 1 priority).
/// </summary>
public sealed class ScheduleDailyImportsJob
{
    private readonly ImportMarketDataHandler _handler;
    private readonly IBackgroundJobClient _jobClient;
    private readonly IClock _clock;
    private readonly ILogger<ScheduleDailyImportsJob> _logger;

    public ScheduleDailyImportsJob(
        ImportMarketDataHandler handler,
        IBackgroundJobClient jobClient,
        IClock clock,
        ILogger<ScheduleDailyImportsJob> logger)
    {
        _handler = handler;
        _jobClient = jobClient;
        _clock = clock;
        _logger = logger;
    }

    /// <summary>
    /// Execute daily import for all 3 APIs.
    /// Runs once per day at market close + 1 hour (17:30 KST).
    /// </summary>
    [Queue("q-evaluation")]
    public async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        var importDate = DateOnly.FromDateTime(_clock.UtcNow.UtcDateTime);
        var correlationId = Guid.NewGuid();

        _logger.LogInformation("Starting daily market data imports: Date={ImportDate}, CorrelationId={CorrelationId}",
            importDate, correlationId);

        // Queue 3 imports in parallel (q-evaluation queue)
        var tasks = new[]
        {
            ExecuteApiImportAsync("krx", importDate, correlationId, cancellationToken),
            ExecuteApiImportAsync("opendart", importDate, correlationId, cancellationToken),
            ExecuteApiImportAsync("kis", importDate, correlationId, cancellationToken)
        };

        var results = await Task.WhenAll(tasks);

        var allSuccess = results.All(r => r.success);
        _logger.LogInformation(
            "Daily imports completed: Date={ImportDate}, AllSuccess={AllSuccess}",
            importDate, allSuccess);

        if (!allSuccess)
        {
            // Log to data quality quarantine for manual review
            _logger.LogWarning(
                "Some imports failed; check observability.data_quality_quarantine for details");
        }
    }

    private async Task<ImportMarketDataResult> ExecuteApiImportAsync(
        string apiName,
        DateOnly importDate,
        Guid correlationId,
        CancellationToken cancellationToken)
    {
        try
        {
            var command = new ImportMarketDataCommand(
                apiName: apiName,
                importDate: importDate,
                parameters: new(),
                idempotencyKey: Guid.NewGuid(),
                correlationId: correlationId);

            var result = await _handler.HandleAsync(command, cancellationToken);

            _logger.LogInformation("API import result: {ApiName} {Status} ({RowCount} rows)",
                apiName, result.success ? "SUCCESS" : "FAILURE", result.rowCount);

            return result;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "API import exception: {ApiName}", apiName);
            return new ImportMarketDataResult(
                success: false,
                apiName: apiName,
                rowCount: 0,
                checksum: "",
                isDuplicate: false,
                errorMessage: ex.Message);
        }
    }
}
