from datetime import datetime
from typing import List, Optional
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy import (
    Integer,
    String,
    Text,
    DateTime,
    ForeignKey,
    UniqueConstraint,
    func,
)
from shared.db.base import Base


class TagGroup(Base):
    __tablename__ = "tag_groups"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    slug: Mapped[str] = mapped_column(String(191), unique=True, nullable=False)
    feature_image: Mapped[Optional[str]] = mapped_column(Text())
    colour: Mapped[Optional[str]] = mapped_column(String(32))
    sort_order: Mapped[int] = mapped_column(Integer, default=0, nullable=False)

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now()
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
    )

    tag_links: Mapped[List["TagGroupTag"]] = relationship(
        "TagGroupTag", back_populates="group", cascade="all, delete-orphan", passive_deletes=True
    )


class TagGroupTag(Base):
    __tablename__ = "tag_group_tags"
    __table_args__ = (
        UniqueConstraint("tag_group_id", "tag_id", name="uq_tag_group_tag"),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    tag_group_id: Mapped[int] = mapped_column(
        ForeignKey("tag_groups.id", ondelete="CASCADE"), nullable=False
    )
    tag_id: Mapped[int] = mapped_column(
        ForeignKey("tags.id", ondelete="CASCADE"), nullable=False
    )

    group: Mapped["TagGroup"] = relationship("TagGroup", back_populates="tag_links")
