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 UpdateStatusCommandHandler(ISubscriptionRepository subscriptionRepository)
    : IRequestHandler<UpdateStatusCommand, SubscriptionListDto?>
{
    /// <inheritdoc />
    public async Task<SubscriptionListDto?> Handle(
        UpdateStatusCommand request,
        CancellationToken cancellationToken)
    {
        // 1. 获取订阅（带跟踪）
        var subscription = await subscriptionRepository.GetByIdForUpdateAsync(request.SubscriptionId, cancellationToken);

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

        // 3. 更新状态
        var oldStatus = subscription.Status;
        subscription.Status = request.Status;

        // 4. 更新备注（如果提供）
        if (!string.IsNullOrWhiteSpace(request.Notes))
        {
            var existingNotes = subscription.Notes ?? string.Empty;
            var statusNote = $"[状态变更: {oldStatus} -> {request.Status}] {request.Notes}";
            subscription.Notes = string.IsNullOrWhiteSpace(existingNotes)
                ? statusNote
                : $"{existingNotes}\n{statusNote}";
        }

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

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

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

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

        // 9. 映射为 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
        };
    }
}
