package logic

import (
	"context"
	"errors"
	"time"

	"juwan-backend/app/order/rpc/internal/svc"
	"juwan-backend/app/order/rpc/pb"
	"juwan-backend/app/snowflake/rpc/snowflake"

	"github.com/shopspring/decimal"

	"github.com/zeromicro/go-zero/core/logx"
)

type AddOrdersLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewAddOrdersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddOrdersLogic {
	return &AddOrdersLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

// -----------------------orders-----------------------
func (l *AddOrdersLogic) AddOrders(in *pb.AddOrdersReq) (*pb.AddOrdersResp, error) {
	idResp, err := l.svcCtx.Snowflake.NextId(l.ctx, &snowflake.NextIdReq{})
	if err != nil {
		return nil, err
	}
	orderID := idResp.Id

	totalPrice, err := parseDecimal(in.GetTotalPrice())
	if err != nil || totalPrice.Cmp(decimal.Zero) <= 0 {
		return nil, errors.New("invalid total price")
	}

	serviceSnapshot, err := parseJSONMap(in.GetServiceSnapshot())
	if err != nil {
		return nil, err
	}

	creator := l.svcCtx.OrderModelsRW.Orders.Create().
		SetID(orderID).
		SetConsumerID(in.ConsumerId).
		SetPlayerID(in.PlayerId).
		SetServiceSnapshot(serviceSnapshot).
		SetTotalPrice(totalPrice)

	if in.ShopId != nil {
		creator = creator.SetShopID(*in.ShopId)
	}
	if in.Status != nil && *in.Status != "" {
		creator = creator.SetStatus(*in.Status)
	}
	if in.Note != nil {
		creator = creator.SetNote(*in.Note)
	}
	if in.Version != nil {
		creator = creator.SetVersion(int(*in.Version))
	}
	if in.TimeoutJobId != nil {
		creator = creator.SetTimeoutJobID(*in.TimeoutJobId)
	}
	if createdAt := unixPtr(in.CreatedAt); createdAt != nil {
		creator = creator.SetCreatedAt(*createdAt)
	}
	if acceptedAt := unixPtr(in.AcceptedAt); acceptedAt != nil {
		creator = creator.SetAcceptedAt(*acceptedAt)
	}
	if closedAt := unixPtr(in.ClosedAt); closedAt != nil {
		creator = creator.SetClosedAt(*closedAt)
	}
	if completedAt := unixPtr(in.CompletedAt); completedAt != nil {
		creator = creator.SetCompletedAt(*completedAt)
	}
	if cancelledAt := unixPtr(in.CancelledAt); cancelledAt != nil {
		creator = creator.SetCancelledAt(*cancelledAt)
	}
	if updatedAt := unixPtr(in.UpdatedAt); updatedAt != nil {
		creator = creator.SetUpdatedAt(*updatedAt)
	} else {
		creator = creator.SetUpdatedAt(time.Now())
	}

	if _, err := creator.Save(l.ctx); err != nil {
		return nil, err
	}

	return &pb.AddOrdersResp{Id: orderID}, nil
}
