using HoneyBox.Admin.Business.Models;
using HoneyBox.Admin.Business.Models.Goods;
using HoneyBox.Admin.Business.Services.Interfaces;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using Microsoft.EntityFrameworkCore;

namespace HoneyBox.Admin.Business.Services;

/// <summary>
/// 奖品等级服务实现
/// </summary>
public class PrizeLevelService : IPrizeLevelService
{
    private readonly HoneyBoxDbContext _dbContext;

    public PrizeLevelService(HoneyBoxDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    /// <inheritdoc />
    public async Task<PagedResult<PrizeLevelResponse>> GetPrizeLevelsAsync(PrizeLevelListRequest request)
    {
        var query = _dbContext.PrizeLevels.AsNoTracking();

        // 按标题过滤
        if (!string.IsNullOrWhiteSpace(request.Title))
        {
            query = query.Where(pl => pl.Title.Contains(request.Title));
        }

        // 获取总数
        var total = await query.CountAsync();

        // 获取列表
        var levels = await query
            .OrderBy(pl => pl.Sort)
            .ThenByDescending(pl => pl.Id)
            .Skip(request.Skip)
            .Take(request.PageSize)
            .ToListAsync();

        // 获取每个等级关联的奖品数量
        var levelIds = levels.Select(l => l.Id).ToList();
        var prizeCounts = await _dbContext.GoodsItems
            .AsNoTracking()
            .Where(gi => gi.ShangId != null && levelIds.Contains(gi.ShangId.Value))
            .GroupBy(gi => gi.ShangId)
            .Select(g => new { ShangId = g.Key, Count = g.Count() })
            .ToDictionaryAsync(x => x.ShangId ?? 0, x => x.Count);

        // 映射结果
        var list = levels.Select(pl => new PrizeLevelResponse
        {
            Id = pl.Id,
            Title = pl.Title,
            Pro = pl.Pro,
            ImgUrl = pl.ImgUrl,
            Color = pl.Color,
            SpecialImgUrl = pl.SpecialImgUrl,
            Sort = pl.Sort,
            UpdatedAt = pl.UpdatedAt,
            PrizeCount = prizeCounts.GetValueOrDefault(pl.Id, 0)
        }).ToList();

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

    /// <inheritdoc />
    public async Task<PrizeLevelResponse?> GetPrizeLevelAsync(int id)
    {
        var level = await _dbContext.PrizeLevels
            .AsNoTracking()
            .FirstOrDefaultAsync(pl => pl.Id == id);

        if (level == null) return null;

        // 获取关联奖品数量
        var prizeCount = await _dbContext.GoodsItems
            .AsNoTracking()
            .CountAsync(gi => gi.ShangId == id);

        return new PrizeLevelResponse
        {
            Id = level.Id,
            Title = level.Title,
            Pro = level.Pro,
            ImgUrl = level.ImgUrl,
            Color = level.Color,
            SpecialImgUrl = level.SpecialImgUrl,
            Sort = level.Sort,
            UpdatedAt = level.UpdatedAt,
            PrizeCount = prizeCount
        };
    }


    /// <inheritdoc />
    public async Task<int> CreatePrizeLevelAsync(PrizeLevelCreateRequest request)
    {
        var level = new PrizeLevel
        {
            Title = request.Title,
            Pro = request.Pro,
            ImgUrl = request.ImgUrl,
            Color = request.Color,
            SpecialImgUrl = request.SpecialImgUrl,
            Sort = request.Sort,
            GoodsId = 0,
            UpdatedAt = DateTime.Now
        };

        _dbContext.PrizeLevels.Add(level);
        await _dbContext.SaveChangesAsync();

        return level.Id;
    }

    /// <inheritdoc />
    public async Task<bool> UpdatePrizeLevelAsync(int id, PrizeLevelUpdateRequest request)
    {
        var level = await _dbContext.PrizeLevels.FirstOrDefaultAsync(pl => pl.Id == id);
        if (level == null) return false;

        level.Title = request.Title;
        level.Pro = request.Pro;
        level.ImgUrl = request.ImgUrl;
        level.Color = request.Color;
        level.SpecialImgUrl = request.SpecialImgUrl;
        level.Sort = request.Sort;
        level.UpdatedAt = DateTime.Now;

        await _dbContext.SaveChangesAsync();
        return true;
    }

    /// <inheritdoc />
    public async Task<bool> DeletePrizeLevelAsync(int id)
    {
        var level = await _dbContext.PrizeLevels.FirstOrDefaultAsync(pl => pl.Id == id);
        if (level == null) return false;

        // 检查是否有关联的奖品
        var hasPrizes = await _dbContext.GoodsItems.AnyAsync(gi => gi.ShangId == id);
        if (hasPrizes)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "当前等级关联有奖品，不可删除");
        }

        _dbContext.PrizeLevels.Remove(level);
        await _dbContext.SaveChangesAsync();
        return true;
    }

    /// <inheritdoc />
    public async Task<List<PrizeLevelOptionResponse>> GetPrizeLevelOptionsAsync()
    {
        return await _dbContext.PrizeLevels
            .AsNoTracking()
            .OrderBy(pl => pl.Sort)
            .ThenByDescending(pl => pl.Id)
            .Select(pl => new PrizeLevelOptionResponse
            {
                Id = pl.Id,
                Title = pl.Title,
                Color = pl.Color
            })
            .ToListAsync();
    }

    /// <inheritdoc />
    public async Task<List<PrizeLevelOptionResponse>> GetPrizeLevelOptionsByTypeAsync(int goodsType, bool isChildPrize = false)
    {
        var query = _dbContext.PrizeLevels.AsNoTracking();

        // 根据盒子类型过滤等级
        // PHP逻辑参考：server/php/app/admin/controller/Goods.php goodslist_add方法
        switch (goodsType)
        {
            case 1:  // 一番赏
            case 5:  // 积分赏
            case 6:  // 限时活动
            case 10: // 商城赏
            case 11: // 自制赏
                if (isChildPrize)
                {
                    // 子奖品（宝箱内奖品）：id <= 33 且 id > 5
                    query = query.Where(pl => pl.Id <= 33 && pl.Id > 5);
                }
                else
                {
                    // 父奖品：id <= 33 且 id != 5
                    query = query.Where(pl => pl.Id <= 33 && pl.Id != 5);
                }
                break;

            case 2:  // 无限赏
            case 8:  // 领主赏
            case 9:  // 连击赏
            case 16: // 翻倍赏
            case 17: // 外卖盒子
                // id between 34 and 38（无上、传说、隐藏、史诗、稀有）
                query = query.Where(pl => pl.Id >= 34 && pl.Id <= 38);
                break;

            case 3:  // 擂台赏
                // id between 4 and 33
                query = query.Where(pl => pl.Id >= 4 && pl.Id <= 33);
                break;

            case 15: // 福利屋
                // id >= 114（普通、大奖）
                query = query.Where(pl => pl.Id >= 114);
                break;

            default:
                // 默认返回所有等级
                break;
        }

        return await query
            .OrderBy(pl => pl.Sort)
            .ThenBy(pl => pl.Id)
            .Select(pl => new PrizeLevelOptionResponse
            {
                Id = pl.Id,
                Title = pl.Title,
                Color = pl.Color
            })
            .ToListAsync();
    }

    /// <inheritdoc />
    public async Task<decimal> GetTotalProbabilityAsync()
    {
        return await _dbContext.PrizeLevels
            .AsNoTracking()
            .SumAsync(pl => pl.Pro);
    }
}
