package logic

import (
	"context"
	"errors"
	"strconv"
	"time"

	"juwan-backend/app/snowflake/rpc/snowflake"

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

	"github.com/shopspring/decimal"

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

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

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

// -----------------------walletTransactions-----------------------
func (l *AddWalletTransactionsLogic) AddWalletTransactions(in *pb.AddWalletTransactionsReq) (*pb.AddWalletTransactionsResp, error) {
	idResp, err := l.svcCtx.Snowflake.NextId(l.ctx, &snowflake.NextIdReq{})
	if err != nil {
		return nil, err
	}

	createdAt := time.Now()
	if in.CreatedAt > 0 {
		createdAt = time.Unix(in.CreatedAt, 0)
	}

	searchText := in.SearchText
	if searchText == "" {
		searchText = in.Type + " " + in.Description
	}

	amount, err := decimal.NewFromString(in.GetAmount())
	if err != nil {
		return nil, errors.New("invalid amount")
	}
	balanceAfter, err := decimal.NewFromString(in.GetBalanceAfter())
	if err != nil {
		return nil, errors.New("invalid balanceAfter")
	}

	tx, err := l.svcCtx.WalletModelsRW.Tx(l.ctx)
	if err != nil {
		return nil, err
	}

	_, err = tx.WalletTransactions.Create().
		SetID(strconv.FormatInt(idResp.Id, 10)).
		SetUserID(in.UserId).
		SetType(in.Type).
		SetAmount(amount).
		SetBalanceAfter(balanceAfter).
		SetDescription([]string{in.Description}).
		SetOrderID(in.OrderId).
		SetCreatedAt(createdAt).
		Save(l.ctx)
	if err != nil {
		_ = tx.Rollback()
		return nil, err
	}

	if err = tx.Commit(); err != nil {
		return nil, err
	}

	return &pb.AddWalletTransactionsResp{}, nil
}
