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 BatchExtendSubscriptionsCommandHandler(
    ISubscriptionRepository subscriptionRepository,
    IIdGenerator idGenerator,
    ILogger<BatchExtendSubscriptionsCommandHandler> logger)
    : IRequestHandler<BatchExtendSubscriptionsCommand, BatchExtendResult>
{
    /// <inheritdoc />
    public async Task<BatchExtendResult> Handle(BatchExtendSubscriptionsCommand request, CancellationToken cancellationToken)
    {
        var successCount = 0;
        var failures = new List<BatchFailureItem>();

        // 验证参数
        if (!request.DurationDays.HasValue && !request.DurationMonths.HasValue)
        {
            throw new InvalidOperationException("必须指定延期天数或延期月数");
        }

        // 计算延期时间
        var extendDays = request.DurationDays ?? 0;
        var extendMonths = request.DurationMonths ?? 0;

        // 查询所有订阅
        var subscriptions = await subscriptionRepository.FindByIdsAsync(
            request.SubscriptionIds,
            cancellationToken);

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

                // 记录原始到期时间
                var originalEffectiveTo = subscription.EffectiveTo;

                // 计算新的到期时间
                var newEffectiveTo = subscription.EffectiveTo;
                if (extendMonths > 0)
                {
                    newEffectiveTo = newEffectiveTo.AddMonths(extendMonths);
                }
                if (extendDays > 0)
                {
                    newEffectiveTo = newEffectiveTo.AddDays(extendDays);
                }

                subscription.EffectiveTo = newEffectiveTo;

                // 更新备注
                if (!string.IsNullOrWhiteSpace(request.Notes))
                {
                    subscription.Notes = request.Notes;
                }

                // 记录变更历史
                var history = new TenantSubscriptionHistory
                {
                    Id = idGenerator.NextId(),
                    TenantId = subscription.TenantId,
                    TenantSubscriptionId = subscription.Id,
                    FromPackageId = subscription.TenantPackageId,
                    ToPackageId = subscription.TenantPackageId,
                    ChangeType = SubscriptionChangeType.Renew,
                    EffectiveFrom = originalEffectiveTo,
                    EffectiveTo = newEffectiveTo,
                    Amount = null,
                    Currency = null,
                    Notes = request.Notes ?? $"批量延期: {(extendMonths > 0 ? $"{extendMonths}个月" : "")}{(extendDays > 0 ? $"{extendDays}天" : "")}"
                };

                await subscriptionRepository.AddHistoryAsync(history, cancellationToken);
                await subscriptionRepository.UpdateAsync(subscription, cancellationToken);
                successCount++;
            }
            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 = "BatchExtend",
            TargetType = "Subscription",
            TargetIds = JsonSerializer.Serialize(request.SubscriptionIds),
            Parameters = JsonSerializer.Serialize(new { request.DurationDays, request.DurationMonths, request.Notes }),
            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 BatchExtendResult
        {
            SuccessCount = successCount,
            FailureCount = failures.Count,
            Failures = failures
        };
    }
}
