"""
Credential permission model for access control.

This model manages fine-grained access control for credentials,
supporting future team expansion with role-based permissions.
"""

from datetime import datetime
from typing import Optional

from sqlalchemy import (
    CHAR,
    CheckConstraint,
    ForeignKey,
    Index,
    String,
    UniqueConstraint,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.sql import func

from api.models.base import Base, UUIDMixin


class CredentialPermission(UUIDMixin, Base):
    """
    Access control for credentials.

    Manages who can access specific credentials and what level of access they have.
    Supports read, write, and admin permission levels.

    Attributes:
        id: UUID primary key
        credential_id: Reference to the credential
        user_id: User or role ID who has access
        permission_level: Level of access (read, write, admin)
        granted_at: When the permission was granted
        granted_by: Who granted the permission
    """

    __tablename__ = "credential_permissions"

    # Foreign keys
    credential_id: Mapped[str] = mapped_column(
        CHAR(36),
        ForeignKey("credentials.id", ondelete="CASCADE"),
        nullable=False,
        doc="Reference to credential",
    )

    # Permission details
    user_id: Mapped[str] = mapped_column(
        String(255),
        nullable=False,
        doc="User or role ID who has access",
    )
    permission_level: Mapped[Optional[str]] = mapped_column(
        String(50),
        nullable=True,
        doc="Level of access",
    )

    # Metadata
    granted_at: Mapped[datetime] = mapped_column(
        nullable=False,
        server_default=func.now(),
        doc="When the permission was granted",
    )
    granted_by: Mapped[Optional[str]] = mapped_column(
        String(255),
        nullable=True,
        doc="Who granted the permission",
    )

    # Table constraints
    __table_args__ = (
        CheckConstraint(
            "permission_level IN ('read', 'write', 'admin')",
            name="ck_credential_permissions_level",
        ),
        UniqueConstraint("credential_id", "user_id", name="uq_credential_user"),
        Index("idx_cred_perm_credential", "credential_id"),
        Index("idx_cred_perm_user", "user_id"),
    )

    def __repr__(self) -> str:
        """String representation of the credential permission."""
        return f"<CredentialPermission(id={self.id}, user={self.user_id}, level={self.permission_level})>"
