"""
Service relationship model for service dependencies and relationships.

Service relationships track how services depend on, proxy through, or
relate to other services in the infrastructure.
"""

from datetime import datetime
from typing import Optional

from sqlalchemy import CHAR, CheckConstraint, ForeignKey, Index, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.sql import func

from .base import Base, UUIDMixin


class ServiceRelationship(Base, UUIDMixin):
    """
    Service relationship model representing dependencies and relationships.

    Tracks relationships between services including hosting, proxying,
    authentication, backend dependencies, and replication.

    Attributes:
        from_service_id: Reference to the source service in the relationship
        to_service_id: Reference to the target service in the relationship
        relationship_type: Type of relationship (hosted_on, proxied_by, etc.)
        notes: Additional notes about the relationship
        created_at: When the relationship was created
    """

    __tablename__ = "service_relationships"

    # Foreign keys
    from_service_id: Mapped[str] = mapped_column(
        CHAR(36),
        ForeignKey("services.id", ondelete="CASCADE"),
        nullable=False,
        doc="Reference to the source service in the relationship"
    )

    to_service_id: Mapped[str] = mapped_column(
        CHAR(36),
        ForeignKey("services.id", ondelete="CASCADE"),
        nullable=False,
        doc="Reference to the target service in the relationship"
    )

    # Relationship details
    relationship_type: Mapped[str] = mapped_column(
        CHAR(50),
        nullable=False,
        doc="Type: hosted_on, proxied_by, authenticates_via, backend_for, depends_on, replicates_to"
    )

    # Notes
    notes: Mapped[Optional[str]] = mapped_column(
        Text,
        doc="Additional notes about the relationship"
    )

    # Timestamp
    created_at: Mapped[datetime] = mapped_column(
        nullable=False,
        server_default=func.now(),
        doc="When the relationship was created"
    )

    # Constraints and indexes
    __table_args__ = (
        CheckConstraint(
            "relationship_type IN ('hosted_on', 'proxied_by', 'authenticates_via', 'backend_for', 'depends_on', 'replicates_to')",
            name="ck_service_relationships_type"
        ),
        UniqueConstraint("from_service_id", "to_service_id", "relationship_type", name="uq_service_relationship"),
        Index("idx_service_rel_from", "from_service_id"),
        Index("idx_service_rel_to", "to_service_id"),
    )

    def __repr__(self) -> str:
        """String representation of the service relationship."""
        return f"<ServiceRelationship(from='{self.from_service_id}', to='{self.to_service_id}', type='{self.relationship_type}')>"
