package jd_cookie

import (
	"context"
	v1 "kami/api/jd_cookie/v1"
	"kami/internal/consts"
	"kami/internal/dao"
	"kami/internal/model"
	"kami/internal/model/entity"
	"kami/utility/config"
	"slices"

	"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"
)

// GetPaymentUrl 获取支付链接
func (s *sJdCookie) GetPaymentUrl(ctx context.Context, userOrderId, orderId string) (result *model.PaymentResult, err error) {
	if orderId == "" {
		return nil, gerror.New("订单号不能为空")
	}

	// 获取订单信息
	order, err := s.getOrderByOrderId(ctx, orderId)
	if err != nil {
		return nil, gerror.Wrap(err, "查询订单失败")
	}
	if order == nil {
		return nil, gerror.New(consts.ErrCodeOrderNotFound)
	}

	// 检查订单状态，如果是失败状态，尝试重新创建京东订单
	orderStatus := consts.OrderStatus(order.Status)
	// 订单已存在，检查订单状态
	if !slices.Contains([]consts.OrderStatus{
		consts.OrderStatusJDOrderFailed, consts.OrderStatusCreated, consts.OrderStatusPending,
	}, orderStatus) {
		return nil, gerror.New("订单已完成")
	}
	if orderStatus == consts.OrderStatusJDOrderFailed {
		glog.Info(ctx, "检测到失败订单，尝试重新创建京东订单", g.Map{
			"orderId":     orderId,
			"userOrderId": userOrderId,
			"status":      orderStatus,
		})

		// 尝试重新创建京东订单
		retryResult, retryErr := s.retryCreateJdOrderForFailedOrder(ctx, order, &model.CreateOrderReq{
			UserOrderId: userOrderId,
			Amount:      gconv.Float64(order.Amount),
			Category:    consts.RedeemOrderCardCategory(order.Category),
		})
		if retryErr != nil {
			// 重试失败，返回错误
			return nil, retryErr
		}

		// 重试成功，返回新的支付信息
		return &model.PaymentResult{
			WxPayUrl:  retryResult.WxPayUrl,
			JdOrderId: retryResult.JdOrderId,
			OrderId:   retryResult.OrderId,
		}, nil
	}

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

	jdOrderId := jdOrder.JdOrderId
	wxPayUrl := jdOrder.WxPayUrl

	// 检查支付链接是否有效
	if jdOrder.WxPayExpireAt != nil && gtime.Now().After(jdOrder.WxPayExpireAt) {
		// 刷新京东订单
		newWxPayUrl, isCkFailed, refreshErr := s.refreshPaymentUrl(ctx, &model.RefreshPaymentUrlReq{
			JdOrderId: jdOrder.JdOrderId,
			PayId:     jdOrder.PayId,
			CookieId:  jdOrder.CookieId,
		})
		if isCkFailed {
			s.handleCookieFailure(ctx, userOrderId, jdOrder.CookieId, jdOrder.JdOrderId, isCkFailed, refreshErr.Error())
		}
		if refreshErr != nil {
			// 刷新失败，标记旧订单为失效
			_ = s.UpdateJdOrderStatus(ctx, jdOrder.JdOrderId, consts.JdOrderStatusExpired, jdOrder.WxPayUrl, refreshErr.Error())
			_ = s.RecordCookieHistory(ctx, &model.RecordCookieHistoryReq{
				CookieId:     jdOrder.CookieId,
				ChangeType:   consts.CookieChangeTypeRefreshFail,
				StatusBefore: consts.JdCookieStatusUnknown,
				StatusAfter:  consts.JdCookieStatusExpired,
				OrderId:      orderId,
				UserOrderId:  userOrderId,
				FailureCount: 0,
				Remark:       "刷新支付链接失败",
			})

			// 解绑旧京东订单
			_ = s.updateJdOrderId(ctx, jdOrder.JdOrderId, "")

			// 创建新的京东订单（带重试机制）
			retryRes, createErr := s.createNewJdOrderWithRetry(ctx, &model.CreateNewJdOrderWithRetryReq{
				OrderId:     orderId,
				UserOrderId: userOrderId,
				Amount:      gconv.Float64(order.Amount),
				Category:    consts.RedeemOrderCardCategory(order.Category),
			})
			if createErr != nil {
				return nil, gerror.Wrap(createErr, "刷新失败且创建新订单失败")
			}

			// 更新订单关联的京东订单ID
			_ = s.updateOrderJdOrderId(ctx, orderId, retryRes.JdOrderId)

			// 京东订单创建成功，更新本地订单状态为待支付，并关联京东订单
			err = s.updateOrderSuccess(ctx, orderId, retryRes.JdOrderId)
			if err != nil {
				glog.Error(ctx, "更新订单状态失败", g.Map{
					"orderId":   orderId,
					"jdOrderId": jdOrderId,
					"error":     err,
				})
				return nil, gerror.Wrap(err, "更新订单信息失败")
			}

			// 更新京东订单的当前关联订单ID
			_ = s.updateJdOrderId(ctx, retryRes.JdOrderId, orderId)

			// 记录订单重新绑定历史
			go func() {
				_ = s.RecordOrderHistory(ctx, &model.RecordOrderHistoryReq{
					OrderId:    orderId,
					ChangeType: consts.OrderChangeTypeBind,
					JdOrderId:  retryRes.JdOrderId,
					Remark:     "",
				})
				// 记录Cookie使用历史
				_ = s.RecordCookieHistory(ctx, &model.RecordCookieHistoryReq{
					CookieId:     retryRes.CookieId,
					UserOrderId:  userOrderId,
					ChangeType:   consts.CookieChangeTypeUse,
					StatusBefore: consts.JdCookieStatusNormal,
					StatusAfter:  consts.JdCookieStatusNormal,
					OrderId:      orderId,
					FailureCount: 0,
				})

			}()

			// 返回新的支付信息
			jdOrderId = retryRes.JdOrderId
			wxPayUrl = retryRes.WxPayUrl
		} else {
			// 刷新成功，更新支付链接
			wxPayUrl = newWxPayUrl
			_ = s.updateJdOrderPaymentUrl(ctx, jdOrderId, wxPayUrl)
		}
	}

	// 更新订单最后请求时间
	_ = s.updateOrderLastRequest(ctx, orderId)

	return &model.PaymentResult{
		WxPayUrl:  wxPayUrl,
		JdOrderId: jdOrderId,
		OrderId:   order.OrderId,
	}, nil
}

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

	orderEntity, err := s.getOrderByOrderId(ctx, orderId)
	if err != nil {
		return nil, gerror.Wrap(err, "查询订单失败")
	}
	if orderEntity == nil {
		return nil, gerror.New(consts.ErrCodeOrderNotFound)
	}

	order = &v1.OrderInfo{
		Id:          orderEntity.Id,
		OrderId:     orderEntity.OrderId,
		UserOrderId: orderEntity.UserOrderId,
		Amount:      gconv.Float64(orderEntity.Amount),
		Category:    orderEntity.Category,
		JdOrderId:   orderEntity.JdOrderId,
		Status:      consts.OrderStatus(orderEntity.Status),
		LastRequest: orderEntity.LastRequestAt,
		CreatedAt:   orderEntity.CreatedAt,
		UpdatedAt:   orderEntity.UpdatedAt,
		DeletedAt:   orderEntity.DeletedAt,
	}

	return
}

// GetOrderStatus 查询订单状态
func (s *sJdCookie) GetOrderStatus(ctx context.Context, orderId string) (order *v1.OrderInfo, err error) {
	if orderId == "" {
		return nil, gerror.New("订单号不能为空")
	}

	orderEntity, err := s.getOrderByOrderId(ctx, orderId)
	if err != nil {
		return nil, gerror.Wrap(err, "查询订单失败")
	}
	if orderEntity == nil {
		return nil, gerror.New(consts.ErrCodeOrderNotFound)
	}

	order = &v1.OrderInfo{
		Id:          orderEntity.Id,
		OrderId:     orderEntity.OrderId,
		UserOrderId: orderEntity.UserOrderId,
		Amount:      gconv.Float64(orderEntity.Amount),
		Category:    orderEntity.Category,
		JdOrderId:   orderEntity.JdOrderId,
		Status:      consts.OrderStatus(orderEntity.Status),
		LastRequest: orderEntity.LastRequestAt,
		CreatedAt:   orderEntity.CreatedAt,
		UpdatedAt:   orderEntity.UpdatedAt,
		DeletedAt:   orderEntity.DeletedAt,
	}

	return
}

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

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

	// 构建查询条件
	if status > 0 {
		m = m.Where(dao.V1JdCookieOrder.Columns().Status, int(status))
	}
	if startTime != "" {
		m = m.WhereGTE(dao.V1JdCookieOrder.Columns().CreatedAt, startTime)
	}
	if endTime != "" {
		m = m.WhereLTE(dao.V1JdCookieOrder.Columns().CreatedAt, endTime)
	}

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

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

	// 转换为响应格式
	list = make([]*v1.OrderInfo, 0, len(orders))
	for _, orderEntity := range orders {
		info := &v1.OrderInfo{
			Id:          orderEntity.Id,
			OrderId:     orderEntity.OrderId,
			UserOrderId: orderEntity.UserOrderId,
			Amount:      gconv.Float64(orderEntity.Amount),
			Category:    orderEntity.Category,
			JdOrderId:   orderEntity.JdOrderId,
			Status:      consts.OrderStatus(orderEntity.Status),
			LastRequest: orderEntity.LastRequestAt,
			CreatedAt:   orderEntity.CreatedAt,
			UpdatedAt:   orderEntity.UpdatedAt,
			DeletedAt:   orderEntity.DeletedAt,
		}
		list = append(list, info)
	}

	return
}
