package order

import (
	"time"

	"cloud.o-forge.io/core/oc-lib/models/booking"
	"cloud.o-forge.io/core/oc-lib/models/common/enum"
	"cloud.o-forge.io/core/oc-lib/models/common/pricing"
	"cloud.o-forge.io/core/oc-lib/models/resources/purchase_resource"
	"cloud.o-forge.io/core/oc-lib/models/utils"
	"cloud.o-forge.io/core/oc-lib/tools"
)

/*
* Booking is a struct that represents a booking
 */

type Order struct {
	utils.AbstractObject
	ExecutionsID string                                `json:"executions_id" bson:"executions_id" validate:"required"`
	Status       enum.CompletionStatus                 `json:"status" bson:"status" default:"0"`
	Purchases    []*purchase_resource.PurchaseResource `json:"purchases" bson:"purchases"`
	Bookings     []*booking.Booking                    `json:"bookings" bson:"bookings"`

	// Billing groupe les bookings par fréquence de facturation, peuplé par GenerateOrder.
	Billing map[pricing.BillingStrategy][]*booking.Booking `json:"billing" bson:"billing"`

	// SubscriptionIDs liste les abonnements récurrents créés pour cet order
	// (un par peer × stratégie de facturation). Peuplé par DraftFirstBill.
	SubscriptionIDs []string `json:"subscription_ids,omitempty" bson:"subscription_ids,omitempty"`
}

func (r *Order) StoreDraftDefault() {
	r.IsDraft = true
}

func (r *Order) CanUpdate(set utils.DBObject) (bool, utils.DBObject) {
	if !r.IsDraft && r.Status != set.(*Order).Status {
		return true, &Order{Status: set.(*Order).Status} // only state can be updated
	}
	return r.IsDraft, set
}

func (r *Order) CanDelete() bool {
	return r.IsDraft // only draft order can be deleted
}

func (o *Order) Quantity() int {
	return len(o.Purchases) + len(o.Purchases)
}

func (d *Order) SetName(_ string) {
	d.Name = d.UUID + "_order_" + "_" + time.Now().UTC().Format("2006-01-02T15:04:05")
}

func (d *Order) GetAccessor(request *tools.APIRequest) utils.Accessor {
	return NewAccessor(request) // Create a new instance of the accessor
}
