package order

import (
	"hfb_sys/backend/internal/model"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

type orderAssets struct {
	Order   *model.RentalOrder
	Listing *model.RentalListing
	Account *model.GameAccount
}

func (r *Repository) lockOrderAssets(tx *gorm.DB, orderID uint64) (*orderAssets, error) {
	var order model.RentalOrder
	if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&order, orderID).Error; err != nil {
		return nil, err
	}
	listing, account, err := r.lockListingAccountForOrder(tx, &order)
	if err != nil {
		return nil, err
	}
	return &orderAssets{
		Order:   &order,
		Listing: listing,
		Account: account,
	}, nil
}

func (r *Repository) lockListingAccountForOrder(tx *gorm.DB, order *model.RentalOrder) (*model.RentalListing, *model.GameAccount, error) {
	var listing model.RentalListing
	if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&listing, order.ListingID).Error; err != nil {
		return nil, nil, err
	}
	var account model.GameAccount
	if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&account, order.AccountID).Error; err != nil {
		return nil, nil, err
	}
	return &listing, &account, nil
}

func reserveListingForOrder(listing *model.RentalListing) {
	listing.InTransaction = true
}

func markAssetsRented(listing *model.RentalListing, account *model.GameAccount) {
	listing.Status = listingStatusRented
	account.Status = accountStatusRented
}

func releaseAssetsForRental(listing *model.RentalListing, account *model.GameAccount) {
	listing.Status = listingStatusPublished
	listing.InTransaction = false
	account.Status = accountStatusPublished
}

func archiveAssets(listing *model.RentalListing, account *model.GameAccount) {
	listing.Status = listingStatusOffline
	listing.InTransaction = false
	listing.PublishedAt = nil
	account.Status = accountStatusOffline
}

func markAssetsAbnormal(listing *model.RentalListing, account *model.GameAccount) {
	listing.Status = listingStatusAbnormal
	listing.InTransaction = false
	listing.PublishedAt = nil
	account.Status = accountStatusAbnormal
}
