"""Event ORM model."""

from __future__ import annotations

from datetime import datetime, timezone
from enum import Enum
from typing import TYPE_CHECKING

from sqlalchemy import DateTime, Enum as SQLEnum, ForeignKey, JSON, String, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.models.base import Base

if TYPE_CHECKING:
    from app.models.engagement import Engagement


class EventPhase(str, Enum):
    """Allowed event phases."""

    RECON = "recon"
    ENUMERATION = "enumeration"
    INITIAL_ACCESS = "initial_access"
    PRIV_ESC = "priv_esc"
    POST_EXPLOITATION = "post_exploitation"
    CLEANUP = "cleanup"


class SeverityLevel(str, Enum):
    """Allowed severity levels."""

    LOW = "low"
    MED = "med"
    HIGH = "high"


class Event(Base):
    """Represents a timeline event for one engagement."""

    __tablename__ = "events"

    id: Mapped[int] = mapped_column(primary_key=True, index=True)
    engagement_id: Mapped[int] = mapped_column(
        ForeignKey("engagements.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    ts: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=lambda: datetime.now(timezone.utc),
        index=True,
    )
    phase: Mapped[EventPhase] = mapped_column(
        SQLEnum(EventPhase, name="event_phase", native_enum=False),
        nullable=False,
        index=True,
    )
    source: Mapped[str] = mapped_column(String(100), nullable=False)
    title: Mapped[str] = mapped_column(String(255), nullable=False)
    content: Mapped[str] = mapped_column(Text, nullable=False)
    tags: Mapped[list[str]] = mapped_column(JSON, nullable=False, default=list)
    severity: Mapped[SeverityLevel] = mapped_column(
        SQLEnum(SeverityLevel, name="severity_level", native_enum=False),
        nullable=False,
        index=True,
    )
    evidence_paths: Mapped[list[str] | None] = mapped_column(JSON, nullable=True)

    engagement: Mapped["Engagement"] = relationship(back_populates="events")
