"""Coverage snapshot models — periodic snapshots of coverage state.

CoverageSnapshot stores aggregate metrics at a point in time.
SnapshotTechniqueState stores per-technique state (normalized, one row
per technique per snapshot) to avoid bloated JSONB fields.
"""

import uuid
from sqlalchemy import (
    Column, String, Float, Integer, DateTime,
    ForeignKey, Index, func,
)
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import relationship

from app.database import Base


class CoverageSnapshot(Base):
    """A point-in-time snapshot of the organisation's overall coverage."""

    __tablename__ = "coverage_snapshots"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    name = Column(String, nullable=True)  # e.g. "Pre-remediación Q1"
    organization_score = Column(Float, nullable=False)
    total_techniques = Column(Integer, nullable=False)
    validated_count = Column(Integer, nullable=False)
    partial_count = Column(Integer, nullable=False)
    not_covered_count = Column(Integer, nullable=False)
    in_progress_count = Column(Integer, nullable=False)
    not_evaluated_count = Column(Integer, nullable=False)
    coverage_percentage = Column(Float, nullable=False, default=0.0)
    by_tactic = Column(JSONB, nullable=False, default=dict)
    by_status = Column(JSONB, nullable=False, default=dict)
    stale_count = Column(Integer, nullable=False, default=0)
    never_tested_count = Column(Integer, nullable=False, default=0)
    created_by = Column(
        UUID(as_uuid=True),
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
    )
    created_at = Column(DateTime(timezone=True), server_default=func.now())

    # Relationships
    creator = relationship("User", foreign_keys=[created_by])
    technique_states = relationship(
        "SnapshotTechniqueState",
        back_populates="snapshot",
        cascade="all, delete-orphan",
    )


class SnapshotTechniqueState(Base):
    """Per-technique state within a snapshot (normalised storage)."""

    __tablename__ = "snapshot_technique_states"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    snapshot_id = Column(
        UUID(as_uuid=True),
        ForeignKey("coverage_snapshots.id", ondelete="CASCADE"),
        nullable=False,
    )
    technique_id = Column(
        UUID(as_uuid=True),
        ForeignKey("techniques.id", ondelete="CASCADE"),
        nullable=False,
    )
    mitre_id = Column(String, nullable=False)  # denormalised for fast queries
    status = Column(String, nullable=False)
    score = Column(Float, nullable=True)

    # Relationships
    snapshot = relationship("CoverageSnapshot", back_populates="technique_states")
    technique = relationship("Technique")

    __table_args__ = (
        Index("ix_snapshot_technique_states_snapshot", "snapshot_id"),
        Index("ix_snapshot_technique_states_technique", "technique_id"),
    )
