using HoneyBox.Admin.Business.Models;
using HoneyBox.Admin.Business.Models.QyLevel;
using HoneyBox.Admin.Business.Models.Reward;
using HoneyBox.Admin.Business.Services.Interfaces;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace HoneyBox.Admin.Business.Services;

/// <summary>
/// 权益等级管理服务实现
/// </summary>
public class QyLevelService : IQyLevelService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly ILogger<QyLevelService> _logger;

    /// <summary>
    /// 奖品类型名称映射
    /// </summary>
    private static readonly Dictionary<int, string> PrizeTypeNames = new()
    {
        { 1, "优惠券" },
        { 2, "实物奖品" }
    };

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

    #region 权益等级操作

    /// <inheritdoc />
    public async Task<PagedResult<QyLevelResponse>> GetQyLevelsAsync(QyLevelListRequest request)
    {
        // 使用 EquityLevels 表
        var query = _dbContext.EquityLevels
            .AsNoTracking()
            .Where(e => e.DeletedAt == null && e.Level > 0);

        // 按关键词搜索（搜索名称）
        if (!string.IsNullOrWhiteSpace(request.Keyword))
        {
            query = query.Where(e => e.Title.Contains(request.Keyword));
        }

        var total = await query.CountAsync();

        var items = await query
            .OrderBy(e => e.Level)
            .Skip(request.Skip)
            .Take(request.PageSize)
            .ToListAsync();

        var list = items.Select(MapEquityLevelToResponse).ToList();

        return PagedResult<QyLevelResponse>.Create(list, total, request.Page, request.PageSize);
    }


    /// <inheritdoc />
    public async Task<QyLevelResponse?> GetQyLevelByIdAsync(int id)
    {
        var entity = await _dbContext.EquityLevels
            .AsNoTracking()
            .FirstOrDefaultAsync(e => e.Id == id && e.DeletedAt == null);

        return entity == null ? null : MapEquityLevelToResponse(entity);
    }

    /// <inheritdoc />
    public async Task<bool> UpdateQyLevelAsync(int id, QyLevelUpdateRequest request)
    {
        var entity = await _dbContext.EquityLevels
            .FirstOrDefaultAsync(e => e.Id == id && e.DeletedAt == null);

        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "权益等级不存在");
        }

        // 验证请求
        ValidateQyLevelUpdateRequest(request);

        entity.Level = request.Level;
        entity.Title = request.Title;
        entity.Number = request.RequiredPoints;
        entity.UpdatedAt = DateTime.Now;

        var result = await _dbContext.SaveChangesAsync() > 0;

        _logger.LogInformation("更新权益等级成功: Id={Id}, Level={Level}", id, request.Level);

        return result;
    }

    /// <inheritdoc />
    public async Task<int> CreateQyLevelAsync(QyLevelCreateRequest request)
    {
        // 验证请求
        if (string.IsNullOrWhiteSpace(request.Title))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "等级名称不能为空");
        }

        if (request.Level < 0)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "等级不能为负数");
        }

        if (request.RequiredPoints < 0)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "所需欧气值不能为负数");
        }

        // 检查等级是否已存在
        var existingLevel = await _dbContext.EquityLevels
            .FirstOrDefaultAsync(e => e.Level == request.Level && e.DeletedAt == null);

        if (existingLevel != null)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, $"等级 {request.Level} 已存在");
        }

        var entity = new EquityLevel
        {
            Level = request.Level,
            Title = request.Title,
            Number = request.RequiredPoints,
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now
        };

        _dbContext.EquityLevels.Add(entity);
        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("创建权益等级成功: Id={Id}, Level={Level}, Title={Title}", entity.Id, entity.Level, entity.Title);

        return entity.Id;
    }

    /// <inheritdoc />
    public async Task<bool> DeleteQyLevelAsync(int id)
    {
        var entity = await _dbContext.EquityLevels
            .FirstOrDefaultAsync(e => e.Id == id && e.DeletedAt == null);

        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "权益等级不存在");
        }

        // 软删除
        entity.DeletedAt = DateTime.Now;
        entity.UpdatedAt = DateTime.Now;

        var result = await _dbContext.SaveChangesAsync() > 0;

        _logger.LogInformation("删除权益等级成功: Id={Id}, Level={Level}", id, entity.Level);

        return result;
    }

    #endregion

    #region 权益等级奖品操作

    /// <inheritdoc />
    public async Task<PagedResult<QyLevelPrizeResponse>> GetQyLevelPrizesAsync(int qyLevelId, QyLevelPrizeListRequest request)
    {
        // 验证权益等级是否存在
        var qyLevel = await _dbContext.EquityLevels
            .AsNoTracking()
            .FirstOrDefaultAsync(e => e.Id == qyLevelId && e.DeletedAt == null);

        if (qyLevel == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "权益等级不存在");
        }

        // 使用 EquityLevelRewards 表
        var query = _dbContext.EquityLevelRewards
            .AsNoTracking()
            .Where(p => p.EquityLevelId == qyLevelId && p.DeletedAt == null);

        // 按奖品类型筛选
        if (request.Type.HasValue)
        {
            var typeFilter = (byte)request.Type.Value;
            query = query.Where(p => p.Type == typeFilter);
        }

        // 按关键词搜索（搜索标题）
        if (!string.IsNullOrWhiteSpace(request.Keyword))
        {
            query = query.Where(p => p.Title != null && p.Title.Contains(request.Keyword));
        }

        var total = await query.CountAsync();

        var items = await query
            .OrderBy(p => p.Id)
            .Skip(request.Skip)
            .Take(request.PageSize)
            .ToListAsync();

        // 获取优惠券类型的奖品关联的优惠券信息
        var couponIds = items
            .Where(p => p.Type == 1 && p.CouponId.HasValue)
            .Select(p => p.CouponId!.Value)
            .Distinct()
            .ToList();

        var coupons = couponIds.Count > 0
            ? await _dbContext.Coupons
                .AsNoTracking()
                .Where(c => couponIds.Contains(c.Id))
                .ToDictionaryAsync(c => c.Id)
            : new Dictionary<int, Coupon>();

        var list = items.Select(p => MapEquityLevelRewardToResponse(p, qyLevel.Level, coupons)).ToList();

        return PagedResult<QyLevelPrizeResponse>.Create(list, total, request.Page, request.PageSize);
    }

    /// <inheritdoc />
    public async Task<QyLevelPrizeResponse?> GetQyLevelPrizeByIdAsync(int prizeId)
    {
        var entity = await _dbContext.EquityLevelRewards
            .AsNoTracking()
            .FirstOrDefaultAsync(p => p.Id == prizeId && p.DeletedAt == null);

        if (entity == null)
        {
            return null;
        }

        // 获取等级信息
        var qyLevel = await _dbContext.EquityLevels
            .AsNoTracking()
            .FirstOrDefaultAsync(e => e.Id == entity.EquityLevelId);
        var level = qyLevel?.Level ?? 0;

        // 如果是优惠券类型，获取优惠券信息
        Dictionary<int, Coupon> coupons = new();
        if (entity.Type == 1 && entity.CouponId.HasValue)
        {
            var coupon = await _dbContext.Coupons
                .AsNoTracking()
                .FirstOrDefaultAsync(c => c.Id == entity.CouponId.Value);
            if (coupon != null)
            {
                coupons[coupon.Id] = coupon;
            }
        }

        return MapEquityLevelRewardToResponse(entity, level, coupons);
    }


    /// <inheritdoc />
    public async Task<int> CreateQyLevelPrizeAsync(int qyLevelId, QyLevelPrizeCreateRequest request)
    {
        // 验证权益等级是否存在
        var qyLevel = await _dbContext.EquityLevels
            .AsNoTracking()
            .FirstOrDefaultAsync(e => e.Id == qyLevelId && e.DeletedAt == null);

        if (qyLevel == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "权益等级不存在");
        }

        // 验证请求
        ValidatePrizeCreateRequest(request);

        // 优惠券类型时，如果没有标题则设置默认标题
        var title = request.Title;
        if (request.Type == 1 && string.IsNullOrEmpty(title))
        {
            title = "优惠券奖励";
        }

        var entity = new EquityLevelReward
        {
            EquityLevelId = qyLevelId,
            Type = (byte)request.Type,
            Title = title ?? "",
            CouponId = request.CouponId,
            ZNum = request.Quantity,
            JiangPrice = request.Value,
            Money = request.ExchangePrice,
            ScMoney = request.ReferencePrice,
            Probability = request.Probability,
            ImgUrl = request.Image,
            PrizeLevelId = request.ShangId,
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now
        };

        _dbContext.EquityLevelRewards.Add(entity);
        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("创建权益等级奖品成功: Id={Id}, QyLevelId={QyLevelId}, Type={Type}",
            entity.Id, qyLevelId, request.Type);

        return entity.Id;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateQyLevelPrizeAsync(int prizeId, QyLevelPrizeUpdateRequest request)
    {
        var entity = await _dbContext.EquityLevelRewards
            .FirstOrDefaultAsync(p => p.Id == prizeId && p.DeletedAt == null);

        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "奖品不存在");
        }

        // 验证请求
        ValidatePrizeUpdateRequest(request);

        // 优惠券类型时，如果没有标题则设置默认标题
        var title = request.Title;
        if (request.Type == 1 && string.IsNullOrEmpty(title))
        {
            title = "优惠券奖励";
        }

        entity.Type = (byte)request.Type;
        entity.Title = title ?? "";
        entity.CouponId = request.CouponId;
        entity.ZNum = request.Quantity;
        entity.JiangPrice = request.Value;
        entity.Money = request.ExchangePrice;
        entity.ScMoney = request.ReferencePrice;
        entity.Probability = request.Probability;
        entity.ImgUrl = request.Image;
        entity.PrizeLevelId = request.ShangId;
        entity.UpdatedAt = DateTime.Now;

        var result = await _dbContext.SaveChangesAsync() > 0;

        _logger.LogInformation("更新权益等级奖品成功: Id={Id}", prizeId);

        return result;
    }

    /// <inheritdoc />
    public async Task<bool> DeleteQyLevelPrizeAsync(int prizeId)
    {
        var entity = await _dbContext.EquityLevelRewards
            .FirstOrDefaultAsync(p => p.Id == prizeId && p.DeletedAt == null);

        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "奖品不存在");
        }

        // 软删除
        entity.DeletedAt = DateTime.Now;
        entity.UpdatedAt = DateTime.Now;

        var result = await _dbContext.SaveChangesAsync() > 0;

        _logger.LogInformation("删除权益等级奖品成功: Id={Id}", prizeId);

        return result;
    }

    #endregion


    #region Private Helper Methods

    /// <summary>
    /// 验证权益等级更新请求
    /// </summary>
    private void ValidateQyLevelUpdateRequest(QyLevelUpdateRequest request)
    {
        if (request.Level <= 0)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "等级必须大于0");
        }

        if (string.IsNullOrWhiteSpace(request.Title))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "等级名称不能为空");
        }

        if (request.RequiredPoints < 0)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "所需欧气值不能为负数");
        }
    }

    /// <summary>
    /// 验证奖品创建请求
    /// </summary>
    private void ValidatePrizeCreateRequest(QyLevelPrizeCreateRequest request)
    {
        if (request.Type < 1 || request.Type > 2)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖品类型必须为1（优惠券）或2（实物奖品）");
        }

        // 优惠券类型验证
        if (request.Type == 1)
        {
            if (!request.CouponId.HasValue || request.CouponId.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "优惠券类型必须选择优惠券");
            }

            if (!request.Quantity.HasValue || request.Quantity.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "优惠券数量必须大于0");
            }
        }
        // 实物奖品类型验证
        else if (request.Type == 2)
        {
            if (string.IsNullOrWhiteSpace(request.Title))
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "实物奖品名称不能为空");
            }

            if (!request.Value.HasValue || request.Value.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖品价值必须大于0");
            }

            if (!request.ExchangePrice.HasValue || request.ExchangePrice.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "兑换价格必须大于0");
            }

            if (!request.ReferencePrice.HasValue || request.ReferencePrice.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "市场参考价必须大于0");
            }

            if (string.IsNullOrWhiteSpace(request.Image))
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖品图片不能为空");
            }
        }

        // 概率值验证（0-100，最多2位小数）
        if (request.Probability.HasValue)
        {
            if (request.Probability.Value < 0 || request.Probability.Value > 100)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "概率值必须在0-100之间");
            }

            // 检查小数位数
            var decimalPlaces = GetDecimalPlaces(request.Probability.Value);
            if (decimalPlaces > 2)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "概率值最多保留2位小数");
            }
        }
    }

    /// <summary>
    /// 验证奖品更新请求
    /// </summary>
    private void ValidatePrizeUpdateRequest(QyLevelPrizeUpdateRequest request)
    {
        if (request.Type < 1 || request.Type > 2)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖品类型必须为1（优惠券）或2（实物奖品）");
        }

        // 优惠券类型验证
        if (request.Type == 1)
        {
            if (!request.CouponId.HasValue || request.CouponId.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "优惠券类型必须选择优惠券");
            }

            if (!request.Quantity.HasValue || request.Quantity.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "优惠券数量必须大于0");
            }
        }
        // 实物奖品类型验证
        else if (request.Type == 2)
        {
            if (string.IsNullOrWhiteSpace(request.Title))
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "实物奖品名称不能为空");
            }

            if (!request.Value.HasValue || request.Value.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖品价值必须大于0");
            }

            if (!request.ExchangePrice.HasValue || request.ExchangePrice.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "兑换价格必须大于0");
            }

            if (!request.ReferencePrice.HasValue || request.ReferencePrice.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "市场参考价必须大于0");
            }

            if (string.IsNullOrWhiteSpace(request.Image))
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖品图片不能为空");
            }
        }

        // 概率值验证（0-100，最多2位小数）
        if (request.Probability.HasValue)
        {
            if (request.Probability.Value < 0 || request.Probability.Value > 100)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "概率值必须在0-100之间");
            }

            // 检查小数位数
            var decimalPlaces = GetDecimalPlaces(request.Probability.Value);
            if (decimalPlaces > 2)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "概率值最多保留2位小数");
            }
        }
    }

    /// <summary>
    /// 获取小数位数
    /// </summary>
    private static int GetDecimalPlaces(decimal value)
    {
        var str = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
        var index = str.IndexOf('.');
        return index < 0 ? 0 : str.Length - index - 1;
    }

    /// <summary>
    /// 将 EquityLevel 实体映射为响应模型
    /// </summary>
    private static QyLevelResponse MapEquityLevelToResponse(EquityLevel entity)
    {
        return new QyLevelResponse
        {
            Id = entity.Id,
            Level = entity.Level,
            Title = entity.Title,
            RequiredPoints = entity.Number,
            CreatedAt = entity.CreatedAt,
            UpdatedAt = entity.UpdatedAt
        };
    }

    /// <summary>
    /// 将 EquityLevelReward 实体映射为奖品响应模型
    /// </summary>
    private static QyLevelPrizeResponse MapEquityLevelRewardToResponse(EquityLevelReward entity, int qyLevel, Dictionary<int, Coupon> coupons)
    {
        var typeValue = (int)entity.Type;
        var response = new QyLevelPrizeResponse
        {
            Id = entity.Id,
            QyLevelId = entity.EquityLevelId,
            QyLevel = qyLevel,
            Type = typeValue,
            TypeName = PrizeTypeNames.GetValueOrDefault(typeValue, "未知"),
            Title = entity.Title,
            CouponId = entity.CouponId,
            Quantity = entity.ZNum,
            Value = entity.JiangPrice,
            ExchangePrice = entity.Money,
            ReferencePrice = entity.ScMoney,
            Probability = entity.Probability,
            Image = entity.ImgUrl,
            PrizeCode = entity.PrizeCode,
            Sort = 0,
            CreatedAt = entity.CreatedAt,
            UpdatedAt = entity.UpdatedAt
        };

        // 如果是优惠券类型，添加优惠券信息
        if (typeValue == 1 && entity.CouponId.HasValue &&
            coupons.TryGetValue(entity.CouponId.Value, out var coupon))
        {
            response.Coupon = new CouponInfo
            {
                Id = coupon.Id,
                Title = coupon.Title,
                Price = coupon.Price,
                ManPrice = coupon.ManPrice,
                EffectiveDay = coupon.EffectiveDay
            };
        }

        return response;
    }

    #endregion
}
