using Hangfire;
using Microsoft.EntityFrameworkCore;
using TakeoutSaaS.Application.App.Members.MessageReach.Services;
using TakeoutSaaS.Infrastructure.App.Persistence;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.TenantApi.Services;

/// <summary>
/// 会员消息触达发送任务执行器。
/// </summary>
public sealed class MemberMessageReachDispatchJobRunner(
    TakeoutAppDbContext dbContext,
    ITenantContextAccessor tenantContextAccessor,
    IMemberMessageReachAppService memberMessageReachAppService,
    ILogger<MemberMessageReachDispatchJobRunner> logger)
{
    /// <summary>
    /// 执行消息发送任务。
    /// </summary>
    [AutomaticRetry(Attempts = 0)]
    public async Task ExecuteAsync(long messageId)
    {
        // 1. 查询任务所属租户，避免跨租户执行。
        var jobMeta = await dbContext.MemberReachMessages
            .IgnoreQueryFilters()
            .AsNoTracking()
            .Where(item => item.Id == messageId)
            .Select(item => new JobMeta(item.Id, item.TenantId))
            .SingleOrDefaultAsync();
        if (jobMeta is null || jobMeta.TenantId <= 0)
        {
            logger.LogWarning("会员消息任务不存在或租户无效，MessageId={MessageId}", messageId);
            return;
        }

        // 2. 切换租户作用域并执行发送逻辑。
        using var _ = tenantContextAccessor.EnterTenantScope(jobMeta.TenantId, "scheduler", $"tenant-{jobMeta.TenantId}");
        try
        {
            await memberMessageReachAppService.ExecuteDispatchAsync(jobMeta.TenantId, jobMeta.Id, CancellationToken.None);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "会员消息任务执行失败，TenantId={TenantId} MessageId={MessageId}", jobMeta.TenantId, jobMeta.Id);
        }
    }

    private sealed record JobMeta(long Id, long TenantId);
}
