package logic

import (
	"context"
	"errors"

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

	"github.com/shopspring/decimal"

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

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

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

func (l *UpdateOrdersLogic) UpdateOrders(in *pb.UpdateOrdersReq) (*pb.UpdateOrdersResp, error) {
	updater := l.svcCtx.OrderModelsRW.Orders.UpdateOneID(in.Id)

	if in.ConsumerId != nil {
		updater = updater.SetConsumerID(*in.ConsumerId)
	}
	if in.PlayerId != nil {
		updater = updater.SetPlayerID(*in.PlayerId)
	}
	if in.ShopId != nil {
		updater = updater.SetShopID(*in.ShopId)
	}
	if in.ServiceSnapshot != nil {
		snapshot, err := parseJSONMap(*in.ServiceSnapshot)
		if err != nil {
			return nil, err
		}
		updater = updater.SetServiceSnapshot(snapshot)
	}
	if in.Status != nil {
		updater = updater.SetStatus(*in.Status)
	}
	if in.TotalPrice != nil {
		price, err := parseDecimal(*in.TotalPrice)
		if err != nil || price.Cmp(decimal.Zero) <= 0 {
			return nil, errors.New("invalid total price")
		}
		updater = updater.SetTotalPrice(price)
	}
	if in.Note != nil {
		updater = updater.SetNote(*in.Note)
	}
	if in.Version != nil {
		updater = updater.SetVersion(int(*in.Version))
	}
	if in.TimeoutJobId != nil {
		updater = updater.SetTimeoutJobID(*in.TimeoutJobId)
	}
	if in.SearchText != nil {
		updater = updater.SetSearchText(*in.SearchText)
	}
	if acceptedAt := unixPtr(in.AcceptedAt); acceptedAt != nil {
		updater = updater.SetAcceptedAt(*acceptedAt)
	}
	if closedAt := unixPtr(in.ClosedAt); closedAt != nil {
		updater = updater.SetClosedAt(*closedAt)
	}
	if completedAt := unixPtr(in.CompletedAt); completedAt != nil {
		updater = updater.SetCompletedAt(*completedAt)
	}
	if cancelledAt := unixPtr(in.CancelledAt); cancelledAt != nil {
		updater = updater.SetCancelledAt(*cancelledAt)
	}
	if updatedAt := unixPtr(in.UpdatedAt); updatedAt != nil {
		updater = updater.SetUpdatedAt(*updatedAt)
	}

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

	return &pb.UpdateOrdersResp{}, nil
}
