using HoneyBox.Core.Interfaces;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace HoneyBox.Core.Services;

/// <summary>
/// 奖励发放服务实现
/// 支持发放钻石、UU币、达达券、优惠券等奖励
/// </summary>
public class RewardService : IRewardService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly ILogger<RewardService> _logger;

    public RewardService(HoneyBoxDbContext dbContext, ILogger<RewardService> logger)
    {
        _dbContext = dbContext;
        _logger = logger;
    }

    /// <inheritdoc />
    public async Task<RewardSendResult> SendRewardAsync(int userId, string rewardId, string source = "系统奖励")
    {
        return await SendRewardInternalAsync(userId, rewardId, 1, source);
    }

    /// <inheritdoc />
    public async Task<RewardSendResult> SendRewardMultipleAsync(int userId, string rewardId, int multiple, string source = "系统奖励")
    {
        return await SendRewardInternalAsync(userId, rewardId, multiple, source);
    }

    /// <summary>
    /// 内部发放奖励方法
    /// </summary>
    private async Task<RewardSendResult> SendRewardInternalAsync(int userId, string rewardId, int multiple, string source)
    {
        var result = new RewardSendResult { Success = false };

        if (userId <= 0)
        {
            result.Message = "用户ID不能为空";
            return result;
        }

        if (string.IsNullOrWhiteSpace(rewardId))
        {
            result.Message = "奖励ID不能为空";
            return result;
        }

        try
        {
            // 获取奖励配置
            var rewards = await _dbContext.Rewards
                .Where(r => r.RewardId == rewardId)
                .ToListAsync();

            if (!rewards.Any())
            {
                result.Message = "未找到有效奖励";
                _logger.LogWarning("Reward not found: RewardId={RewardId}", rewardId);
                return result;
            }

            // 获取用户
            var user = await _dbContext.Users.FindAsync(userId);
            if (user == null)
            {
                result.Message = "用户不存在";
                return result;
            }

            // 逐个发放奖励
            foreach (var reward in rewards)
            {
                var detail = await SendSingleRewardAsync(userId, user, reward, multiple, source);
                result.Details.Add(detail);
            }

            await _dbContext.SaveChangesAsync();

            result.Success = result.Details.All(d => d.Success);
            result.Message = result.Success ? "奖励发放成功" : "部分奖励发放失败";

            _logger.LogInformation("Reward sent: UserId={UserId}, RewardId={RewardId}, Multiple={Multiple}, Success={Success}",
                userId, rewardId, multiple, result.Success);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to send reward: UserId={UserId}, RewardId={RewardId}", userId, rewardId);
            result.Message = "奖励发放失败";
        }

        return result;
    }


    /// <summary>
    /// 发放单个奖励
    /// </summary>
    private async Task<RewardSendDetail> SendSingleRewardAsync(int userId, User user, Reward reward, int multiple, string source)
    {
        var detail = new RewardSendDetail
        {
            RewardId = reward.Id,
            RewardType = reward.RewardType,
            Success = false
        };

        var rewardValue = reward.RewardValue * multiple;

        try
        {
            switch (reward.RewardType)
            {
                case 1: // 钻石 (Money)
                    await AddMoneyAsync(userId, user, rewardValue, source);
                    detail.Success = true;
                    detail.Message = $"获得钻石*{rewardValue}";
                    break;

                case 2: // HH币 (Integral)
                    await AddIntegralAsync(userId, user, rewardValue, source);
                    detail.Success = true;
                    detail.Message = $"获得HH币*{rewardValue}";
                    break;

                case 3: // 哈尼券 (Money2)
                    await AddMoney2Async(userId, user, rewardValue, source);
                    detail.Success = true;
                    detail.Message = $"获得哈尼券*{rewardValue}";
                    break;

                case 4: // 优惠券
                    var couponResult = await AddCouponAsync(userId, reward.RewardExtend, (int)rewardValue);
                    detail.Success = couponResult.success;
                    detail.Message = couponResult.message;
                    break;

                default:
                    detail.Message = "不支持的奖励类型";
                    break;
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to send single reward: UserId={UserId}, RewardType={RewardType}",
                userId, reward.RewardType);
            detail.Message = "奖励发放失败";
        }

        return detail;
    }

    /// <summary>
    /// 增加钻石
    /// </summary>
    private async Task AddMoneyAsync(int userId, User user, decimal amount, string source)
    {
        user.Money += amount;

        var profit = new ProfitMoney
        {
            UserId = userId,
            Type = 6, // 奖励赠送
            ChangeMoney = amount,
            Money = user.Money,
            Content = source,
            ShareUid = 0,
            CreatedAt = DateTime.Now
        };
        _dbContext.ProfitMoneys.Add(profit);

        _logger.LogInformation("Money added: UserId={UserId}, Amount={Amount}, Source={Source}",
            userId, amount, source);
    }

    /// <summary>
    /// 增加UU币（积分）
    /// </summary>
    private async Task AddIntegralAsync(int userId, User user, decimal amount, string source)
    {
        user.Integral += amount;

        var profit = new ProfitIntegral
        {
            UserId = userId,
            Type = 6, // 奖励赠送
            ChangeMoney = amount,
            Money = user.Integral,
            Content = source,
            ShareUid = 0,
            CreatedAt = DateTime.Now
        };
        _dbContext.ProfitIntegrals.Add(profit);

        _logger.LogInformation("Integral added: UserId={UserId}, Amount={Amount}, Source={Source}",
            userId, amount, source);
    }

    /// <summary>
    /// 增加达达券
    /// </summary>
    private async Task AddMoney2Async(int userId, User user, decimal amount, string source)
    {
        user.Money2 = (user.Money2 ?? 0) + amount;

        var profit = new ProfitMoney2
        {
            UserId = userId,
            Type = 6, // 奖励赠送
            ChangeMoney = amount,
            Money = user.Money2 ?? 0,
            Content = source,
            ShareUid = 0,
            CreatedAt = DateTime.Now
        };
        _dbContext.ProfitMoney2s.Add(profit);

        _logger.LogInformation("Money2 added: UserId={UserId}, Amount={Amount}, Source={Source}",
            userId, amount, source);
    }

    /// <summary>
    /// 发放优惠券
    /// </summary>
    private async Task<(bool success, string message)> AddCouponAsync(int userId, int? couponId, int quantity = 1)
    {
        if (!couponId.HasValue || couponId.Value <= 0)
        {
            return (false, "优惠券ID不能为空");
        }

        var coupon = await _dbContext.Coupons.FindAsync(couponId.Value);
        if (coupon == null)
        {
            return (false, "优惠券不存在");
        }

        var ttype = coupon.Ttype ?? 0;
        var effectiveDays = coupon.EffectiveDay ?? 7;

        for (int i = 0; i < quantity; i++)
        {
            var couponReceive = new CouponReceife
            {
                UserId = userId,
                Title = coupon.Title,
                Price = coupon.Price,
                ManPrice = coupon.ManPrice,
                EndTime = DateTime.Now.AddDays(effectiveDays),
                CouponId = coupon.Id,
                State = 0, // 未使用
                Status = 1, // 启用
                Ttype = ttype,
                CreatedAt = DateTime.Now
            };
            _dbContext.CouponReceives.Add(couponReceive);
        }

        _logger.LogInformation("Coupon added: UserId={UserId}, CouponId={CouponId}, Quantity={Quantity}",
            userId, couponId, quantity);

        return (true, "优惠券发放成功");
    }
}
