"""Phase 9: Ownership & Revalidation Queue models."""

import enum
import uuid
from datetime import datetime

from sqlalchemy import Column, DateTime, Enum, ForeignKey, Index, String, Text
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.orm import relationship

from app.database import Base


class QueuePriority(str, enum.Enum):
    critical = "critical"
    high = "high"
    medium = "medium"
    low = "low"


class QueueStatus(str, enum.Enum):
    pending = "pending"
    in_progress = "in_progress"
    completed = "completed"
    dismissed = "dismissed"


class QueueReason(str, enum.Enum):
    validation_expired = "validation_expired"
    infra_change = "infra_change"
    osint_alert = "osint_alert"
    mitre_update = "mitre_update"
    rule_modified = "rule_modified"
    low_confidence = "low_confidence"
    manual = "manual"


class TechniqueOwnership(Base):
    """Ownership assignment for a MITRE technique."""

    __tablename__ = "technique_ownerships"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    technique_id = Column(
        UUID(as_uuid=True),
        ForeignKey("techniques.id", ondelete="CASCADE"),
        nullable=False,
        unique=True,
    )
    owner_id = Column(
        UUID(as_uuid=True),
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
    )
    backup_owner_id = Column(
        UUID(as_uuid=True),
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
    )
    team = Column(String(200), nullable=True)
    notes = Column(Text, nullable=True)
    assigned_at = Column(DateTime, nullable=True)
    assigned_by = Column(
        UUID(as_uuid=True),
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
    )
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    technique = relationship("Technique", foreign_keys=[technique_id])
    owner = relationship("User", foreign_keys=[owner_id])
    backup_owner = relationship("User", foreign_keys=[backup_owner_id])


class RevalidationQueueItem(Base):
    """A prioritised work item for the analyst's daily queue."""

    __tablename__ = "revalidation_queue_items"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    technique_id = Column(
        UUID(as_uuid=True),
        ForeignKey("techniques.id", ondelete="CASCADE"),
        nullable=True,
    )
    detection_asset_id = Column(
        UUID(as_uuid=True),
        ForeignKey("detection_assets.id", ondelete="CASCADE"),
        nullable=True,
    )

    priority = Column(
        Enum(QueuePriority, name="queue_priority"),
        nullable=False,
        default=QueuePriority.medium,
    )
    reason = Column(
        Enum(QueueReason, name="queue_reason"),
        nullable=False,
    )
    reason_detail = Column(Text, nullable=True)
    status = Column(
        Enum(QueueStatus, name="queue_status"),
        nullable=False,
        default=QueueStatus.pending,
    )

    assigned_to = Column(
        UUID(as_uuid=True),
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
    )
    due_date = Column(DateTime, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    completed_at = Column(DateTime, nullable=True)
    dismissed_at = Column(DateTime, nullable=True)
    completed_by = Column(
        UUID(as_uuid=True),
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
    )
    extra = Column(JSONB, nullable=True)  # arbitrary metadata

    technique = relationship("Technique", foreign_keys=[technique_id])
    detection_asset = relationship("DetectionAsset", foreign_keys=[detection_asset_id])
    assignee = relationship("User", foreign_keys=[assigned_to])


# Indexes
Index("ix_rqueue_status", RevalidationQueueItem.status)
Index("ix_rqueue_priority", RevalidationQueueItem.priority)
Index("ix_rqueue_assigned_to", RevalidationQueueItem.assigned_to)
Index("ix_rqueue_technique_id", RevalidationQueueItem.technique_id)
Index("ix_rqueue_asset_id", RevalidationQueueItem.detection_asset_id)
Index("ix_techown_owner_id", TechniqueOwnership.owner_id)
