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

import (
	"time"

	"github.com/gocql/gocql"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/crypto"
)

// Tag represents a user-defined label with color that can be assigned to collections or files
// All sensitive data (name, color) is encrypted end-to-end using the tag's unique encryption key
type Tag struct {
	// Identifiers
	ID     gocql.UUID `bson:"_id" json:"id"`
	UserID gocql.UUID `bson:"user_id" json:"user_id"` // Owner of the tag

	// Encrypted Tag Details
	// EncryptedName is the tag label (e.g., "Important", "Work") encrypted with the tag key
	EncryptedName string `bson:"encrypted_name" json:"encrypted_name"`
	// EncryptedColor is the hex color code (e.g., "#FF5733") encrypted with the tag key
	EncryptedColor string `bson:"encrypted_color" json:"encrypted_color"`
	// EncryptedTagKey is the unique symmetric key used to encrypt this tag's data (name and color)
	// This key is encrypted with the user's master key for storage and transmission
	EncryptedTagKey *crypto.EncryptedTagKey `bson:"encrypted_tag_key" json:"encrypted_tag_key"`

	// Timestamps and versioning
	CreatedAt  time.Time `bson:"created_at" json:"created_at"`
	ModifiedAt time.Time `bson:"modified_at" json:"modified_at"`
	Version    uint64    `bson:"version" json:"version"` // Versioning for sync

	// State management
	State string `bson:"state" json:"state"` // active, deleted, archived
}

// TagAssignment represents the assignment of a tag to a collection or file
type TagAssignment struct {
	// Identifiers
	ID       gocql.UUID `bson:"_id" json:"id"`
	UserID   gocql.UUID `bson:"user_id" json:"user_id"`     // User who assigned the tag
	TagID    gocql.UUID `bson:"tag_id" json:"tag_id"`       // Reference to the tag
	EntityID gocql.UUID `bson:"entity_id" json:"entity_id"` // Collection or File ID
	// EntityType indicates whether this is a "collection" or "file"
	EntityType string `bson:"entity_type" json:"entity_type"`

	// Timestamps
	CreatedAt time.Time `bson:"created_at" json:"created_at"`
}

// TagListFilter represents filter criteria for listing tags
type TagListFilter struct {
	UserID gocql.UUID
	State  string // Optional: filter by state
}

// TagAssignmentFilter represents filter criteria for tag assignments
type TagAssignmentFilter struct {
	TagID      *gocql.UUID
	EntityID   *gocql.UUID
	EntityType *string
	UserID     *gocql.UUID
}

// EmbeddedTag represents tag data that is embedded in collections and files
// This eliminates the need for frontend API lookups to get tag colors
type EmbeddedTag struct {
	// Core identifiers and data
	ID              gocql.UUID              `bson:"id" json:"id"`
	EncryptedName   string                  `bson:"encrypted_name" json:"encrypted_name"`
	EncryptedColor  string                  `bson:"encrypted_color" json:"encrypted_color"`
	EncryptedTagKey *crypto.EncryptedTagKey `bson:"encrypted_tag_key" json:"encrypted_tag_key"`

	// For cache invalidation - detect stale embedded data
	ModifiedAt time.Time `bson:"modified_at" json:"modified_at"`
}

// ToEmbeddedTag converts a Tag to an EmbeddedTag for embedding in collections/files
func (t *Tag) ToEmbeddedTag() *EmbeddedTag {
	if t == nil {
		return nil
	}
	return &EmbeddedTag{
		ID:              t.ID,
		EncryptedName:   t.EncryptedName,
		EncryptedColor:  t.EncryptedColor,
		EncryptedTagKey: t.EncryptedTagKey,
		ModifiedAt:      t.ModifiedAt,
	}
}
