package jd_cookie

import (
	"context"
	"fmt"
	v1 "kami/api/jd_cookie/v1"
	"kami/internal/consts"
	"kami/internal/dao"
	"kami/internal/model"
	"kami/internal/model/do"
	"kami/internal/model/entity"
	"kami/utility/cache"
	"kami/utility/config"
	"kami/utility/integration/kami_gateway"
	"slices"
	"time"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/xuri/excelize/v2"
)

// GetJdOrder 获取单个京东订单
func (s *sJdCookie) GetJdOrder(ctx context.Context, jdOrderId string) (order *v1.JdOrderInfo, err error) {
	if jdOrderId == "" {
		return nil, gerror.New("京东订单号不能为空")
	}

	// 查询京东订单
	jdOrderEntity, err := s.getJdOrderByJdOrderId(ctx, jdOrderId)
	if err != nil {
		return nil, gerror.Wrap(err, "查询京东订单失败")
	}
	if jdOrderEntity == nil {
		return nil, gerror.New(consts.ErrCodeJdOrderNotFound)
	}

	order = &v1.JdOrderInfo{
		Id:              jdOrderEntity.Id,
		JdOrderId:       jdOrderEntity.JdOrderId,
		PayId:           jdOrderEntity.PayId,
		Amount:          gconv.Float64(jdOrderEntity.Amount),
		Category:        jdOrderEntity.Category,
		CookieId:        jdOrderEntity.CookieId,
		Status:          consts.JdOrderStatus(jdOrderEntity.Status),
		WxPayUrl:        jdOrderEntity.WxPayUrl,
		WxPayExpireAt:   jdOrderEntity.WxPayExpireAt,
		OrderExpireAt:   jdOrderEntity.OrderExpireAt,
		OrderId:         jdOrderEntity.OrderId,
		CardNo:          jdOrderEntity.CardNo,
		CardPassword:    jdOrderEntity.CardPassword,
		CardExtractedAt: jdOrderEntity.CardExtractedAt,
		CreatedAt:       jdOrderEntity.CreatedAt,
		UpdatedAt:       jdOrderEntity.UpdatedAt,
		DeletedAt:       jdOrderEntity.DeletedAt,
	}

	// 查询关联的Cookie信息
	if jdOrderEntity.CookieId != "" {
		var cookieEntity *entity.V1JdCookieAccount
		err = dao.V1JdCookieAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
			Where(dao.V1JdCookieAccount.Columns().CookieId, jdOrderEntity.CookieId).
			Scan(&cookieEntity)
		if err == nil && cookieEntity != nil {
			order.Cookie = &v1.CookieAccountInfo{
				Id:          cookieEntity.Id,
				CookieId:    cookieEntity.CookieId,
				AccountName: cookieEntity.AccountName,
				Status:      consts.JdCookieStatus(cookieEntity.Status),
				CreatedAt:   cookieEntity.CreatedAt,
				UpdatedAt:   cookieEntity.UpdatedAt,
			}
		}
	}

	return
}

// ListJdOrder 京东订单列表查询
func (s *sJdCookie) ListJdOrder(ctx context.Context, page, size int, status consts.JdOrderStatus, startTime, endTime, orderId string) (list []*v1.JdOrderInfo, total int, err error) {
	if page <= 0 {
		page = 1
	}
	if size <= 0 {
		size = 20
	}

	m := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())

	// 构建查询条件
	if status > 0 {
		m = m.Where(dao.V1JdCookieJdOrder.Columns().Status, int(status))
	}
	if startTime != "" {
		m = m.WhereGTE(dao.V1JdCookieJdOrder.Columns().CreatedAt, startTime)
	}
	if endTime != "" {
		m = m.WhereLTE(dao.V1JdCookieJdOrder.Columns().CreatedAt, endTime)
	}
	if orderId != "" {
		// 直接根据order_id字段筛选
		m = m.Where(dao.V1JdCookieJdOrder.Columns().OrderId, orderId)
	}

	// 查询总数
	total, err = m.Count()
	if err != nil {
		return nil, 0, gerror.Wrap(err, "查询京东订单总数失败")
	}

	// 查询列表数据
	var jdOrders []*entity.V1JdCookieJdOrder
	err = m.Page(page, size).
		OrderDesc(dao.V1JdCookieJdOrder.Columns().CreatedAt).
		Scan(&jdOrders)
	if err != nil {
		return nil, 0, gerror.Wrap(err, "查询京东订单列表失败")
	}

	// 收集所有Cookie ID
	cookieIds := make([]string, 0, len(jdOrders))
	cookieMap := make(map[string]*entity.V1JdCookieAccount)
	for _, jdOrder := range jdOrders {
		if jdOrder.CookieId != "" {
			cookieIds = append(cookieIds, jdOrder.CookieId)
		}
	}

	// 批量查询Cookie信息
	if len(cookieIds) > 0 {
		var cookies []*entity.V1JdCookieAccount
		err = dao.V1JdCookieAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
			WhereIn(dao.V1JdCookieAccount.Columns().CookieId, cookieIds).
			Scan(&cookies)
		if err == nil {
			for _, cookie := range cookies {
				cookieMap[cookie.CookieId] = cookie
			}
		}
	}

	// 转换为响应格式
	list = make([]*v1.JdOrderInfo, 0, len(jdOrders))
	for _, jdOrderEntity := range jdOrders {
		info := &v1.JdOrderInfo{
			Id:              jdOrderEntity.Id,
			JdOrderId:       jdOrderEntity.JdOrderId,
			PayId:           jdOrderEntity.PayId,
			Amount:          gconv.Float64(jdOrderEntity.Amount),
			Category:        jdOrderEntity.Category,
			CookieId:        jdOrderEntity.CookieId,
			Status:          consts.JdOrderStatus(jdOrderEntity.Status),
			WxPayUrl:        jdOrderEntity.WxPayUrl,
			WxPayExpireAt:   jdOrderEntity.WxPayExpireAt,
			OrderExpireAt:   jdOrderEntity.OrderExpireAt,
			OrderId:         jdOrderEntity.OrderId,
			PaidAt:          jdOrderEntity.PaidAt,
			CardNo:          jdOrderEntity.CardNo,
			CardPassword:    jdOrderEntity.CardPassword,
			CardExtractedAt: jdOrderEntity.CardExtractedAt,
			CreatedAt:       jdOrderEntity.CreatedAt,
			UpdatedAt:       jdOrderEntity.UpdatedAt,
			DeletedAt:       jdOrderEntity.DeletedAt,
		}

		// 设置关联的Cookie信息
		if cookie, exists := cookieMap[jdOrderEntity.CookieId]; exists && cookie != nil {
			info.Cookie = &v1.CookieAccountInfo{
				Id:          cookie.Id,
				CookieId:    cookie.CookieId,
				AccountName: cookie.AccountName,
				Status:      consts.JdCookieStatus(cookie.Status),
				CreatedAt:   cookie.CreatedAt,
				UpdatedAt:   cookie.UpdatedAt,
			}
		}

		list = append(list, info)
	}

	return
}

// BatchCheckPaymentStatus 批量检查京东订单支付状态（定时任务）
func (s *sJdCookie) BatchCheckPaymentStatus(ctx context.Context) error {
	//glog.Info(ctx, "开始批量检查京东订单支付状态")

	// 配置参数
	const (
		PageSize = 100 // 单页处理订单数量
	)

	// 筛选待检查订单
	jdOrderModel := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())

	// 构建基础查询条件
	baseQuery := jdOrderModel.
		Where(dao.V1JdCookieJdOrder.Columns().Status, int(consts.JdOrderStatusPending)).   // 状态为待支付
		WhereGT(dao.V1JdCookieJdOrder.Columns().CreatedAt, gtime.Now().Add(-24*time.Hour)) // 24小时内创建

	// 查询总数量
	totalCount, err := baseQuery.Count()
	if err != nil {
		glog.Error(ctx, "查询待检查订单总数失败", err)
		return err
	}

	if totalCount == 0 {
		//glog.Info(ctx, "没有需要检查的订单")
		return nil
	}

	glog.Info(ctx, "找到待检查订单", g.Map{"totalCount": totalCount})

	// 分页处理所有订单
	page := 1
	totalSuccessCount := 0
	totalErrorCount := 0
	totalProcessed := 0

	for {
		// 查询当前页的订单
		var pendingOrders []*entity.V1JdCookieJdOrder
		err := baseQuery.
			OrderAsc(dao.V1JdCookieJdOrder.Columns().CreatedAt). // 优先处理早期订单
			Page(page, PageSize).
			Scan(&pendingOrders)

		if err != nil {
			glog.Error(ctx, "查询待检查订单失败", g.Map{
				"page":  page,
				"error": err,
			})
			return err
		}

		if len(pendingOrders) == 0 {
			// 没有更多数据，结束循环
			break
		}

		glog.Info(ctx, "处理当前页订单", g.Map{
			"page":     page,
			"pageSize": len(pendingOrders),
		})

		// 处理当前页订单
		pageSuccessCount := 0
		pageErrorCount := 0

		for _, jdOrder := range pendingOrders {
			// 检查并更新支付状态
			err = s.ExtractCardInfo(ctx, jdOrder.JdOrderId)
			if err != nil {
				pageErrorCount++
				totalErrorCount++
				glog.Error(ctx, "检查订单支付状态失败", g.Map{
					"jdOrderId": jdOrder.JdOrderId,
					"error":     err,
				})
				continue
			}
			pageSuccessCount++
			totalSuccessCount++
		}

		totalProcessed += len(pendingOrders)

		glog.Info(ctx, "当前页处理完成", g.Map{
			"page":           page,
			"pageSize":       len(pendingOrders),
			"pageSuccess":    pageSuccessCount,
			"pageError":      pageErrorCount,
			"totalProcessed": totalProcessed,
			"totalCount":     totalCount,
		})

		// 如果当前页数据少于PageSize，说明已经是最后一页
		if len(pendingOrders) < PageSize {
			break
		}

		page++
	}

	glog.Info(ctx, "批量检查完成", g.Map{
		"totalCount":    totalCount,
		"processed":     totalProcessed,
		"successCount":  totalSuccessCount,
		"errorCount":    totalErrorCount,
		"processedTime": gtime.Now().Format("Y-m-d H:i:s"),
		"pages":         page,
	})

	return nil
}

// ExtractCardInfo 提取卡密信息
func (s *sJdCookie) ExtractCardInfo(ctx context.Context, jdOrderId string) error {
	if jdOrderId == "" {
		return gerror.New("京东订单号不能为空")
	}

	// 检查是否已经被锁定
	cacheKey := cache.PrefixJdCardExtract.Key(jdOrderId)
	cacheValue, _ := cache.NewCache().Get(ctx, cacheKey)
	if cacheValue != nil && !cacheValue.IsNil() {
		glog.Debug(ctx, "卡密提取正在进行中，跳过", g.Map{"jdOrderId": jdOrderId})
		return nil
	}

	// 设置锁定缓存，防止重复提取
	_ = cache.NewCache().Set(ctx, cacheKey, gtime.Now().String(), 1*time.Minute)
	defer func() {
		_, _ = cache.NewCache().Remove(ctx, cacheKey)
	}()

	// 获取京东订单信息
	jdOrder, err := s.getJdOrderByJdOrderId(ctx, jdOrderId)
	if err != nil {
		return gerror.Wrap(err, "查询京东订单失败")
	}
	if jdOrder == nil {
		return gerror.New(consts.ErrCodeJdOrderNotFound)
	}

	// 检查是否已经提取过卡密
	if jdOrder.CardNo != "" || jdOrder.CardPassword != "" {
		glog.Info(ctx, "卡密已经提取，跳过", g.Map{"jdOrderId": jdOrderId})
		return nil
	}

	// 检查订单状态是否允许提取卡密
	if !s.shouldExtractCard(ctx, jdOrder) {
		glog.Debug(ctx, "订单状态不允许提取卡密", g.Map{
			"jdOrderId": jdOrderId,
			"status":    jdOrder,
		})
		return nil
	}

	// 获取Cookie信息
	cookieInfo, err := s.getCookieById(ctx, jdOrder.CookieId)
	if err != nil || cookieInfo == nil {
		return gerror.New(consts.ErrCodeCookieNotFound)
	}

	resp, err := s.callJdCheckPayment(ctx, &model.CallJdCheckPaymentReq{
		JdOrderId:     jdOrder.JdOrderId,
		RealJdOrderId: jdOrder.RealJdOrderId,
		CookieValue:   cookieInfo.CookieValue,
		Category:      consts.RedeemOrderCardCategory(jdOrder.Category),
	})
	if err != nil {
		if resp != nil {
			if resp.IsCkFailed {
				s.handleCookieFailure(ctx, "", cookieInfo.CookieId, jdOrderId, true, resp.Remark)
				_ = s.UpdateJdOrderStatus(ctx, jdOrderId, consts.JdOrderStatusCkFailed, "", resp.Remark)
				_, _ = dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).Where(dao.V1JdCookieOrder.Columns().OrderId, jdOrder.OrderId).
					Update(do.V1JdCookieOrder{
						Status: consts.OrderStatusCkFailed,
					})
				_ = s.RecordOrderHistory(ctx, &model.RecordOrderHistoryReq{
					OrderId:    jdOrder.OrderId,
					ChangeType: consts.OrderChangeTypeCkFailed,
					JdOrderId:  jdOrderId,
					Remark:     "",
				})

			}
		}
		return gerror.Wrap(err, "查询京东订单支付状态失败")
	}

	if !slices.Contains([]string{"待使用", "待发送"}, resp.OrderStatus) {
		return nil
	}
	if resp.OrderStatus == "等待发码" && jdOrder.Status != int(consts.JdOrderStatusPaid) {
		// 保存卡密信息到数据库
		_, err = dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
			Where(dao.V1JdCookieJdOrder.Columns().JdOrderId, jdOrderId).
			Update(do.V1JdCookieJdOrder{
				PaidAt: gtime.Now(),
				Status: consts.JdOrderStatusPaid,
			})
		if jdOrder.OrderId != "" {
			_ = s.RecordJdOrderHistory(ctx, jdOrderId, consts.JdOrderChangeTypePay, jdOrder.OrderId, jdOrder.WxPayUrl, "")
			_, _ = dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).Where(dao.V1JdCookieOrder.Columns().OrderId, jdOrder.OrderId).
				Update(do.V1JdCookieOrder{
					Status: consts.OrderStatusPaid,
				})
			_ = s.RecordOrderHistory(ctx, &model.RecordOrderHistoryReq{
				OrderId:    jdOrder.OrderId,
				ChangeType: consts.OrderChangeTypePay,
				JdOrderId:  jdOrderId,
				Remark:     "",
			})
		}
		return nil
	}
	if resp.CardNo == "" || resp.CardPassword == "" {
		return gerror.New("获取卡密信息为空")
	}

	affected, _ := dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1JdCookieOrder.Columns().OrderId, jdOrder.OrderId).
		WhereNot(dao.V1JdCookieOrder.Columns().Status, consts.OrderStatusPaid).
		UpdateAndGetAffected(do.V1JdCookieOrder{
			Status: consts.OrderStatusPaid,
		})
	if affected > 0 {
		_ = s.RecordOrderHistory(ctx, &model.RecordOrderHistoryReq{
			OrderId:    jdOrder.OrderId,
			ChangeType: consts.OrderChangeTypePay,
			JdOrderId:  jdOrderId,
			Remark:     "",
		})
	}

	// 保存卡密信息到数据库
	_, err = dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1JdCookieJdOrder.Columns().JdOrderId, jdOrderId).
		Update(do.V1JdCookieJdOrder{
			Status:          consts.JdOrderStatusSent,
			CardNo:          resp.CardNo,
			CardPassword:    resp.CardPassword,
			CardExtractedAt: gtime.Now(),
		})
	if err != nil {
		return gerror.Wrap(err, "保存卡密信息失败")
	}

	_ = s.RecordJdOrderHistory(ctx, jdOrderId, consts.JdOrderChangeTypeSend, jdOrder.OrderId, jdOrder.WxPayUrl, "")

	glog.Info(ctx, "卡密提取成功", g.Map{
		"jdOrderId": jdOrderId,
		"cardNo":    resp.CardNo,
		"orderId":   jdOrder.OrderId,
	})

	//提取成功要回调
	go s.callback(ctx, jdOrder, resp.CardNo, resp.CardPassword)

	return nil
}

// callback
func (s *sJdCookie) callback(ctx context.Context, jdOrder *entity.V1JdCookieJdOrder, cardNo, cardPassword string) {
	var cookieOrder *entity.V1JdCookieOrder
	if err := dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1JdCookieOrder.Columns().OrderId, jdOrder.OrderId).Scan(&cookieOrder); err != nil || cookieOrder == nil || cookieOrder.Id == 0 {
		glog.Error(ctx, "查询订单失败", g.Map{"orderId": jdOrder.OrderId, "err": err})
		return
	}

	var orderInfo *entity.V1OrderInfo
	if err := dao.V1OrderInfo.Ctx(ctx).DB(config.GetDatabaseV1()).Where(dao.V1OrderInfo.Columns().BankOrderId, cookieOrder.UserOrderId).Scan(&orderInfo); err != nil || orderInfo == nil || orderInfo.Id == 0 {
		glog.Error(ctx, "查询订单失败", g.Map{"userOrderId": cookieOrder.UserOrderId, "err": err})
		return
	}
	var merchantInfo *entity.V1MerchantInfo
	if err := dao.V1MerchantInfo.Ctx(ctx).DB(config.GetDatabaseV1()).Where(dao.V1MerchantInfo.Columns().MerchantUid, orderInfo.MerchantUid).Scan(&merchantInfo); err != nil || merchantInfo == nil || merchantInfo.Id == 0 {
		glog.Error(ctx, "查询商户信息失败", g.Map{"merchantId": orderInfo.MerchantUid, "err": err})
		return
	}
	var roadInfo *entity.V1RoadInfo
	if err := dao.V1RoadInfo.Ctx(ctx).DB(config.GetDatabaseV1()).Where(dao.V1RoadInfo.Columns().RoadUid, orderInfo.RoadUid).Scan(&roadInfo); err != nil || roadInfo == nil || roadInfo.Id == 0 {
		glog.Error(ctx, "查询通道信息失败", g.Map{"roadId": orderInfo.RoadUid, "err": err})
		return
	}
	_, err := kami_gateway.SubmitOrder(ctx, &kami_gateway.SubmitOrderReq{
		OrderPeriod: 24,
		NotifyUrl:   "https://baidu.com",
		OrderPrice:  orderInfo.OrderAmount.String(),
		OrderNo:     orderInfo.MerchantOrderId,
		ProductCode: roadInfo.ProductCode,
		ExValue: (&kami_gateway.RedeemCardInfo{
			FaceType:     orderInfo.OrderAmount.String(),
			RecoveryType: "8",
			Data:         cardPassword,
			CardNo:       cardNo,
		}).ToJson(),
		Ip:        "127.0.0.1",
		PayKey:    merchantInfo.MerchantKey,
		PaySecret: merchantInfo.MerchantSecret,
		Url:       "http://kami_gateway:12309",
	})
	if err != nil {
		_ = s.RecordOrderHistory(ctx, &model.RecordOrderHistoryReq{
			OrderId:    jdOrder.OrderId,
			ChangeType: consts.OrderChangeTypeCallback,
			JdOrderId:  jdOrder.JdOrderId,
			Remark:     "回调失败" + err.Error(),
		})
	} else {
		_ = s.RecordOrderHistory(ctx, &model.RecordOrderHistoryReq{
			OrderId:    jdOrder.OrderId,
			ChangeType: consts.OrderChangeTypeCallback,
			JdOrderId:  jdOrder.JdOrderId,
			Remark:     "回调成功",
		})
	}
}

// shouldExtractCard 判断是否需要提取卡密
func (s *sJdCookie) shouldExtractCard(ctx context.Context, jdOrder *entity.V1JdCookieJdOrder) bool {
	if jdOrder == nil {
		return false
	}

	// 检查是否已经提取过卡密
	if jdOrder.CardNo != "" || jdOrder.CardPassword != "" {
		return false
	}

	// 检查订单状态：必须是已支付或待支付
	if jdOrder.Status != int(consts.JdOrderStatusPending) && jdOrder.Status != int(consts.JdOrderStatusPaid) {
		return false
	}

	return true
}

// CleanupExpiredOrders 清理过期订单（定时任务）
func (s *sJdCookie) CleanupExpiredOrders(ctx context.Context) error {
	// 清理过期的京东订单
	jdOrderModel := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())

	// 先查询即将过期的京东订单，用于记录历史
	var expiredJdOrders []*entity.V1JdCookieJdOrder
	err := jdOrderModel.
		Where(dao.V1JdCookieJdOrder.Columns().Status, int(consts.JdOrderStatusPending)).
		WhereLT(dao.V1JdCookieJdOrder.Columns().OrderExpireAt, gtime.Now()).
		Scan(&expiredJdOrders)
	if err != nil {
		glog.Error(ctx, "查询过期京东订单失败", err)
		return err
	}

	// 批量更新过期状态
	_, err = jdOrderModel.
		Where(dao.V1JdCookieJdOrder.Columns().Status, int(consts.JdOrderStatusPending)).
		WhereLT(dao.V1JdCookieJdOrder.Columns().OrderExpireAt, gtime.Now()).
		Update(do.V1JdCookieJdOrder{
			Status: int(consts.JdOrderStatusExpired),
		})
	if err != nil {
		glog.Error(ctx, "清理过期京东订单失败", err)
		return err
	}

	// 为每个过期的京东订单记录历史
	for _, jdOrder := range expiredJdOrders {
		orderId := jdOrder.OrderId
		if jdOrder.OrderId != "" {
			// 同时记录用户订单的历史
			_ = s.RecordOrderHistory(ctx, &model.RecordOrderHistoryReq{
				OrderId:    orderId,
				ChangeType: consts.OrderChangeTypeExpire,
				JdOrderId:  jdOrder.JdOrderId,
				Remark:     "",
			})
		}
		_ = s.RecordJdOrderHistory(ctx, jdOrder.JdOrderId, consts.JdOrderChangeTypeExpire, orderId, jdOrder.WxPayUrl, "")
	}

	// 清理过期的用户订单
	orderModel := dao.V1JdCookieOrder.Ctx(ctx).DB(config.GetDatabaseV1())

	// 查询即将过期的用户订单
	var expiredOrders []*entity.V1JdCookieOrder
	err = orderModel.
		Where(dao.V1JdCookieOrder.Columns().Status, int(consts.OrderStatusPending)).
		WhereLT(dao.V1JdCookieOrder.Columns().CreatedAt, gtime.Now().Add(-time.Hour*30)).
		Scan(&expiredOrders)
	if err != nil {
		glog.Error(ctx, "查询过期用户订单失败", err)
		return err
	}

	// 批量更新过期状态
	_, err = orderModel.
		Where(dao.V1JdCookieOrder.Columns().Status, int(consts.OrderStatusPending)).
		WhereLT(dao.V1JdCookieOrder.Columns().CreatedAt, gtime.Now().Add(-time.Minute*30)).
		Update(do.V1JdCookieOrder{
			Status: consts.OrderStatusExpired,
		})
	if err != nil {
		glog.Error(ctx, "清理过期用户订单失败", err)
		return err
	}

	// 为每个过期的用户订单记录历史
	for _, order := range expiredOrders {
		_ = s.RecordOrderHistory(ctx, &model.RecordOrderHistoryReq{
			OrderId:    order.OrderId,
			ChangeType: consts.OrderChangeTypeExpire,
			JdOrderId:  order.JdOrderId,
			Remark:     "",
		})
	}

	if len(expiredJdOrders) > 0 || len(expiredOrders) > 0 {
		// 批量更新订单状态为已取消
		glog.Info(ctx, "清理过期订单完成", g.Map{
			"expiredJdOrderCount": len(expiredJdOrders),
			"expiredOrderCount":   len(expiredOrders),
		})
	}
	return nil
}

// ReleaseExpiredJdOrders 释放过期京东订单的关联（使其可以被复用）
func (s *sJdCookie) ReleaseExpiredJdOrders(ctx context.Context) error {
	// 查找超过30分钟未支付的京东订单
	expireTime := gtime.Now().Add(-time.Minute * consts.JdOrderReuseTimeout)

	// 释放这些订单的关联
	jdOrderModel := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())
	_, err := jdOrderModel.
		Where(dao.V1JdCookieJdOrder.Columns().Status, int(consts.JdOrderStatusPending)).
		WhereNotNull(dao.V1JdCookieJdOrder.Columns().OrderId).
		WhereLT(dao.V1JdCookieJdOrder.Columns().CreatedAt, expireTime).
		Update(do.V1JdCookieJdOrder{
			OrderId: nil,
		})
	if err != nil {
		glog.Error(ctx, "释放过期京东订单关联失败", err)
		return err
	}
	return nil
}

// ExportJdOrder 导出京东订单数据为Excel
func (s *sJdCookie) ExportJdOrder(ctx context.Context, status consts.JdOrderStatus, startTime, endTime, orderId string) (fileName string, content []byte, err error) {
	// 构建查询条件
	m := dao.V1JdCookieJdOrder.Ctx(ctx).DB(config.GetDatabaseV1())

	if status > 0 {
		m = m.Where(dao.V1JdCookieJdOrder.Columns().Status, int(status))
	}
	if startTime != "" {
		m = m.WhereGTE(dao.V1JdCookieJdOrder.Columns().CreatedAt, startTime)
	}
	if endTime != "" {
		m = m.WhereLTE(dao.V1JdCookieJdOrder.Columns().CreatedAt, endTime)
	}
	if orderId != "" {
		// 直接根据order_id字段筛选
		m = m.Where(dao.V1JdCookieJdOrder.Columns().OrderId, orderId)
	}

	// 查询所有符合条件的订单
	var jdOrders []*entity.V1JdCookieJdOrder
	err = m.OrderDesc(dao.V1JdCookieJdOrder.Columns().CreatedAt).Scan(&jdOrders)
	if err != nil {
		return "", nil, gerror.Wrap(err, "查询京东订单列表失败")
	}

	// 收集所有Cookie ID
	cookieIds := make([]string, 0, len(jdOrders))
	cookieMap := make(map[string]*entity.V1JdCookieAccount)
	for _, jdOrder := range jdOrders {
		if jdOrder.CookieId != "" {
			cookieIds = append(cookieIds, jdOrder.CookieId)
		}
	}

	// 批量查询Cookie信息
	if len(cookieIds) > 0 {
		var cookies []*entity.V1JdCookieAccount
		err = dao.V1JdCookieAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
			WhereIn(dao.V1JdCookieAccount.Columns().CookieId, cookieIds).
			Scan(&cookies)
		if err == nil {
			for _, cookie := range cookies {
				cookieMap[cookie.CookieId] = cookie
			}
		}
	}

	// 创建Excel文件
	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			glog.Error(ctx, "关闭Excel文件失败", err)
		}
	}()

	// 设置工作表名称
	sheetName := "京东订单数据"
	f.SetSheetName("Sheet1", sheetName)

	// 设置表头
	headers := []string{"京东订单号", "用户订单号", "卡号", "卡密", "ck名称", "京东订单状态"}
	for i, header := range headers {
		cell := fmt.Sprintf("%s1", string(rune('A'+i)))
		f.SetCellValue(sheetName, cell, header)
	}

	// 填充数据
	for i, jdOrder := range jdOrders {
		row := i + 2
		// 京东订单号
		f.SetCellValue(sheetName, fmt.Sprintf("A%d", row), jdOrder.JdOrderId)

		// 用户订单号
		f.SetCellValue(sheetName, fmt.Sprintf("B%d", row), jdOrder.OrderId)

		// 卡号
		f.SetCellValue(sheetName, fmt.Sprintf("C%d", row), jdOrder.CardNo)

		// 卡密
		f.SetCellValue(sheetName, fmt.Sprintf("D%d", row), jdOrder.CardPassword)

		// ck名称
		cookieName := ""
		if cookie, exists := cookieMap[jdOrder.CookieId]; exists && cookie != nil {
			cookieName = cookie.AccountName
		}
		f.SetCellValue(sheetName, fmt.Sprintf("E%d", row), cookieName)

		// 京东订单状态
		statusText := s.getJdOrderStatusText(consts.JdOrderStatus(jdOrder.Status))
		f.SetCellValue(sheetName, fmt.Sprintf("F%d", row), statusText)
	}

	// 生成文件名
	fileName = fmt.Sprintf("京东订单数据_%s.xlsx", gtime.Now().Format("Y-m-d_H-i-s"))

	// 保存到字节数组
	buf, err := f.WriteToBuffer()
	if err != nil {
		return "", nil, gerror.Wrap(err, "生成Excel文件失败")
	}

	return fileName, buf.Bytes(), nil
}

// createEmptyExcel 创建空的Excel文件
func (s *sJdCookie) createEmptyExcel(ctx context.Context) (string, []byte, error) {
	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			glog.Error(ctx, "关闭Excel文件失败", err)
		}
	}()

	// 设置工作表名称
	sheetName := "京东订单数据"
	f.SetSheetName("Sheet1", sheetName)

	// 设置表头
	headers := []string{"京东订单号", "用户订单号", "卡号", "卡密", "ck名称", "京东订单状态"}
	for i, header := range headers {
		cell := fmt.Sprintf("%s1", string(rune('A'+i)))
		f.SetCellValue(sheetName, cell, header)
	}

	// 生成文件名
	fileName := fmt.Sprintf("京东订单数据_%s.xlsx", gtime.Now().Format("Y-m-d_H-i-s"))

	// 保存到字节数组
	buf, err := f.WriteToBuffer()
	if err != nil {
		return "", nil, gerror.Wrap(err, "生成Excel文件失败")
	}

	return fileName, buf.Bytes(), nil
}

// getJdOrderStatusText 获取京东订单状态文本
func (s *sJdCookie) getJdOrderStatusText(status consts.JdOrderStatus) string {
	switch status {
	case consts.JdOrderStatusPending:
		return "待支付"
	case consts.JdOrderStatusPaid:
		return "已支付"
	case consts.JdOrderStatusSent:
		return "已发货"
	case consts.JdOrderStatusExpired:
		return "已过期"
	case consts.JdOrderStatusCanceled:
		return "已取消"
	default:
		return "未知状态"
	}
}
