using HoneyBox.Admin.Business.Models;
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 RewardService : IRewardService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly ILogger<RewardService> _logger;

    /// <summary>
    /// 奖励类型名称映射
    /// </summary>
    private static readonly Dictionary<int, string> RewardTypeNames = new()
    {
        { 1, "钻石" },
        { 2, "HH币" },
        { 3, "哈尼券" },
        { 4, "优惠券" }
    };

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

    /// <inheritdoc />
    public async Task<PagedResult<RewardResponse>> GetRewardsAsync(RewardListRequest request)
    {
        var query = _dbContext.Rewards.AsNoTracking();

        // 按奖励类型筛选
        if (request.RewardType.HasValue)
        {
            query = query.Where(r => r.RewardType == request.RewardType.Value);
        }

        // 按关键词搜索（搜索描述）
        if (!string.IsNullOrWhiteSpace(request.Keyword))
        {
            query = query.Where(r => r.Description != null && r.Description.Contains(request.Keyword));
        }

        // 按奖励ID筛选（模糊搜索）
        if (!string.IsNullOrWhiteSpace(request.RewardId))
        {
            query = query.Where(r => r.RewardId.Contains(request.RewardId));
        }

        var total = await query.CountAsync();

        var items = await query
            .OrderByDescending(r => r.CreatedAt)
            .Skip(request.Skip)
            .Take(request.PageSize)
            .ToListAsync();

        // 获取优惠券类型的奖励关联的优惠券信息
        var couponIds = items
            .Where(r => r.RewardType == 4 && r.RewardExtend.HasValue)
            .Select(r => r.RewardExtend!.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(r => MapToResponse(r, coupons)).ToList();

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


    /// <inheritdoc />
    public async Task<RewardResponse?> GetRewardByIdAsync(int id)
    {
        var entity = await _dbContext.Rewards
            .AsNoTracking()
            .FirstOrDefaultAsync(r => r.Id == id);

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

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

        return MapToResponse(entity, coupons);
    }

    /// <inheritdoc />
    public async Task<List<RewardResponse>> GetRewardsByRewardIdAsync(string rewardId)
    {
        if (string.IsNullOrWhiteSpace(rewardId))
        {
            return new List<RewardResponse>();
        }

        var items = await _dbContext.Rewards
            .AsNoTracking()
            .Where(r => r.RewardId == rewardId)
            .OrderBy(r => r.Id)
            .ToListAsync();

        // 获取优惠券类型的奖励关联的优惠券信息
        var couponIds = items
            .Where(r => r.RewardType == 4 && r.RewardExtend.HasValue)
            .Select(r => r.RewardExtend!.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>();

        return items.Select(r => MapToResponse(r, coupons)).ToList();
    }

    /// <inheritdoc />
    public async Task<int> CreateRewardAsync(RewardCreateRequest request)
    {
        // 验证请求
        ValidateCreateRequest(request);

        var entity = new Reward
        {
            RewardId = request.RewardId ?? GenerateRewardId(),
            RewardType = request.RewardType,
            RewardExtend = request.RewardExtend,
            RewardValue = request.RewardValue,
            Description = request.Description,
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now
        };

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

        _logger.LogInformation("创建奖励成功: Id={Id}, RewardId={RewardId}, Type={Type}",
            entity.Id, entity.RewardId, entity.RewardType);

        return entity.Id;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateRewardAsync(int id, RewardUpdateRequest request)
    {
        var entity = await _dbContext.Rewards.FirstOrDefaultAsync(r => r.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "奖励不存在");
        }

        // 验证请求
        ValidateUpdateRequest(request);

        entity.RewardType = request.RewardType;
        entity.RewardExtend = request.RewardExtend;
        entity.RewardValue = request.RewardValue;
        entity.Description = request.Description;
        entity.UpdatedAt = DateTime.Now;

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

        _logger.LogInformation("更新奖励成功: Id={Id}", id);

        return result;
    }

    /// <inheritdoc />
    public async Task<bool> DeleteRewardAsync(int id)
    {
        var entity = await _dbContext.Rewards.FirstOrDefaultAsync(r => r.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "奖励不存在");
        }

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

        _logger.LogInformation("删除奖励成功: Id={Id}", id);

        return result;
    }


    /// <inheritdoc />
    public async Task<bool> BatchUpdateRewardsAsync(RewardBatchRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.RewardId))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖励ID不能为空");
        }

        // 删除原有的奖励
        var existingRewards = await _dbContext.Rewards
            .Where(r => r.RewardId == request.RewardId)
            .ToListAsync();

        if (existingRewards.Count > 0)
        {
            _dbContext.Rewards.RemoveRange(existingRewards);
        }

        // 创建新的奖励
        if (request.Rewards.Count > 0)
        {
            var newRewards = request.Rewards.Select((item, index) => new Reward
            {
                RewardId = request.RewardId,
                RewardType = item.RewardType,
                RewardExtend = item.RewardExtend,
                RewardValue = item.RewardValue,
                Description = item.Description,
                CreatedAt = DateTime.Now,
                UpdatedAt = DateTime.Now
            }).ToList();

            // 验证每个奖励项
            foreach (var reward in newRewards)
            {
                ValidateRewardItem(reward);
            }

            _dbContext.Rewards.AddRange(newRewards);
        }

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

        _logger.LogInformation("批量更新奖励成功: RewardId={RewardId}, Count={Count}",
            request.RewardId, request.Rewards.Count);

        return result;
    }

    #region Private Helper Methods

    /// <summary>
    /// 生成奖励ID
    /// </summary>
    private static string GenerateRewardId()
    {
        return $"reward_{DateTime.Now:yyyyMMddHHmmss}_{Guid.NewGuid():N}"[..32];
    }

    /// <summary>
    /// 验证创建请求
    /// </summary>
    private void ValidateCreateRequest(RewardCreateRequest request)
    {
        if (request.RewardType < 1 || request.RewardType > 4)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖励类型必须为1-4");
        }

        // 优惠券类型必须有优惠券ID
        if (request.RewardType == 4)
        {
            if (!request.RewardExtend.HasValue || request.RewardExtend.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "优惠券类型必须选择优惠券");
            }
        }
        else
        {
            // 非优惠券类型必须有奖励数值
            if (request.RewardValue <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖励数值必须大于0");
            }
        }
    }

    /// <summary>
    /// 验证更新请求
    /// </summary>
    private void ValidateUpdateRequest(RewardUpdateRequest request)
    {
        if (request.RewardType < 1 || request.RewardType > 4)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖励类型必须为1-4");
        }

        // 优惠券类型必须有优惠券ID
        if (request.RewardType == 4)
        {
            if (!request.RewardExtend.HasValue || request.RewardExtend.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "优惠券类型必须选择优惠券");
            }
        }
        else
        {
            // 非优惠券类型必须有奖励数值
            if (request.RewardValue <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖励数值必须大于0");
            }
        }
    }

    /// <summary>
    /// 验证奖励项
    /// </summary>
    private void ValidateRewardItem(Reward reward)
    {
        if (reward.RewardType < 1 || reward.RewardType > 4)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖励类型必须为1-4");
        }

        // 优惠券类型必须有优惠券ID
        if (reward.RewardType == 4)
        {
            if (!reward.RewardExtend.HasValue || reward.RewardExtend.Value <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "优惠券类型必须选择优惠券");
            }
        }
        else
        {
            // 非优惠券类型必须有奖励数值
            if (reward.RewardValue <= 0)
            {
                throw new BusinessException(BusinessErrorCodes.ValidationFailed, "奖励数值必须大于0");
            }
        }
    }

    /// <summary>
    /// 将实体映射为响应模型
    /// </summary>
    private static RewardResponse MapToResponse(Reward entity, Dictionary<int, Coupon> coupons)
    {
        var response = new RewardResponse
        {
            Id = entity.Id,
            RewardId = entity.RewardId,
            RewardType = entity.RewardType,
            RewardTypeName = RewardTypeNames.GetValueOrDefault(entity.RewardType, "未知"),
            RewardExtend = entity.RewardExtend,
            RewardValue = entity.RewardValue,
            Description = entity.Description,
            CreatedAt = entity.CreatedAt,
            UpdatedAt = entity.UpdatedAt
        };

        // 如果是优惠券类型，添加优惠券信息
        if (entity.RewardType == 4 && entity.RewardExtend.HasValue &&
            coupons.TryGetValue(entity.RewardExtend.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
}
