// EN: Command to subscribe or upgrade merchant's plan.
// VI: Command để đăng ký hoặc nâng cấp gói của merchant.

using MediatR;
using MerchantService.Domain.AggregatesModel.MerchantAggregate;

namespace MerchantService.API.Application.Commands.Subscriptions;

/// <summary>
/// EN: Command to subscribe or upgrade to a plan.
/// VI: Command để đăng ký hoặc nâng cấp gói.
/// </summary>
/// <param name="PlanId">Plan ID (0=Starter, 1=Growth, 2=Pro, 3=Enterprise) / ID gói</param>
/// <param name="UserId">User ID extracted from JWT claims by the controller / User ID được lấy từ JWT claims bởi controller</param>
public record SubscribeCommand(int PlanId, Guid UserId = default) : IRequest<SubscribeCommandResult>;

/// <summary>
/// EN: Result of subscribe command.
/// VI: Kết quả của subscribe command.
/// </summary>
/// <param name="Success">Whether the operation was successful / Thao tác có thành công không</param>
/// <param name="Message">Result message / Thông điệp kết quả</param>
/// <param name="PlanId">Subscribed plan ID / ID gói đã đăng ký</param>
/// <param name="PlanName">Subscribed plan name / Tên gói đã đăng ký</param>
public record SubscribeCommandResult(bool Success, string Message, int PlanId, string PlanName);

/// <summary>
/// EN: Handler for SubscribeCommand.
/// VI: Handler cho SubscribeCommand.
/// </summary>
public class SubscribeCommandHandler : IRequestHandler<SubscribeCommand, SubscribeCommandResult>
{
    private readonly IMerchantRepository _merchantRepository;
    private readonly ILogger<SubscribeCommandHandler> _logger;

    public SubscribeCommandHandler(
        IMerchantRepository merchantRepository,
        ILogger<SubscribeCommandHandler> logger)
    {
        _merchantRepository = merchantRepository;
        _logger = logger;
    }

    public async Task<SubscribeCommandResult> Handle(SubscribeCommand request, CancellationToken cancellationToken)
    {
        // EN: Use user ID passed from the controller
        // VI: Dùng user ID được truyền từ controller
        var merchant = await _merchantRepository.GetByUserIdAsync(request.UserId, cancellationToken);
        if (merchant == null)
        {
            _logger.LogWarning("EN: Merchant not found for user {UserId} / VI: Không tìm thấy merchant cho user {UserId}", request.UserId);
            return new SubscribeCommandResult(false, "Merchant not found / Không tìm thấy merchant", -1, "");
        }

        // EN: Update subscription plan via domain behavior method.
        // VI: Cập nhật gói đăng ký qua domain behavior method.
        merchant.UpdateSubscriptionPlan(request.PlanId);
        _merchantRepository.Update(merchant);
        await _merchantRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        var planNames = new[] { "Starter", "Growth", "Pro", "Enterprise" };
        var planName = request.PlanId >= 0 && request.PlanId < planNames.Length ? planNames[request.PlanId] : "Unknown";

        _logger.LogInformation("EN: Merchant {MerchantId} subscribed to {PlanName} / VI: Merchant {MerchantId} đã đăng ký {PlanName}",
            merchant.Id, planName);

        return new SubscribeCommandResult(true, $"Subscribed to {planName} plan successfully", request.PlanId, planName);
    }
}
