using HoneyBox.Admin.Business.Models;
using HoneyBox.Admin.Business.Models.Reward;
using HoneyBox.Admin.Business.Models.SignConfig;
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 SignConfigService : ISignConfigService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly ILogger<SignConfigService> _logger;

    /// <summary>
    /// 签到类型名称映射
    /// </summary>
    private static readonly Dictionary<int, string> SignTypeNames = new()
    {
        { 1, "每日签到" },
        { 2, "累计签到" }
    };

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

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

    /// <inheritdoc />
    public async Task<PagedResult<SignConfigResponse>> GetSignConfigsAsync(SignConfigListRequest request)
    {
        var query = _dbContext.SignConfigs.AsNoTracking();

        // 按签到类型筛选
        query = query.Where(s => s.Type == request.Type);

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

        var total = await query.CountAsync();

        var items = await query
            .OrderBy(s => s.Sort)
            .ThenByDescending(s => s.CreatedAt)
            .Skip(request.Skip)
            .Take(request.PageSize)
            .ToListAsync();

        // 获取所有签到配置的奖励ID
        var rewardIds = items.Select(s => s.RewardId).Distinct().ToList();

        // 批量获取奖励信息
        var rewards = await GetRewardsByRewardIdsAsync(rewardIds);

        var list = items.Select(s => MapToResponse(s, rewards)).ToList();

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

    /// <inheritdoc />
    public async Task<SignConfigResponse?> GetSignConfigByIdAsync(int id)
    {
        var entity = await _dbContext.SignConfigs
            .AsNoTracking()
            .FirstOrDefaultAsync(s => s.Id == id);

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

        // 获取关联的奖励信息
        var rewards = await GetRewardsByRewardIdsAsync(new List<string> { entity.RewardId });

        return MapToResponse(entity, rewards);
    }

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

        // 生成奖励ID
        var rewardId = GenerateRewardId("sign");

        // 创建签到配置
        var entity = new Model.Entities.SignConfig
        {
            Type = (byte)request.Type,
            Day = request.Day.HasValue ? (byte)request.Day.Value : null,
            Title = request.Title,
            Icon = request.Icon,
            Status = 1, // 默认启用
            Sort = request.Sort ?? 0,
            RewardId = rewardId,
            Description = request.Description,
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now
        };

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

        // 创建关联的奖励
        if (request.Rewards.Count > 0)
        {
            await CreateRewardsAsync(rewardId, request.Rewards);
        }

        _logger.LogInformation("创建签到配置成功: Id={Id}, Type={Type}, Title={Title}",
            entity.Id, entity.Type, entity.Title);

        return entity.Id;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateSignConfigAsync(int id, SignConfigUpdateRequest request)
    {
        var entity = await _dbContext.SignConfigs.FirstOrDefaultAsync(s => s.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "签到配置不存在");
        }

        // 验证请求
        ValidateUpdateRequest(request);

        entity.Type = (byte)request.Type;
        entity.Day = request.Day.HasValue ? (byte)request.Day.Value : null;
        entity.Title = request.Title;
        entity.Icon = request.Icon;
        entity.Sort = request.Sort ?? 0;
        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> DeleteSignConfigAsync(int id)
    {
        var entity = await _dbContext.SignConfigs.FirstOrDefaultAsync(s => s.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "签到配置不存在");
        }

        // 删除关联的奖励
        var rewards = await _dbContext.Rewards
            .Where(r => r.RewardId == entity.RewardId)
            .ToListAsync();

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

        // 删除签到配置
        _dbContext.SignConfigs.Remove(entity);
        var result = await _dbContext.SaveChangesAsync() > 0;

        _logger.LogInformation("删除签到配置成功: Id={Id}", id);

        return result;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateSignConfigStatusAsync(int id, int status)
    {
        var entity = await _dbContext.SignConfigs.FirstOrDefaultAsync(s => s.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "签到配置不存在");
        }

        if (status != 0 && status != 1)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "状态值必须为0或1");
        }

        entity.Status = (byte)status;
        entity.UpdatedAt = DateTime.Now;

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

        _logger.LogInformation("更新签到配置状态成功: Id={Id}, Status={Status}", id, status);

        return result;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateSignConfigSortAsync(int id, int sort)
    {
        var entity = await _dbContext.SignConfigs.FirstOrDefaultAsync(s => s.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "签到配置不存在");
        }

        entity.Sort = sort;
        entity.UpdatedAt = DateTime.Now;

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

        _logger.LogInformation("更新签到配置排序成功: Id={Id}, Sort={Sort}", id, sort);

        return result;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateSignConfigRewardAsync(int id, SignConfigRewardRequest request)
    {
        var entity = await _dbContext.SignConfigs.FirstOrDefaultAsync(s => s.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "签到配置不存在");
        }

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

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

        // 创建新的奖励
        if (request.Rewards.Count > 0)
        {
            await CreateRewardsAsync(entity.RewardId, request.Rewards);
        }

        entity.UpdatedAt = DateTime.Now;
        var result = await _dbContext.SaveChangesAsync() >= 0;

        _logger.LogInformation("更新签到配置奖励成功: Id={Id}, RewardCount={Count}", id, request.Rewards.Count);

        return result;
    }


    #region Private Helper Methods

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

    /// <summary>
    /// 验证创建请求
    /// </summary>
    private void ValidateCreateRequest(SignConfigCreateRequest request)
    {
        if (request.Type < 1 || request.Type > 2)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "签到类型必须为1或2");
        }

        if (string.IsNullOrWhiteSpace(request.Title))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "标题不能为空");
        }

        if (!request.Day.HasValue || request.Day.Value <= 0)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "签到天数必须大于0");
        }
    }

    /// <summary>
    /// 验证更新请求
    /// </summary>
    private void ValidateUpdateRequest(SignConfigUpdateRequest request)
    {
        if (request.Type < 1 || request.Type > 2)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "签到类型必须为1或2");
        }

        if (string.IsNullOrWhiteSpace(request.Title))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "标题不能为空");
        }

        if (!request.Day.HasValue || request.Day.Value <= 0)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "签到天数必须大于0");
        }
    }

    /// <summary>
    /// 创建奖励
    /// </summary>
    private async Task CreateRewardsAsync(string rewardId, List<RewardItem> rewards)
    {
        var newRewards = rewards.Select(item => new Reward
        {
            RewardId = 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);
        await _dbContext.SaveChangesAsync();
    }

    /// <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>
    /// 根据奖励ID列表获取奖励信息
    /// </summary>
    private async Task<Dictionary<string, List<RewardResponse>>> GetRewardsByRewardIdsAsync(List<string> rewardIds)
    {
        if (rewardIds.Count == 0)
        {
            return new Dictionary<string, List<RewardResponse>>();
        }

        var rewards = await _dbContext.Rewards
            .AsNoTracking()
            .Where(r => rewardIds.Contains(r.RewardId))
            .ToListAsync();

        // 获取优惠券类型的奖励关联的优惠券信息
        var couponIds = rewards
            .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 rewards
            .GroupBy(r => r.RewardId)
            .ToDictionary(
                g => g.Key,
                g => g.Select(r => MapRewardToResponse(r, coupons)).ToList()
            );
    }

    /// <summary>
    /// 将签到配置实体映射为响应模型
    /// </summary>
    private SignConfigResponse MapToResponse(Model.Entities.SignConfig entity, Dictionary<string, List<RewardResponse>> rewards)
    {
        return new SignConfigResponse
        {
            Id = entity.Id,
            Type = entity.Type,
            TypeName = SignTypeNames.GetValueOrDefault(entity.Type, "未知"),
            Day = entity.Day,
            Title = entity.Title,
            Icon = entity.Icon,
            Status = entity.Status,
            Sort = entity.Sort,
            RewardId = entity.RewardId,
            Description = entity.Description,
            CreatedAt = entity.CreatedAt,
            UpdatedAt = entity.UpdatedAt,
            Rewards = rewards.GetValueOrDefault(entity.RewardId, new List<RewardResponse>())
        };
    }

    /// <summary>
    /// 将奖励实体映射为响应模型
    /// </summary>
    private static RewardResponse MapRewardToResponse(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
}
