"""
Tag model definitions.

Tags are unified across user-created tags, ML-detected objects, scene
labels, and face clusters via the `kind` column. The `photo_tags`
association carries per-photo ML metadata (confidence, bounding box,
source model).
"""
from sqlalchemy import Column, String, Float, ForeignKey, Table, Index, UniqueConstraint  # noqa: F401
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import JSONB
import uuid

from app.database import Base

# Association table for many-to-many relationship
photo_tags = Table(
    'photo_tags',
    Base.metadata,
    Column('photo_id', String, ForeignKey('photos.id', ondelete='CASCADE'), primary_key=True),
    Column('tag_id', String, ForeignKey('tags.id', ondelete='CASCADE'), primary_key=True),
    # ML metadata — null for user-applied tags
    Column('confidence', Float, nullable=True),
    Column('bbox', JSONB, nullable=True),       # [x1, y1, x2, y2] normalized 0-1
    Column('source', String, nullable=True),     # e.g. "vision:clip_classifier"
    Index('ix_photo_tags_photo_id', 'photo_id'),
    Index('ix_photo_tags_tag_id', 'tag_id'),
)

class Tag(Base):
    __tablename__ = 'tags'
    __table_args__ = (
        UniqueConstraint('name', 'kind', 'user_id', name='uq_tags_name_kind_user'),
    )

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    name = Column(String, nullable=False, index=True)
    color = Column(String)  # Hex color code for UI display

    # Owner
    user_id = Column(String, ForeignKey('users.id'), nullable=True, index=True)

    # Tag classification
    kind = Column(String, nullable=False, default='user', index=True)
    # kind values: 'user' | 'content_type'

    # Which model produced this tag (null for user-created)
    source = Column(String, nullable=True)
    # e.g. "vision:clip_classifier", null

    # Relationships
    photos = relationship("Photo", secondary=photo_tags, backref="tags")


class PhotoTag:
    """Helper class for photo-tag associations (not a table model)"""
    pass
