// Package actor stores the calling user (tenant_id + uid) on a request
// context so middleware can inject it once and any downstream layer
// (handler / logic / usecase / repository) can read it without
// re-parsing the JWT.
//
// The package lives under internal/library because it is depended on
// by BOTH internal/middleware AND internal/logic/*. Defining the
// context key here is the only way to keep a single key value across
// packages (Go context.Value keys are typed by package, so each
// package would otherwise get its own isolated slot).
package actor

import (
	"context"
	"fmt"
)

type contextKey struct{}

// Actor identifies the calling tenant member, injected by the AuthJWT
// middleware after a successful Bearer token parse.
type Actor struct {
	TenantID string
	UID      string
}

// WithActor stores tenant/uid on ctx. Returns the original ctx
// unchanged when either field is empty.
func WithActor(ctx context.Context, tenantID, uid string) context.Context {
	if tenantID == "" || uid == "" {
		return ctx
	}
	return context.WithValue(ctx, contextKey{}, Actor{TenantID: tenantID, UID: uid})
}

// ActorFromContext returns the actor injected by AuthJWT. The error is
// a plain error (no biz code) so callers can wrap it with their own
// scope-specific Builder when needed.
func ActorFromContext(ctx context.Context) (Actor, error) {
	v, ok := ctx.Value(contextKey{}).(Actor)
	if !ok || v.TenantID == "" || v.UID == "" {
		return Actor{}, fmt.Errorf("missing bearer token or X-Tenant-ID/X-UID headers")
	}
	return v, nil
}
