"""
Modelli Label e MessageLabel – tagging messaggi con supporto tassonomia gerarchica.

Struttura ad albero (Feature N2 – Tassonomia di Classificazione Multi-livello):
  parent_id = NULL  → Livello 0: Ambito (Area Aziendale)
  parent_id = ID ambito → Livello 1: Processo
  parent_id = ID processo → Livello 2: Classificazione (foglia)

Le label senza parent_id sono label "piatte" classiche (comportamento pre-esistente).
"""

import uuid

from sqlalchemy import CHAR, ForeignKey, Index, String, Text
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column

from app.database import Base


class Label(Base):
    __tablename__ = "labels"

    id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
    )
    tenant_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False
    )
    # Tassonomia: se parent_id è None è un nodo radice (Ambito) o label piatta
    parent_id: Mapped[uuid.UUID | None] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("labels.id", ondelete="CASCADE"),
        nullable=True,
    )
    name: Mapped[str] = mapped_column(String(100), nullable=False)
    color: Mapped[str | None] = mapped_column(CHAR(7), nullable=True)  # hex #RRGGBB
    description: Mapped[str | None] = mapped_column(Text, nullable=True)

    # Nota: i vincoli di unicità sono gestiti da indici parziali nel DB:
    #   uq_label_name_root   – UNIQUE (tenant_id, name) WHERE parent_id IS NULL
    #   uq_label_name_parent – UNIQUE (tenant_id, name, parent_id) WHERE parent_id IS NOT NULL
    __table_args__ = (
        Index("idx_labels_parent", "parent_id"),
    )

    def __repr__(self) -> str:
        return f"<Label {self.name!r} parent={self.parent_id}>"


class MessageLabel(Base):
    __tablename__ = "message_labels"

    message_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("messages.id", ondelete="CASCADE"),
        primary_key=True,
    )
    label_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("labels.id", ondelete="CASCADE"),
        primary_key=True,
    )
