"""
Credential audit log model for tracking credential access and modifications.

This model provides a comprehensive audit trail for all credential-related
operations including views, updates, rotations, and decryptions.
"""

from datetime import datetime
from typing import Optional

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

from api.models.base import Base, UUIDMixin


class CredentialAuditLog(UUIDMixin, Base):
    """
    Audit trail for credential access and modifications.

    Records all operations performed on credentials including who accessed them,
    when, from where, and what action was performed.

    Attributes:
        id: UUID primary key
        credential_id: Reference to the credential
        action: Type of action performed (view, create, update, delete, rotate, decrypt)
        user_id: User who performed the action (JWT sub claim)
        ip_address: IP address of the user
        user_agent: Browser/client user agent
        details: JSON string with additional context about the action
        timestamp: When the action was performed
    """

    __tablename__ = "credential_audit_log"

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

    # Action details
    action: Mapped[str] = mapped_column(
        String(50),
        nullable=False,
        doc="Type of action performed",
    )
    user_id: Mapped[str] = mapped_column(
        String(255),
        nullable=False,
        doc="User who performed the action (JWT sub claim)",
    )

    # Context information
    ip_address: Mapped[Optional[str]] = mapped_column(
        String(45),
        nullable=True,
        doc="IP address (IPv4 or IPv6)",
    )
    user_agent: Mapped[Optional[str]] = mapped_column(
        Text,
        nullable=True,
        doc="Browser/client user agent string",
    )
    details: Mapped[Optional[str]] = mapped_column(
        Text,
        nullable=True,
        doc="JSON string with additional context (what changed, why, etc.)",
    )

    # Timestamp
    timestamp: Mapped[datetime] = mapped_column(
        nullable=False,
        server_default=func.now(),
        doc="When the action was performed",
    )

    # Table constraints
    __table_args__ = (
        CheckConstraint(
            "action IN ('view', 'create', 'update', 'delete', 'rotate', 'decrypt')",
            name="ck_credential_audit_action",
        ),
        Index("idx_cred_audit_credential", "credential_id"),
        Index("idx_cred_audit_user", "user_id"),
        Index("idx_cred_audit_timestamp", "timestamp"),
    )

    def __repr__(self) -> str:
        """String representation of the audit log entry."""
        return f"<CredentialAuditLog(id={self.id}, action={self.action}, user={self.user_id}, timestamp={self.timestamp})>"
