using MediatR;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using TakeoutSaaS.Application.App.Subscriptions.Commands;
using TakeoutSaaS.Domain.Tenants.Entities;
using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Ids;

namespace TakeoutSaaS.Application.App.Subscriptions.Handlers;

/// <summary>
/// 批量发送续费提醒命令处理器。
/// </summary>
public sealed class BatchSendReminderCommandHandler(
    ISubscriptionRepository subscriptionRepository,
    IIdGenerator idGenerator,
    ILogger<BatchSendReminderCommandHandler> logger)
    : IRequestHandler<BatchSendReminderCommand, BatchSendReminderResult>
{
    /// <inheritdoc />
    public async Task<BatchSendReminderResult> Handle(BatchSendReminderCommand request, CancellationToken cancellationToken)
    {
        var successCount = 0;
        var failures = new List<BatchFailureItem>();

        // 查询所有订阅及租户信息
        var subscriptions = await subscriptionRepository.FindByIdsWithTenantAsync(
            request.SubscriptionIds,
            cancellationToken);

        foreach (var subscriptionId in request.SubscriptionIds)
        {
            try
            {
                var item = subscriptions.FirstOrDefault(s => s.Subscription.Id == subscriptionId);
                if (item == null)
                {
                    failures.Add(new BatchFailureItem
                    {
                        SubscriptionId = subscriptionId,
                        Reason = "订阅不存在"
                    });
                    continue;
                }

                // 创建通知记录
                var notification = new TenantNotification
                {
                    Id = idGenerator.NextId(),
                    TenantId = item.Subscription.TenantId,
                    Title = "续费提醒",
                    Message = request.ReminderContent,
                    Severity = TenantNotificationSeverity.Warning,
                    Channel = TenantNotificationChannel.InApp,
                    SentAt = DateTime.UtcNow,
                    ReadAt = null,
                    CreatedAt = DateTime.UtcNow
                };

                await subscriptionRepository.AddNotificationAsync(notification, cancellationToken);
                successCount++;

                logger.LogInformation(
                    "发送续费提醒: SubscriptionId={SubscriptionId}, TenantId={TenantId}, TenantName={TenantName}",
                    subscriptionId, item.Subscription.TenantId, item.Tenant.Name);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "发送续费提醒失败: SubscriptionId={SubscriptionId}", subscriptionId);
                failures.Add(new BatchFailureItem
                {
                    SubscriptionId = subscriptionId,
                    Reason = $"发送失败: {ex.Message}"
                });
            }
        }

        // 记录操作日志
        var operationLog = new OperationLog
        {
            Id = idGenerator.NextId(),
            OperationType = "BatchRemind",
            TargetType = "Subscription",
            TargetIds = JsonSerializer.Serialize(request.SubscriptionIds),
            Parameters = JsonSerializer.Serialize(new { request.ReminderContent }),
            Result = JsonSerializer.Serialize(new { SuccessCount = successCount, FailureCount = failures.Count }),
            Success = failures.Count == 0,
            CreatedAt = DateTime.UtcNow
        };

        await subscriptionRepository.AddOperationLogAsync(operationLog, cancellationToken);

        // 保存所有更改
        await subscriptionRepository.SaveChangesAsync(cancellationToken);

        return new BatchSendReminderResult
        {
            SuccessCount = successCount,
            FailureCount = failures.Count,
            Failures = failures
        };
    }
}
