package camel_oil

import (
	"context"
	"fmt"
	"kami/utility/utils"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/os/glog"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/shopspring/decimal"

	v1 "kami/api/camel_oil/v1"
	"kami/internal/consts"
	"kami/internal/dao"
	"kami/internal/model/do"
	"kami/internal/model/entity"
	"kami/utility/config"
)

// ====================================================================================
// 订单管理相关方法
// ====================================================================================

// UpdateOrderStatus 更新订单状态并记录历史
func (s *sCamelOil) UpdateOrderStatus(ctx context.Context, orderId int64, newStatus consts.CamelOilOrderStatus, operationType consts.CamelOilOrderChangeType, rawData string, description string) (err error) {
	m := dao.V1CamelOilOrder.Ctx(ctx).DB(config.GetDatabaseV1())

	// 获取当前订单信息
	var order *entity.V1CamelOilOrder
	err = m.Where(dao.V1CamelOilOrder.Columns().Id, orderId).Scan(&order)
	if err != nil {
		return gerror.Wrap(err, "查询订单失败")
	}

	if order == nil {
		return gerror.New("订单不存在")
	}

	oldStatus := consts.CamelOilOrderStatus(order.Status)

	// 如果状态没有变化，则不更新
	if oldStatus == newStatus {
		return nil
	}

	// 更新订单状态
	_, err = m.Where(dao.V1CamelOilOrder.Columns().Id, orderId).Update(&do.V1CamelOilOrder{
		Status: int(newStatus),
	})

	if err != nil {
		return gerror.Wrap(err, "更新订单状态失败")
	}

	// 记录订单变更历史
	_ = s.RecordOrderHistory(ctx, order.OrderNo, operationType, rawData, description)

	g.Log().Infof(ctx, "订单状态更新成功，订单号=%s, 原状态=%d, 新状态=%d", order.OrderNo, oldStatus, newStatus)

	return nil
}

// SubmitOrder 提交订单并返回支付宝支付链接
func (s *sCamelOil) SubmitOrder(ctx context.Context, req *v1.SubmitOrderReq) (res *v1.SubmitOrderRes, err error) {
	var order *entity.V1CamelOilOrder
	_ = dao.V1CamelOilOrder.Ctx(ctx).DB(config.GetDatabaseV1()).Where(dao.V1CamelOilOrder.Columns().MerchantOrderId, req.MerchantOrderId).Scan(&order)
	if order != nil {
		if order.Status != int(consts.CamelOilOrderStatusPending) {
			return nil, gerror.New("订单已失效")
		}
		return &v1.SubmitOrderRes{
			OrderNo:   order.OrderNo,
			AlipayUrl: order.AlipayUrl,
			Amount:    req.Amount,
			CreatedAt: order.CreatedAt,
		}, nil
	}

	orderId := fmt.Sprintf("CO%s", utils.GenerateRandomUUID())
	prefetchOrder, err := s.MatchPrefetchOrder(ctx, orderId, req.Amount)
	if prefetchOrder == nil {
		prefetchOrder, err = s.PrefetchOrderConcurrently(ctx, req.Amount)
		if err != nil || prefetchOrder == nil {
			return nil, gerror.Wrap(err, "拉取订单失败")
		}
	}

	// 2. 创建空订单记录
	_, err = dao.V1CamelOilOrder.Ctx(ctx).DB(config.GetDatabaseV1()).Insert(&do.V1CamelOilOrder{
		OrderNo:         orderId,
		MerchantOrderId: req.MerchantOrderId,
		Amount:          decimal.NewFromFloat(req.Amount),
		Status:          consts.CamelOilOrderStatusPending,    // 1=待支付
		PayStatus:       consts.CamelOilPaymentStatusUnpaid,   // 0=未支付
		NotifyStatus:    consts.CamelOilCallbackStatusPending, // 0=未回调
		NotifyCount:     0,
		AccountId:       prefetchOrder.AccountId,
		AccountName:     prefetchOrder.AccountName,
		PlatformOrderNo: prefetchOrder.PlatformOrderNo,
		AlipayUrl:       prefetchOrder.AlipayUrl,
		Attach:          req.Attach,
	})
	if err != nil {
		return nil, gerror.Wrap(err, "更新订单失败")
	}

	// 更新账号使用记录
	_, _ = dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CamelOilAccount.Columns().Id, prefetchOrder.AccountId).
		Increment(dao.V1CamelOilAccount.Columns().DailyOrderCount, 1)

	_, _ = dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CamelOilAccount.Columns().Id, prefetchOrder.AccountId).
		Increment(dao.V1CamelOilAccount.Columns().TotalOrderCount, 1)

	glog.Infof(ctx, "订单提交成功: 订单号=%s", orderId)

	res = &v1.SubmitOrderRes{
		OrderNo:   orderId,
		AlipayUrl: prefetchOrder.AlipayUrl,
		Amount:    req.Amount,
		CreatedAt: gtime.Now(),
	}

	return res, nil
}

// ====================================================================================
// 卡密填写相关方法
// ====================================================================================

// FillOrderCard 填写订单卡密和卡号
func (s *sCamelOil) fillOrderCard(ctx context.Context, orderNo string, cardNumber string, cardPassword string) error {
	// 1. 查询订单信息
	var order *entity.V1CamelOilOrder
	err := dao.V1CamelOilOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CamelOilOrder.Columns().OrderNo, orderNo).
		Scan(&order)
	if err != nil {
		return gerror.Wrap(err, "查询订单失败")
	}
	if order == nil {
		return gerror.New("订单不存在")
	}

	// 2. 更新卡密和卡号
	_, err = dao.V1CamelOilOrder.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CamelOilOrder.Columns().OrderNo, orderNo).
		Update(&do.V1CamelOilOrder{
			CardPassword: cardPassword,
			CardNumber:   cardNumber,
			PaidAt:       gtime.Now(),
			PayStatus:    consts.CamelOilPaymentStatusPaid,
		})
	if err != nil {
		return gerror.Wrap(err, "更新卡密失败")
	}

	// 3. 记录操作历史
	remark := fmt.Sprintf("填写卡密和卡号")
	_, err = dao.V1CamelOilOrderHistory.Ctx(ctx).DB(config.GetDatabaseV1()).Data(&do.V1CamelOilOrderHistory{
		OrderNo:     orderNo,
		ChangeType:  consts.CamelOilOrderChangeTypeFillCard,
		AccountId:   order.AccountId,
		AccountName: order.AccountName,
		Remark:      remark,
	}).Insert()
	if err != nil {
		g.Log().Errorf(ctx, "记录订单历史失败：%v", err)
	}

	return nil
}

// IncrementAccountOrderCount 增加账户订单计数（支付成功时调用）
func (s *sCamelOil) IncrementAccountOrderCount(ctx context.Context, accountId int64) error {
	if accountId <= 0 {
		return gerror.New("账户ID无效")
	}

	// 增加日订单计数
	_, err := dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CamelOilAccount.Columns().Id, accountId).
		Update(gdb.Map{
			dao.V1CamelOilAccount.Columns().DailyOrderCount: gdb.Counter{Field: dao.V1CamelOilAccount.Columns().DailyOrderCount, Value: 1},
			dao.V1CamelOilAccount.Columns().TotalOrderCount: gdb.Counter{Field: dao.V1CamelOilAccount.Columns().TotalOrderCount, Value: 1},
		})
	if err != nil {
		return gerror.Wrap(err, "增加账户日订单计数失败")
	}

	glog.Infof(ctx, "账户订单计数增加成功，账户ID=%d", accountId)
	return nil
}
