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

namespace HoneyBox.Core.Services;

/// <summary>
/// 福利屋服务实现
/// </summary>
public class WelfareService : IWelfareService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly ILogger<WelfareService> _logger;
    private const int WelfareType = 15; // 福利屋商品类型

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

    /// <inheritdoc />
    public async Task<WelfareListResponse> GetWelfareListAsync(int userId, int type, int page, int limit = 15)
    {
        // 验证type参数
        if (type != 1 && type != 3)
        {
            throw new ArgumentException("参数错误");
        }

        // 计算用户消费总额（用于解锁金额判断）
        decimal userTotalConsumption = 0;

        if (userId > 0)
        {
            var userInfo = await _dbContext.Users
                .Where(u => u.Id == userId)
                .Select(u => new { u.IsTest })
                .FirstOrDefaultAsync();

            if (userInfo != null && userInfo.IsTest > 0)
            {
                // 推广账号，门槛计算是全部的order_zhe_total
                userTotalConsumption = await _dbContext.Orders
                    .Where(o => o.Status == 1 && o.UserId == userId)
                    .SumAsync(o => o.OrderZheTotal);
            }
            else
            {
                // 普通用户，计算price + use_money
                var orderPrice = await _dbContext.Orders
                    .Where(o => o.Status == 1 && o.UserId == userId)
                    .SumAsync(o => o.Price);
                var orderMoney = await _dbContext.Orders
                    .Where(o => o.Status == 1 && o.UserId == userId)
                    .SumAsync(o => o.UseMoney);
                userTotalConsumption = orderPrice + orderMoney;
            }
        }

        // 构建查询
        var now = DateTime.Now;
        IQueryable<Good> query;

        if (type == 1)
        {
            // type=1 进行中：Status=1, IsOpen=0, 且开奖时间未到
            query = _dbContext.Goods
                .Where(g => g.Status == 1
                    && g.DeletedAt == null
                    && g.Type == WelfareType
                    && g.IsOpen == 0
                    && g.UnlockAmount <= userTotalConsumption
                    && (g.OpenTime == null || g.OpenTime > now))
                .OrderByDescending(g => g.Sort)
                .ThenByDescending(g => g.Id);
        }
        else
        {
            // type=3 已结束：已开奖的 或 开奖时间已过但未开奖的
            query = _dbContext.Goods
                .Where(g => g.Type == WelfareType
                    && g.DeletedAt == null
                    && g.UnlockAmount <= userTotalConsumption
                    && (g.IsOpen == 1 || (g.OpenTime != null && g.OpenTime <= now)))
                .OrderByDescending(g => g.OpenTime);
        }

        // 获取总数
        var total = await query.CountAsync();
        var lastPage = (int)Math.Ceiling((double)total / limit);

        // 分页查询
        var goods = await query
            .Skip((page - 1) * limit)
            .Take(limit)
            .Select(g => new
            {
                g.Id,
                g.Title,
                g.ImgUrl,
                g.Price,
                g.Type,
                g.NewIs,
                g.QuanjuXiangou,
                g.ChoujiangXianzhi,
                g.FlwStartTime,
                g.FlwEndTime,
                g.OpenTime,
                g.GoodsDescribe,
                g.IsOpen
            })
            .ToListAsync();

        // 获取商品ID列表
        var goodsIds = goods.Select(g => g.Id).ToList();

        // 获取每个商品的奖品列表
        var goodsListItems = await _dbContext.GoodsItems
            .Where(gi => goodsIds.Contains(gi.GoodsId) && gi.Num == 0)
            .Select(gi => new
            {
                gi.GoodsId,
                gi.Title,
                gi.ImgUrl,
                gi.Stock,
                gi.Price,
                gi.ScMoney
            })
            .ToListAsync();

        // 获取参与次数
        var joinCounts = await _dbContext.OrderItems
            .Where(oi => goodsIds.Contains(oi.GoodsId ?? 0))
            .GroupBy(oi => oi.GoodsId)
            .Select(g => new { GoodsId = g.Key, Count = g.Count() })
            .ToDictionaryAsync(x => x.GoodsId ?? 0, x => x.Count);

        // 构建返回数据
        var list = goods.Select(g => new WelfareItemDto
        {
            Id = g.Id,
            Title = g.Title,
            Imgurl = g.ImgUrl,
            Price = g.Price,
            Type = g.Type,
            NewIs = g.NewIs,
            QuanjuXiangou = g.QuanjuXiangou,
            ChoujiangXianzhi = g.ChoujiangXianzhi,
            FlwStartTime = g.FlwStartTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
            FlwEndTime = g.FlwEndTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
            OpenTime = g.OpenTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
            GoodsDescribe = g.GoodsDescribe ?? "",
            IsOpen = g.IsOpen,
            JoinCount = joinCounts.GetValueOrDefault(g.Id, 0),
            Goodslist = goodsListItems
                .Where(gi => gi.GoodsId == g.Id)
                .Select(gi => new WelfareGoodsListItemDto
                {
                    Title = gi.Title,
                    Imgurl = gi.ImgUrl,
                    Stock = gi.Stock,
                    Price = gi.Price,
                    ScMoney = gi.ScMoney
                })
                .ToList()
        }).ToList();

        return new WelfareListResponse
        {
            List = list,
            LastPage = lastPage,
            Total = total
        };
    }

    /// <inheritdoc />
    public async Task<WelfareDetailResponse> GetWelfareDetailAsync(int userId, int goodsId)
    {
        // 获取商品信息
        var goods = await _dbContext.Goods
            .Where(g => g.Id == goodsId && g.DeletedAt == null)
            .FirstOrDefaultAsync();

        if (goods == null)
        {
            throw new InvalidOperationException("盒子不存在");
        }

        if (goods.Status != 1 && goods.Status != 3)
        {
            throw new InvalidOperationException("盒子已下架");
        }

        if (goods.Type != WelfareType)
        {
            throw new InvalidOperationException("该盒子不是福利屋类型");
        }

        // 检查用户是否可以查看该福利屋（解锁金额限制）
        decimal userTotalConsumption = 0;
        if (userId > 0)
        {
            var userInfo = await _dbContext.Users
                .Where(u => u.Id == userId)
                .Select(u => new { u.IsTest })
                .FirstOrDefaultAsync();

            if (userInfo != null && userInfo.IsTest > 0)
            {
                // 推广账号
                userTotalConsumption = await _dbContext.Orders
                    .Where(o => o.Status == 1 && o.UserId == userId)
                    .SumAsync(o => o.OrderZheTotal);
            }
            else
            {
                var orderPrice = await _dbContext.Orders
                    .Where(o => o.Status == 1 && o.UserId == userId)
                    .SumAsync(o => o.Price);
                var orderMoney = await _dbContext.Orders
                    .Where(o => o.Status == 1 && o.UserId == userId)
                    .SumAsync(o => o.UseMoney);
                userTotalConsumption = orderPrice + orderMoney;
            }

            if (goods.UnlockAmount > userTotalConsumption)
            {
                throw new InvalidOperationException($"您需要消费满{goods.UnlockAmount}元才能查看此福利屋");
            }
        }
        else if (goods.UnlockAmount > 0)
        {
            throw new InvalidOperationException($"您需要登录并充值满{goods.UnlockAmount}元才能查看此福利屋");
        }

        // 获取奖品列表
        var goodsListItems = await _dbContext.GoodsItems
            .Where(gi => gi.GoodsId == goodsId && gi.Num == 0)
            .OrderByDescending(gi => gi.ShangId)
            .ThenBy(gi => gi.Sort)
            .Select(gi => new
            {
                gi.Id,
                gi.Title,
                gi.ImgUrl,
                gi.ImgUrlDetail,
                gi.Stock,
                gi.Price,
                gi.ScMoney,
                gi.ShangId,
                gi.SurplusStock,
                gi.Sort
            })
            .ToListAsync();

        // 获取奖品等级信息
        var shangIds = goodsListItems.Where(gi => gi.ShangId.HasValue).Select(gi => gi.ShangId!.Value).Distinct().ToList();
        var shangInfos = await _dbContext.PrizeLevels
            .Where(p => shangIds.Contains(p.Id))
            .Select(p => new { p.Id, p.Title, p.Color })
            .ToDictionaryAsync(p => p.Id);

        // 统计参与人数
        var joinCount = await _dbContext.OrderItems
            .Where(oi => oi.GoodsId == goodsId && oi.OrderType == WelfareType)
            .CountAsync();

        // 统计用户参与次数
        var userCount = userId > 0
            ? await _dbContext.OrderItems
                .Where(oi => oi.GoodsId == goodsId && oi.UserId == userId && oi.OrderType == WelfareType)
                .CountAsync()
            : 0;

        // 获取用户在活动期间的消费数据
        var userConsumption = new UserConsumptionDto();
        if (userId > 0 && goods.FlwStartTime.HasValue && goods.FlwEndTime.HasValue)
        {
            var startTimestamp = ToUnixTimestamp(goods.FlwStartTime.Value);
            var endTimestamp = ToUnixTimestamp(goods.FlwEndTime.Value);

            var consumptionData = await _dbContext.Orders
                .Where(o => o.UserId == userId
                    && o.Status == 1
                    && o.Addtime >= startTimestamp
                    && o.Addtime <= endTimestamp)
                .GroupBy(o => 1)
                .Select(g => new
                {
                    TotalAmount = g.Sum(o => o.OrderTotal),
                    OrderCount = g.Count()
                })
                .FirstOrDefaultAsync();

            if (consumptionData != null)
            {
                userConsumption.TotalAmount = consumptionData.TotalAmount;
                userConsumption.OrderCount = consumptionData.OrderCount;
            }
        }

        // 构建商品DTO
        var goodsDto = new WelfareGoodsDto
        {
            Id = goods.Id,
            Title = goods.Title,
            Imgurl = goods.ImgUrl,
            ImgurlDetail = !string.IsNullOrEmpty(goods.ImgUrlDetail) ? goods.ImgUrlDetail : goods.ImgUrl,
            Price = goods.Price,
            Type = goods.Type,
            NewIs = goods.NewIs,
            QuanjuXiangou = goods.QuanjuXiangou,
            ChoujiangXianzhi = goods.ChoujiangXianzhi,
            GoodsDescribe = goods.GoodsDescribe ?? "",
            IsOpen = goods.IsOpen,
            UnlockAmount = goods.UnlockAmount,
            Sort = goods.Sort,
            FlwStartTime = goods.FlwStartTime?.ToString("yyyy-MM-dd HH:mm") ?? "",
            FlwEndTime = goods.FlwEndTime?.ToString("yyyy-MM-dd HH:mm") ?? "",
            OpenTime = goods.OpenTime?.ToString("yyyy-MM-dd HH:mm") ?? ""
        };

        // 构建奖品列表
        var prizeList = goodsListItems.Select(gi =>
        {
            var shangInfo = gi.ShangId.HasValue ? shangInfos.GetValueOrDefault(gi.ShangId.Value) : null;
            return new WelfarePrizeDto
            {
                Id = gi.Id,
                Title = gi.Title,
                Imgurl = gi.ImgUrl,
                ImgurlDetail = !string.IsNullOrEmpty(gi.ImgUrlDetail) ? gi.ImgUrlDetail : gi.ImgUrl,
                Stock = gi.Stock,
                Price = gi.Price,
                ScMoney = gi.ScMoney,
                ShangId = gi.ShangId ?? 0,
                SurplusStock = gi.SurplusStock,
                Sort = gi.Sort,
                ShangTitle = shangInfo?.Title ?? "",
                ShangColor = shangInfo?.Color ?? ""
            };
        }).ToList();

        // 判断福利屋状态
        var now = DateTime.Now;
        var startTime = goods.FlwStartTime ?? DateTime.MinValue;
        var endTime = goods.FlwEndTime ?? DateTime.MinValue;
        var openTime = goods.OpenTime ?? DateTime.MinValue;

        string status;
        string statusText;

        if (now < startTime)
        {
            status = "waiting";
            statusText = "即将开始";
        }
        else if (now >= startTime && now < endTime)
        {
            status = "ongoing";
            statusText = "进行中";
        }
        else if (now >= endTime && now < openTime)
        {
            status = "ended";
            statusText = "已结束，等待开奖";
        }
        else if (now >= openTime)
        {
            if (goods.IsOpen == 1)
            {
                status = "opened";
                statusText = "已开奖";
            }
            else
            {
                status = "to_open";
                statusText = "待开奖";
            }
        }
        else
        {
            status = "unknown";
            statusText = "未知状态";
        }

        return new WelfareDetailResponse
        {
            Goods = goodsDto,
            Goodslist = prizeList,
            JoinCount = joinCount,
            CurrentTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
            UserCount = userCount,
            UserConsumption = userConsumption,
            Status = status,
            StatusText = statusText
        };
    }

    /// <inheritdoc />
    public async Task<List<ParticipantDto>> GetParticipantsAsync(int goodsId, int page = 1, int limit = 15)
    {
        var participants = await _dbContext.OrderItems
            .Where(oi => oi.GoodsId == goodsId && oi.OrderType == WelfareType)
            .OrderByDescending(oi => oi.Addtime)
            .Take(1000)
            .Select(oi => new
            {
                oi.UserId,
                oi.Addtime
            })
            .ToListAsync();

        // 获取用户信息
        var userIds = participants.Select(p => p.UserId).Distinct().ToList();
        var users = await _dbContext.Users
            .Where(u => userIds.Contains(u.Id))
            .Select(u => new { u.Id, u.Nickname, u.HeadImg })
            .ToDictionaryAsync(u => u.Id);

        return participants.Select(p =>
        {
            var user = users.GetValueOrDefault(p.UserId);
            return new ParticipantDto
            {
                Nickname = user?.Nickname ?? "",
                Avatar = user?.HeadImg ?? "",
                CreateTime = DateTimeOffset.FromUnixTimeSeconds(p.Addtime).LocalDateTime.ToString("yyyy-MM-dd HH:mm")
            };
        }).ToList();
    }

    /// <inheritdoc />
    public async Task<List<WinningRecordDto>> GetWinningRecordsAsync(int goodsId, int page = 1, int limit = 15)
    {
        var records = await _dbContext.OrderItems
            .Where(oi => oi.GoodsId == goodsId && oi.OrderType == WelfareType && oi.ShangId > 0)
            .OrderByDescending(oi => oi.ShangId)
            .ThenByDescending(oi => oi.Addtime)
            .Take(1000)
            .Select(oi => new
            {
                oi.UserId,
                oi.Addtime,
                oi.GoodslistTitle,
                oi.ShangId
            })
            .ToListAsync();

        // 获取用户信息
        var userIds = records.Select(r => r.UserId).Distinct().ToList();
        var users = await _dbContext.Users
            .Where(u => userIds.Contains(u.Id))
            .Select(u => new { u.Id, u.Nickname, u.HeadImg })
            .ToDictionaryAsync(u => u.Id);

        return records.Select(r =>
        {
            var user = users.GetValueOrDefault(r.UserId);
            return new WinningRecordDto
            {
                Nickname = user?.Nickname ?? "",
                Avatar = user?.HeadImg ?? "",
                GoodslistTitle = r.GoodslistTitle ?? "",
                ShangId = r.ShangId,
                CreateTime = DateTimeOffset.FromUnixTimeSeconds(r.Addtime).LocalDateTime.ToString("yyyy-MM-dd HH:mm")
            };
        }).ToList();
    }

    /// <inheritdoc />
    public async Task<List<UserParticipationDto>> GetUserParticipationRecordsAsync(int userId, int page = 1, int limit = 15)
    {
        var records = await _dbContext.OrderItems
            .Where(oi => oi.UserId == userId && oi.OrderType == WelfareType)
            .OrderByDescending(oi => oi.Addtime)
            .Take(1000)
            .Select(oi => new
            {
                oi.GoodsId,
                oi.Addtime,
                oi.GoodslistTitle,
                oi.ShangId
            })
            .ToListAsync();

        // 获取商品信息
        var goodsIds = records.Where(r => r.GoodsId.HasValue).Select(r => r.GoodsId!.Value).Distinct().ToList();
        var goodsInfos = await _dbContext.Goods
            .Where(g => goodsIds.Contains(g.Id))
            .Select(g => new { g.Id, g.Title })
            .ToDictionaryAsync(g => g.Id);

        return records.Select(r =>
        {
            var goodsInfo = r.GoodsId.HasValue ? goodsInfos.GetValueOrDefault(r.GoodsId.Value) : null;
            return new UserParticipationDto
            {
                GoodsId = r.GoodsId ?? 0,
                GoodsTitle = goodsInfo?.Title ?? "",
                GoodslistTitle = r.GoodslistTitle ?? "",
                ShangId = r.ShangId,
                CreateTime = DateTimeOffset.FromUnixTimeSeconds(r.Addtime).LocalDateTime.ToString("yyyy-MM-dd HH:mm")
            };
        }).ToList();
    }

    /// <inheritdoc />
    public async Task<List<UserWinningDto>> GetUserWinningRecordsAsync(int userId, int page = 1, int limit = 15)
    {
        var records = await _dbContext.OrderItems
            .Where(oi => oi.UserId == userId && oi.OrderType == WelfareType && oi.ShangId > 0)
            .OrderByDescending(oi => oi.Addtime)
            .Take(1000)
            .Select(oi => new
            {
                oi.GoodsId,
                oi.Addtime,
                oi.GoodslistTitle,
                oi.ShangId
            })
            .ToListAsync();

        // 获取商品信息（包括开奖时间）
        var goodsIds = records.Where(r => r.GoodsId.HasValue).Select(r => r.GoodsId!.Value).Distinct().ToList();
        var goodsInfos = await _dbContext.Goods
            .Where(g => goodsIds.Contains(g.Id))
            .Select(g => new { g.Id, g.Title, g.OpenTime })
            .ToDictionaryAsync(g => g.Id);

        return records.Select(r =>
        {
            var goodsInfo = r.GoodsId.HasValue ? goodsInfos.GetValueOrDefault(r.GoodsId.Value) : null;
            return new UserWinningDto
            {
                GoodsId = r.GoodsId ?? 0,
                GoodsTitle = goodsInfo?.Title ?? "",
                GoodslistTitle = r.GoodslistTitle ?? "",
                ShangId = r.ShangId,
                CreateTime = goodsInfo?.OpenTime?.ToString("yyyy-MM-dd HH:mm") ?? ""
            };
        }).ToList();
    }

    /// <summary>
    /// 将DateTime转换为Unix时间戳
    /// </summary>
    private static int ToUnixTimestamp(DateTime dateTime)
    {
        return (int)(dateTime.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
    }

    /// <inheritdoc />
    public async Task<FuliwuListResponse> GetFuliwuListAsync(int userId, int type, int page)
    {
        // 验证type参数
        if (type != 1 && type != 3)
        {
            throw new ArgumentException("参数错误");
        }

        const int paginate = 15;

        // 计算用户消费总额（用于解锁金额判断）
        decimal userTotalConsumption = 0;

        if (userId > 0)
        {
            var userInfo = await _dbContext.Users
                .Where(u => u.Id == userId)
                .Select(u => new { u.IsTest })
                .FirstOrDefaultAsync();

            if (userInfo != null && userInfo.IsTest > 0)
            {
                // 推广账号，门槛计算是全部的order_zhe_total
                userTotalConsumption = await _dbContext.Orders
                    .Where(o => o.Status == 1 && o.UserId == userId)
                    .SumAsync(o => o.OrderZheTotal);
            }
            else
            {
                // 普通用户，计算price + use_money
                var orderPrice = await _dbContext.Orders
                    .Where(o => o.Status == 1 && o.UserId == userId)
                    .SumAsync(o => o.Price);
                var orderMoney = await _dbContext.Orders
                    .Where(o => o.Status == 1 && o.UserId == userId)
                    .SumAsync(o => o.UseMoney);
                userTotalConsumption = orderPrice + orderMoney;
            }
        }

        // 构建查询
        var now = DateTime.Now;
        IQueryable<Good> query;

        _logger.LogInformation("GetFuliwuListAsync: userId={UserId}, type={Type}, page={Page}, userTotalConsumption={Consumption}, now={Now}",
            userId, type, page, userTotalConsumption, now);

        if (type == 1)
        {
            // type=1 进行中：Status=1, IsOpen=0, 且开奖时间未到
            query = _dbContext.Goods
                .Where(g => g.Status == 1
                    && g.DeletedAt == null
                    && g.Type == WelfareType
                    && g.IsOpen == 0
                    && g.UnlockAmount <= userTotalConsumption
                    && (g.OpenTime == null || g.OpenTime > now))
                .OrderByDescending(g => g.Sort)
                .ThenByDescending(g => g.Id);
        }
        else
        {
            // type=3 已结束：已开奖的 或 开奖时间已过但未开奖的
            query = _dbContext.Goods
                .Where(g => g.Type == WelfareType
                    && g.DeletedAt == null
                    && g.UnlockAmount <= userTotalConsumption
                    && (g.IsOpen == 1 || (g.OpenTime != null && g.OpenTime <= now)))
                .OrderByDescending(g => g.OpenTime);
        }

        // 获取总数计算最后一页
        var total = await query.CountAsync();
        var lastPage = (int)Math.Ceiling((double)total / paginate);

        _logger.LogInformation("GetFuliwuListAsync: total={Total}, lastPage={LastPage}", total, lastPage);

        // 分页查询
        var goods = await query
            .Skip((page - 1) * paginate)
            .Take(paginate)
            .Select(g => new
            {
                g.Id,
                g.Title,
                g.ImgUrl,
                g.Price,
                g.Type,
                g.NewIs,
                g.QuanjuXiangou,
                g.ChoujiangXianzhi,
                g.FlwStartTime,
                g.FlwEndTime,
                g.OpenTime,
                g.GoodsDescribe,
                g.IsOpen
            })
            .ToListAsync();

        // 获取商品ID列表
        var goodsIds = goods.Select(g => g.Id).ToList();

        // 获取每个商品的奖品列表
        var goodsListItems = await _dbContext.GoodsItems
            .Where(gi => goodsIds.Contains(gi.GoodsId) && gi.Num == 0)
            .Select(gi => new
            {
                gi.GoodsId,
                gi.Title,
                gi.ImgUrl,
                gi.Stock,
                gi.Price,
                gi.ScMoney
            })
            .ToListAsync();

        // 获取参与次数
        var joinCounts = await _dbContext.OrderItems
            .Where(oi => goodsIds.Contains(oi.GoodsId ?? 0))
            .GroupBy(oi => oi.GoodsId)
            .Select(g => new { GoodsId = g.Key, Count = g.Count() })
            .ToDictionaryAsync(x => x.GoodsId ?? 0, x => x.Count);

        // 构建返回数据
        var list = goods.Select(g => new WelfareItemDto
        {
            Id = g.Id,
            Title = g.Title,
            Imgurl = g.ImgUrl,
            Price = g.Price,
            Type = g.Type,
            NewIs = g.NewIs,
            QuanjuXiangou = g.QuanjuXiangou,
            ChoujiangXianzhi = g.ChoujiangXianzhi,
            FlwStartTime = g.FlwStartTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
            FlwEndTime = g.FlwEndTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
            OpenTime = g.OpenTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
            GoodsDescribe = g.GoodsDescribe ?? "",
            IsOpen = g.IsOpen,
            JoinCount = joinCounts.GetValueOrDefault(g.Id, 0),
            Goodslist = goodsListItems
                .Where(gi => gi.GoodsId == g.Id)
                .Select(gi => new WelfareGoodsListItemDto
                {
                    Title = gi.Title,
                    Imgurl = gi.ImgUrl,
                    Stock = gi.Stock,
                    Price = gi.Price,
                    ScMoney = gi.ScMoney
                })
                .ToList()
        }).ToList();

        return new FuliwuListResponse
        {
            Data = list,
            LastPage = lastPage
        };
    }

    /// <inheritdoc />
    public async Task<WelfareBuyResponse> BuyWelfareAsync(int userId, WelfareBuyRequest request)
    {
        // 1. 获取用户信息
        var user = await _dbContext.Users
            .Where(u => u.Id == userId)
            .Select(u => new
            {
                u.Id,
                u.Mobile,
                u.Money,
                u.Integral,
                u.Money2,
                u.IsTest
            })
            .FirstOrDefaultAsync();

        if (user == null)
        {
            throw new InvalidOperationException("用户不存在");
        }

        // 2. 验证手机号绑定
        if (string.IsNullOrEmpty(user.Mobile))
        {
            throw new InvalidOperationException("请先绑定手机号");
        }

        // 3. 获取商品信息
        var goods = await _dbContext.Goods
            .Where(g => g.Id == request.GoodsId && g.DeletedAt == null)
            .FirstOrDefaultAsync();

        if (goods == null)
        {
            throw new InvalidOperationException("盒子不存在");
        }

        if (goods.Status != 1)
        {
            throw new InvalidOperationException("盒子已下架");
        }

        // 4. 验证是否为福利屋类型
        if (goods.Type != WelfareType)
        {
            throw new InvalidOperationException("该盒子不是福利屋类型");
        }

        // 5. 验证福利屋活动时间
        var now = DateTime.Now;
        if (goods.FlwStartTime.HasValue && now < goods.FlwStartTime.Value)
        {
            throw new InvalidOperationException("福利屋活动尚未开始");
        }
        if (goods.FlwEndTime.HasValue && now > goods.FlwEndTime.Value)
        {
            throw new InvalidOperationException("福利屋活动已结束");
        }

        // 6. 验证解锁金额
        decimal userTotalConsumption = 0;
        if (user.IsTest > 0)
        {
            userTotalConsumption = await _dbContext.Orders
                .Where(o => o.Status == 1 && o.UserId == userId)
                .SumAsync(o => o.OrderZheTotal);
        }
        else
        {
            var orderPrice = await _dbContext.Orders
                .Where(o => o.Status == 1 && o.UserId == userId)
                .SumAsync(o => o.Price);
            var orderMoney = await _dbContext.Orders
                .Where(o => o.Status == 1 && o.UserId == userId)
                .SumAsync(o => o.UseMoney);
            userTotalConsumption = orderPrice + orderMoney;
        }

        if (goods.UnlockAmount > userTotalConsumption)
        {
            throw new InvalidOperationException($"您需要消费满{goods.UnlockAmount}元才能参与此福利屋");
        }

        // 7. 验证抽奖门槛 (福利屋活动期间消费)
        if (goods.ChoujiangXianzhi > 0 && goods.FlwStartTime.HasValue && goods.FlwEndTime.HasValue)
        {
            var startTimestamp = ToUnixTimestamp(goods.FlwStartTime.Value);
            var endTimestamp = ToUnixTimestamp(goods.FlwEndTime.Value);

            var consumptionInPeriod = await _dbContext.Orders
                .Where(o => o.Status == 1
                    && o.UserId == userId
                    && o.Addtime >= startTimestamp
                    && o.Addtime <= endTimestamp)
                .SumAsync(o => o.UseMoney);

            if (consumptionInPeriod < goods.ChoujiangXianzhi)
            {
                var remaining = Math.Round(goods.ChoujiangXianzhi - consumptionInPeriod, 2);
                throw new InvalidOperationException(
                    $"需在活动期间消耗达到{goods.ChoujiangXianzhi}钻石，还需{remaining}钻石");
            }
        }

        // 8. 验证全局限购
        if (goods.QuanjuXiangou > 0)
        {
            var userQuanjuCount = await _dbContext.OrderItems
                .Where(oi => oi.GoodsId == request.GoodsId
                    && oi.UserId == userId
                    && oi.ParentGoodsListId == 0)
                .CountAsync();

            if (userQuanjuCount >= goods.QuanjuXiangou)
            {
                throw new InvalidOperationException($"当前限购{goods.QuanjuXiangou}次");
            }

            var nowPrizeNum = request.PrizeNum + userQuanjuCount;
            if (nowPrizeNum > goods.QuanjuXiangou)
            {
                throw new InvalidOperationException($"购买超出限制,还允许购买{goods.QuanjuXiangou - userQuanjuCount}次");
            }
        }

        // 9. 计算订单金额
        var prizeNum = request.PrizeNum > 0 ? request.PrizeNum : 1;
        var orderTotal = goods.Price * prizeNum;
        var price = orderTotal;

        // 余额抵扣
        decimal useMoney = 0;
        if (request.UseMoneyIs == 1)
        {
            if (user.Money >= price)
            {
                useMoney = price;
                price = 0;
            }
            else
            {
                useMoney = user.Money;
                price -= user.Money;
            }
        }

        // 积分抵扣 (1:100比例)
        decimal useIntegral = 0;
        if (request.UseIntegralIs == 1 && price > 0)
        {
            var priceInIntegral = price * 100;
            if (user.Integral >= priceInIntegral)
            {
                useIntegral = priceInIntegral;
                price = 0;
            }
            else
            {
                useIntegral = user.Integral;
                price -= user.Integral / 100;
            }
        }

        // 货币2抵扣 (1:100比例)
        decimal useMoney2 = 0;
        var userMoney2 = user.Money2 ?? 0;
        if (request.UseMoney2Is == 1 && price > 0)
        {
            var priceInMoney2 = price * 100;
            if (userMoney2 >= priceInMoney2)
            {
                useMoney2 = priceInMoney2;
                price = 0;
            }
            else
            {
                useMoney2 = userMoney2;
                price -= userMoney2 / 100;
            }
        }

        price = Math.Round(price, 2);

        // 10. 生成订单号
        var orderNum = $"FLW_{DateTime.Now:yyyyMMddHHmmss}_{userId}_{new Random().Next(1000, 9999)}";

        // 11. 使用事务创建订单
        using var transaction = await _dbContext.Database.BeginTransactionAsync();
        try
        {
            // 扣除用户余额/积分
            if (useMoney > 0 || useIntegral > 0 || useMoney2 > 0)
            {
                var userEntity = await _dbContext.Users.FindAsync(userId);
                if (userEntity != null)
                {
                    if (useMoney > 0)
                    {
                        userEntity.Money -= useMoney;
                    }
                    if (useIntegral > 0)
                    {
                        userEntity.Integral -= useIntegral;
                    }
                    if (useMoney2 > 0)
                    {
                        userEntity.Money2 = (userEntity.Money2 ?? 0) - useMoney2;
                    }
                }
            }

            // 创建订单
            var order = new Order
            {
                UserId = userId,
                OrderNum = orderNum,
                OrderTotal = orderTotal,
                OrderZheTotal = orderTotal,
                Price = price,
                UseMoney = useMoney,
                UseIntegral = useIntegral,
                UseMoney2 = useMoney2,
                UseScore = 0,
                Zhe = 1,
                GoodsId = request.GoodsId,
                Num = 0, // 福利屋固定为0
                GoodsPrice = goods.Price,
                GoodsTitle = goods.Title,
                GoodsImgurl = goods.ImgUrlDetail,
                PrizeNum = prizeNum,
                Status = price > 0 ? (byte)0 : (byte)1, // 需要微信支付则待支付，否则已支付
                PayType = 1,
                OrderType = WelfareType,
                Addtime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
                CouponId = request.CouponId > 0 ? request.CouponId : null,
                UseCoupon = 0,
                IsShouZhe = 0,
                IsFlw = 1,
                CreatedAt = DateTime.Now,
                UpdatedAt = DateTime.Now
            };

            _dbContext.Orders.Add(order);
            await _dbContext.SaveChangesAsync();

            // 如果不需要微信支付，直接创建参与记录
            if (price <= 0)
            {
                order.Status = 1;
                order.PayTime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();

                // 创建订单项（参与记录）
                for (int i = 0; i < prizeNum; i++)
                {
                    var orderItem = new OrderItem
                    {
                        UserId = userId,
                        OrderId = order.Id,
                        GoodsId = request.GoodsId,
                        Num = 0,
                        OrderType = WelfareType,
                        ShangId = 0, // 未开奖
                        GoodslistTitle = "",
                        GoodslistImgurl = "",
                        GoodslistMoney = 0,
                        Addtime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
                        ParentGoodsListId = 0,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    };
                    _dbContext.OrderItems.Add(orderItem);
                }

                await _dbContext.SaveChangesAsync();
            }

            await transaction.CommitAsync();

            // 12. 返回结果
            if (price > 0)
            {
                // 需要微信支付
                return new WelfareBuyResponse
                {
                    Status = 1,
                    OrderNum = orderNum,
                    PayParams = new { message = "请使用微信支付完成订单" }
                };
            }
            else
            {
                // 余额支付成功
                return new WelfareBuyResponse
                {
                    Status = 0,
                    OrderNum = orderNum
                };
            }
        }
        catch (Exception ex)
        {
            await transaction.RollbackAsync();
            _logger.LogError(ex, "福利屋购买失败: UserId={UserId}, GoodsId={GoodsId}", userId, request.GoodsId);
            throw new InvalidOperationException("购买失败,请刷新重试");
        }
    }
}
