"""
Security incident model for tracking security events and remediation.

This model captures security incidents, their investigation, and resolution
including BEC, backdoors, malware, and other security threats.
"""

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 api.models.base import Base, TimestampMixin, UUIDMixin


class SecurityIncident(UUIDMixin, TimestampMixin, Base):
    """
    Security incident tracking and remediation.

    Records security incidents from detection through investigation to resolution,
    including details about the incident type, severity, and remediation steps.

    Attributes:
        id: UUID primary key
        client_id: Reference to affected client
        service_id: Reference to affected service
        infrastructure_id: Reference to affected infrastructure
        incident_type: Type of security incident
        incident_date: When the incident occurred
        severity: Severity level (critical, high, medium, low)
        description: Detailed description of the incident
        findings: Investigation results and findings
        remediation_steps: Steps taken to remediate
        status: Current status of incident handling
        resolved_at: When the incident was resolved
        notes: Additional notes
        created_at: Creation timestamp
        updated_at: Last update timestamp
    """

    __tablename__ = "security_incidents"

    # Foreign keys
    client_id: Mapped[Optional[str]] = mapped_column(
        CHAR(36),
        ForeignKey("clients.id", ondelete="CASCADE"),
        nullable=True,
        doc="Reference to affected client",
    )
    service_id: Mapped[Optional[str]] = mapped_column(
        CHAR(36),
        ForeignKey("services.id", ondelete="SET NULL"),
        nullable=True,
        doc="Reference to affected service",
    )
    infrastructure_id: Mapped[Optional[str]] = mapped_column(
        CHAR(36),
        ForeignKey("infrastructure.id", ondelete="SET NULL"),
        nullable=True,
        doc="Reference to affected infrastructure",
    )

    # Incident details
    incident_type: Mapped[Optional[str]] = mapped_column(
        String(100),
        nullable=True,
        doc="Type of security incident",
    )
    incident_date: Mapped[datetime] = mapped_column(
        nullable=False,
        doc="When the incident occurred",
    )
    severity: Mapped[Optional[str]] = mapped_column(
        String(50),
        nullable=True,
        doc="Severity level",
    )
    description: Mapped[str] = mapped_column(
        Text,
        nullable=False,
        doc="Detailed description of the incident",
    )

    # Investigation and remediation
    findings: Mapped[Optional[str]] = mapped_column(
        Text,
        nullable=True,
        doc="Investigation results and findings",
    )
    remediation_steps: Mapped[Optional[str]] = mapped_column(
        Text,
        nullable=True,
        doc="Steps taken to remediate the incident",
    )

    # Status tracking
    status: Mapped[str] = mapped_column(
        String(50),
        nullable=False,
        server_default="'investigating'",
        doc="Current status of incident handling",
    )
    resolved_at: Mapped[Optional[datetime]] = mapped_column(
        nullable=True,
        doc="When the incident was resolved",
    )

    # Additional information
    notes: Mapped[Optional[str]] = mapped_column(
        Text,
        nullable=True,
        doc="Additional notes and context",
    )

    # Table constraints
    __table_args__ = (
        CheckConstraint(
            "incident_type IN ('bec', 'backdoor', 'malware', 'unauthorized_access', 'data_breach', 'phishing', 'ransomware', 'brute_force')",
            name="ck_security_incidents_type",
        ),
        CheckConstraint(
            "severity IN ('critical', 'high', 'medium', 'low')",
            name="ck_security_incidents_severity",
        ),
        CheckConstraint(
            "status IN ('investigating', 'contained', 'resolved', 'monitoring')",
            name="ck_security_incidents_status",
        ),
        Index("idx_incidents_client", "client_id"),
        Index("idx_incidents_type", "incident_type"),
        Index("idx_incidents_status", "status"),
    )

    def __repr__(self) -> str:
        """String representation of the security incident."""
        return f"<SecurityIncident(id={self.id}, type={self.incident_type}, severity={self.severity}, status={self.status})>"
