package ledger

import (
	"time"

	"go.mongodb.org/mongo-driver/v2/bson"
)

// OwnershipRole captures legal roles (not permissions).
type OwnershipRole string

const (
	RoleLegalOwner      OwnershipRole = "legal_owner"
	RoleBeneficialOwner OwnershipRole = "beneficial_owner"
	RoleCustodian       OwnershipRole = "custodian"
	RoleSignatory       OwnershipRole = "signatory"
)

type Ownership struct {
	OwnerPartyRef bson.ObjectID `bson:"ownerPartyRef"         json:"ownerPartyRef"`
	Role          OwnershipRole `bson:"role"                  json:"role"`
	SharePct      *float64      `bson:"sharePct,omitempty"    json:"sharePct,omitempty"` // 0..100; nil = unspecified
	From          time.Time     `bson:"effectiveFrom"         json:"effectiveFrom"`
	To            *time.Time    `bson:"effectiveTo,omitempty" json:"effectiveTo,omitempty"` // active if t < To; nil = open
}

func (o *Ownership) Validate() error {
	var verr *ValidationError

	if o.OwnerPartyRef.IsZero() {
		veAdd(&verr, "ownerPartyRef", "required", "owner party reference required")
	}
	switch o.Role {
	case RoleLegalOwner, RoleBeneficialOwner, RoleCustodian, RoleSignatory:
	default:
		veAdd(&verr, "role", "invalid", "unknown ownership role")
	}
	if o.SharePct != nil {
		if *o.SharePct < 0 || *o.SharePct > 100 {
			veAdd(&verr, "sharePct", "out_of_range", "must be between 0 and 100")
		}
	}
	if o.To != nil && o.To.Before(o.From) {
		veAdd(&verr, "effectiveTo", "before_from", "must be >= effectiveFrom")
	}
	if verr == nil {
		return nil
	}
	return verr
}

func (o *Ownership) ActiveAt(t time.Time) bool {
	if t.Before(o.From) {
		return false
	}
	if o.To != nil && !t.Before(*o.To) { // active iff t < To
		return false
	}
	return true
}
