// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/tag/tag.go
package tag

import (
	"context"

	"github.com/gocql/gocql"

	dom_tag "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/tag"
	uc_tag "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/tag"
)

// TagService provides business logic for tag operations
// Note: With E2EE, the service layer primarily validates encrypted data exists
// and passes it through to use cases. Plaintext validation happens client-side.
type TagService struct {
	createUC           *uc_tag.CreateTagUseCase
	getByIDUC          *uc_tag.GetTagByIDUseCase
	listByUserUC       *uc_tag.ListTagsByUserUseCase
	updateUC           *uc_tag.UpdateTagUseCase
	deleteUC           *uc_tag.DeleteTagUseCase
	assignTagUC        *uc_tag.AssignTagUseCase
	unassignTagUC      *uc_tag.UnassignTagUseCase
	getTagsForEntityUC *uc_tag.GetTagsForEntityUseCase
}

func NewTagService(
	createUC *uc_tag.CreateTagUseCase,
	getByIDUC *uc_tag.GetTagByIDUseCase,
	listByUserUC *uc_tag.ListTagsByUserUseCase,
	updateUC *uc_tag.UpdateTagUseCase,
	deleteUC *uc_tag.DeleteTagUseCase,
	assignTagUC *uc_tag.AssignTagUseCase,
	unassignTagUC *uc_tag.UnassignTagUseCase,
	getTagsForEntityUC *uc_tag.GetTagsForEntityUseCase,
) *TagService {
	return &TagService{
		createUC:           createUC,
		getByIDUC:          getByIDUC,
		listByUserUC:       listByUserUC,
		updateUC:           updateUC,
		deleteUC:           deleteUC,
		assignTagUC:        assignTagUC,
		unassignTagUC:      unassignTagUC,
		getTagsForEntityUC: getTagsForEntityUC,
	}
}

// NOTE: Plaintext validation methods removed - validation happens client-side with E2EE
// The backend only validates that encrypted data exists and is properly formatted

// CreateTag creates a new tag with encrypted data (E2EE)
// The client must send a complete Tag object with encrypted fields
func (s *TagService) CreateTag(ctx context.Context, tag *dom_tag.Tag) error {
	return s.createUC.Execute(ctx, tag)
}

// GetTag retrieves a tag by ID
func (s *TagService) GetTag(ctx context.Context, id gocql.UUID) (*dom_tag.Tag, error) {
	return s.getByIDUC.Execute(ctx, id)
}

// ListUserTags lists all tags for a user
func (s *TagService) ListUserTags(ctx context.Context, userID gocql.UUID) ([]*dom_tag.Tag, error) {
	return s.listByUserUC.Execute(ctx, userID)
}

// UpdateTag updates a tag with new encrypted data (E2EE)
// The client must send a complete updated Tag object with encrypted fields
func (s *TagService) UpdateTag(ctx context.Context, tag *dom_tag.Tag) error {
	return s.updateUC.Execute(ctx, tag)
}

// DeleteTag deletes a tag
func (s *TagService) DeleteTag(ctx context.Context, userID, id gocql.UUID) error {
	return s.deleteUC.Execute(ctx, userID, id)
}

// AssignTag assigns a tag to an entity (collection or file)
func (s *TagService) AssignTag(ctx context.Context, userID, tagID, entityID gocql.UUID, entityType string) error {
	return s.assignTagUC.Execute(ctx, userID, tagID, entityID, entityType)
}

// UnassignTag removes a tag from an entity
func (s *TagService) UnassignTag(ctx context.Context, tagID, entityID gocql.UUID, entityType string) error {
	return s.unassignTagUC.Execute(ctx, tagID, entityID, entityType)
}

// GetTagsForEntity retrieves all tags assigned to an entity
func (s *TagService) GetTagsForEntity(ctx context.Context, entityID gocql.UUID, entityType string) ([]*dom_tag.Tag, error) {
	return s.getTagsForEntityUC.Execute(ctx, entityID, entityType)
}

// CreateDefaultTags has been removed - default tags must be created client-side
// due to E2EE. The client creates default tags after first login.
