using Microsoft.Extensions.Logging;
using Volo.Abp.Domain.Services;
using Yi.Framework.AiHub.Domain.Entities;
using Yi.Framework.AiHub.Domain.Shared.Enums;
using Yi.Framework.SqlSugarCore.Abstractions;

namespace Yi.Framework.AiHub.Domain.Managers;

/// <summary>
/// 尊享包管理器
/// </summary>
public class PremiumPackageManager : DomainService
{
    private readonly ISqlSugarRepository<PremiumPackageAggregateRoot, Guid> _premiumPackageRepository;
    private readonly ILogger<PremiumPackageManager> _logger;
    private readonly ISqlSugarRepository<AiRechargeAggregateRoot> _rechargeRepository;

    public PremiumPackageManager(
        ISqlSugarRepository<PremiumPackageAggregateRoot, Guid> premiumPackageRepository,
        ILogger<PremiumPackageManager> logger, ISqlSugarRepository<AiRechargeAggregateRoot> rechargeRepository)
    {
        _premiumPackageRepository = premiumPackageRepository;
        _logger = logger;
        _rechargeRepository = rechargeRepository;
    }

    /// <summary>
    /// 为用户创建尊享包
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="packageName"></param>
    /// <param name="totalAmount">支付金额</param>
    /// <param name="remark"></param>
    /// <param name="expireMonths">过期月数，0或null表示永久</param>
    /// <param name="tokenAmount"></param>
    /// <param name="isCreateRechargeRecord">是否创建订单，如果只购买尊享包，才需要单独创建订单，如果和会员组合一起购买，只需要创建会员套餐订单即可</param>
    /// <returns></returns>
    public async Task<PremiumPackageAggregateRoot> CreatePremiumPackageAsync(
        Guid userId,
        long tokenAmount,
        string packageName,
        decimal totalAmount,
        string remark,
        int? expireMonths = null,
        bool isCreateRechargeRecord = true)
    {
        var premiumPackage = new PremiumPackageAggregateRoot(userId, tokenAmount, packageName)
        {
            PurchaseAmount = totalAmount
        };

        // 设置到期时间
        if (expireMonths.HasValue && expireMonths.Value > 0)
        {
            premiumPackage.SetExpireDateTime(DateTime.Now.AddMonths(expireMonths.Value));
        }

        await _premiumPackageRepository.InsertAsync(premiumPackage);

        if (isCreateRechargeRecord)
        {
            // 创建充值记录
            var rechargeRecord = new AiRechargeAggregateRoot
            {
                UserId = userId,
                RechargeAmount = totalAmount,
                Content = packageName,
                ExpireDateTime = premiumPackage.ExpireDateTime,
                Remark = remark,
                ContactInfo = null,
                RechargeType = RechargeTypeEnum.PremiumPackage
            };

            // 保存充值记录到数据库
            await _rechargeRepository.InsertAsync(rechargeRecord);
        }


        _logger.LogInformation(
            $"用户 {userId} 购买尊享包成功: {packageName}, Token数量: {tokenAmount}, 金额: {totalAmount}");

        return premiumPackage;
    }

    /// <summary>
    /// 消耗用户尊享包的Token
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="tokenCount">需要消耗的Token数量</param>
    /// <returns>是否消耗成功</returns>
    public async Task<bool> TryConsumeTokensAsync(Guid userId, long tokenCount)
    {
        // 获取用户所有可用的尊享包，按剩余token升序排列（优先消耗快用完的）
        var availablePackages = await _premiumPackageRepository._DbQueryable
            .Where(x => x.UserId == userId && x.IsActive)
            .OrderBy(x => x.CreationTime)
            .ToListAsync();

        if (!availablePackages.Any())
        {
            _logger.LogWarning($"用户 {userId} 没有可用的尊享包");
            return false;
        }

        // 过滤掉已过期的包
        var validPackages = availablePackages
            .Where(p => p.IsAvailable())
            .ToList();

        if (!validPackages.Any())
        {
            _logger.LogWarning($"用户 {userId} 的尊享包已全部过期");
            return false;
        }

        var firstPackage = validPackages.First();
        // 直接扣除最早的token包需要消耗的token，允许扣减到负数
        firstPackage.ConsumeTokens(tokenCount);
        await _premiumPackageRepository.UpdateAsync(firstPackage);

        return true;
    }

    /// <summary>
    /// 获取用户可用的尊享包总Token数
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>可用Token总数</returns>
    public async Task<long> GetAvailableTokensAsync(Guid userId)
    {
        return await _premiumPackageRepository._DbQueryable
            .Where(x => x.UserId == userId && x.IsActive && x.RemainingTokens > 0)
            .Where(p => p.IsActive)
            .Where(p => !p.ExpireDateTime.HasValue || p.ExpireDateTime.Value >= DateTime.Now)
            .SumAsync(p => p.RemainingTokens);
    }
}