using MediatR;
using TakeoutSaaS.Application.App.Subscriptions.Commands;
using TakeoutSaaS.Application.App.Subscriptions.Contracts;
using TakeoutSaaS.Domain.Tenants.Repositories;

namespace TakeoutSaaS.Application.App.Subscriptions.Handlers;

/// <summary>
/// 延期订阅命令处理器。
/// </summary>
public sealed class ExtendSubscriptionCommandHandler(ISubscriptionRepository subscriptionRepository)
    : IRequestHandler<ExtendSubscriptionCommand, SubscriptionListDto?>
{
    /// <inheritdoc />
    public async Task<SubscriptionListDto?> Handle(
        ExtendSubscriptionCommand request,
        CancellationToken cancellationToken)
    {
        // 1. 获取订阅（带跟踪）
        var subscription = await subscriptionRepository.GetByIdForUpdateAsync(request.SubscriptionId, cancellationToken);

        // 2. 如果不存在，返回 null
        if (subscription is null)
        {
            return null;
        }

        // 3. 延期到期时间
        subscription.EffectiveTo = subscription.EffectiveTo.AddMonths(request.DurationMonths);

        // 4. 更新下次计费时间（如果有）
        if (subscription.NextBillingDate.HasValue)
        {
            subscription.NextBillingDate = subscription.NextBillingDate.Value.AddMonths(request.DurationMonths);
        }

        // 5. 更新备注（如果提供）
        if (!string.IsNullOrWhiteSpace(request.Notes))
        {
            var existingNotes = subscription.Notes ?? string.Empty;
            var extendNote = $"[延期 {request.DurationMonths} 个月] {request.Notes}";
            subscription.Notes = string.IsNullOrWhiteSpace(existingNotes)
                ? extendNote
                : $"{existingNotes}\n{extendNote}";
        }

        // 6. 更新时间戳
        subscription.UpdatedAt = DateTime.UtcNow;

        // 7. 保存变更
        await subscriptionRepository.SaveChangesAsync(cancellationToken);

        // 8. 获取更新后的订阅信息
        var result = await subscriptionRepository.GetListResultByIdAsync(request.SubscriptionId, cancellationToken);

        // 9. 如果不存在，返回 null
        if (result is null)
        {
            return null;
        }

        // 10. 映射为 DTO 并返回
        return new SubscriptionListDto
        {
            Id = result.Id,
            TenantId = result.TenantId,
            TenantName = result.TenantName,
            TenantCode = result.TenantCode,
            TenantPackageId = result.TenantPackageId,
            PackageName = result.PackageName,
            ScheduledPackageId = result.ScheduledPackageId,
            ScheduledPackageName = result.ScheduledPackageName,
            Status = result.Status,
            EffectiveFrom = result.EffectiveFrom,
            EffectiveTo = result.EffectiveTo,
            NextBillingDate = result.NextBillingDate,
            AutoRenew = result.AutoRenew,
            Notes = result.Notes,
            CreatedAt = result.CreatedAt,
            UpdatedAt = result.UpdatedAt
        };
    }
}
