package repository

import (
	"github.com/tech/sendico/pkg/db/repository/builder"
	"github.com/tech/sendico/pkg/model"
	"go.mongodb.org/mongo-driver/v2/bson"
)

// AccountBoundFilter provides factory methods for creating account-bound filters
type AccountBoundFilter struct{}

// NewAccountBoundFilter creates a new AccountBoundFilter instance
func NewAccountBoundFilter() *AccountBoundFilter {
	return &AccountBoundFilter{}
}

// WithoutOrg creates a filter for account-bound objects without organization filter
// This filter finds objects where:
// - accountRef matches the provided accountRef, OR
// - accountRef is nil/null, OR
// - accountRef field doesn't exist
func (f *AccountBoundFilter) WithoutOrg(accountRef bson.ObjectID) builder.Query {
	return Query().Or(
		AccountFilter(accountRef),
		Filter(model.AccountRefField, nil),
		Exists(AccountField(), false),
	)
}

// WithOrg creates a filter for account-bound objects with organization filter
// This filter finds objects where:
// - accountRef matches the provided accountRef, OR
// - accountRef is nil/null, OR
// - accountRef field doesn't exist
// AND combines with organization filter
func (f *AccountBoundFilter) WithOrg(accountRef, organizationRef bson.ObjectID) builder.Query {
	return Query().And(
		OrgFilter(organizationRef),
		f.WithoutOrg(accountRef),
	)
}

// WithQuery creates a filter for account-bound objects with additional query and organization filter
func (f *AccountBoundFilter) WithQuery(accountRef, organizationRef bson.ObjectID, additionalQuery builder.Query) builder.Query {
	accountQuery := f.WithOrg(accountRef, organizationRef)
	return additionalQuery.And(accountQuery)
}

// WithQueryNoOrg creates a filter for account-bound objects with additional query but no org filter
func (f *AccountBoundFilter) WithQueryNoOrg(accountRef bson.ObjectID, additionalQuery builder.Query) builder.Query {
	accountQuery := f.WithoutOrg(accountRef)
	return additionalQuery.And(accountQuery)
}

// Global instance for convenience
var DefaultAccountBoundFilter = NewAccountBoundFilter()

// Convenience functions that use the global factory instance

// WithOrg is a convenience function that uses the default factory
func WithOrg(accountRef, organizationRef bson.ObjectID) builder.Query {
	return DefaultAccountBoundFilter.WithOrg(accountRef, organizationRef)
}

// WithoutOrg is a convenience function that uses the default factory
func WithoutOrg(accountRef bson.ObjectID) builder.Query {
	return DefaultAccountBoundFilter.WithoutOrg(accountRef)
}

// WithQuery is a convenience function that uses the default factory
func WithQuery(accountRef, organizationRef bson.ObjectID, additionalQuery builder.Query) builder.Query {
	return DefaultAccountBoundFilter.WithQuery(accountRef, organizationRef, additionalQuery)
}

// WithQueryNoOrg is a convenience function that uses the default factory
func WithQueryNoOrg(accountRef bson.ObjectID, additionalQuery builder.Query) builder.Query {
	return DefaultAccountBoundFilter.WithQueryNoOrg(accountRef, additionalQuery)
}
