package order_test

import (
	"testing"

	"cloud.o-forge.io/core/oc-lib/models/common/enum"
	"cloud.o-forge.io/core/oc-lib/models/order"
	"cloud.o-forge.io/core/oc-lib/models/resources/purchase_resource"
	"cloud.o-forge.io/core/oc-lib/tools"
	"github.com/stretchr/testify/assert"
)

// ---- Order model ----

func TestOrder_StoreDraftDefault(t *testing.T) {
	o := &order.Order{}
	o.StoreDraftDefault()
	assert.True(t, o.IsDraft)
}

func TestOrder_CanDelete_Draft(t *testing.T) {
	o := &order.Order{}
	o.IsDraft = true
	assert.True(t, o.CanDelete())
}

func TestOrder_CanDelete_NonDraft(t *testing.T) {
	o := &order.Order{}
	o.IsDraft = false
	assert.False(t, o.CanDelete())
}

func TestOrder_CanUpdate_StatusChange_NonDraft(t *testing.T) {
	o := &order.Order{Status: enum.PENDING}
	o.IsDraft = false
	set := &order.Order{Status: enum.PAID}
	ok, returned := o.CanUpdate(set)
	assert.True(t, ok)
	assert.Equal(t, enum.PAID, returned.(*order.Order).Status)
}

func TestOrder_CanUpdate_SameStatus_NonDraft(t *testing.T) {
	o := &order.Order{Status: enum.PENDING}
	o.IsDraft = false
	set := &order.Order{Status: enum.PENDING}
	ok, _ := o.CanUpdate(set)
	// !r.IsDraft && r.Status == set.Status → first branch false → returns r.IsDraft = false
	assert.False(t, ok)
}

func TestOrder_CanUpdate_Draft(t *testing.T) {
	o := &order.Order{Status: enum.PENDING}
	o.IsDraft = true
	set := &order.Order{Status: enum.PAID}
	ok, _ := o.CanUpdate(set)
	// !r.IsDraft = false → first branch false → returns r.IsDraft = true
	assert.True(t, ok)
}

func TestOrder_Quantity(t *testing.T) {
	o := &order.Order{
		Purchases: []*purchase_resource.PurchaseResource{{}, {}},
	}
	// Quantity = len(Purchases) + len(Purchases) (note: there is a bug in source: uses Purchases twice)
	assert.Equal(t, 4, o.Quantity())
}

func TestOrder_Quantity_Empty(t *testing.T) {
	o := &order.Order{}
	assert.Equal(t, 0, o.Quantity())
}

func TestOrder_SetName(t *testing.T) {
	o := &order.Order{}
	o.UUID = "order-uuid"
	o.SetName("ignored")
	// Name is generated from UUID, not from the argument
	assert.Contains(t, o.Name, "order-uuid")
	assert.Contains(t, o.Name, "_order_")
}

func TestOrder_GetAccessor(t *testing.T) {
	o := &order.Order{}
	acc := o.GetAccessor(&tools.APIRequest{})
	assert.NotNil(t, acc)
}

func TestOrder_GetAccessor_NilRequest(t *testing.T) {
	o := &order.Order{}
	acc := o.GetAccessor(nil)
	assert.NotNil(t, acc)
}
