# app/models/syndarix/sprint.py
"""
Sprint model for Syndarix AI consulting platform.

A Sprint represents a time-boxed iteration for organizing and delivering work.
"""

from sqlalchemy import Column, Date, Enum, ForeignKey, Index, Integer, String, Text
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import relationship

from app.models.base import Base, TimestampMixin, UUIDMixin

from .enums import SprintStatus


class Sprint(Base, UUIDMixin, TimestampMixin):
    """
    Sprint model representing a time-boxed iteration.

    Tracks:
    - Sprint metadata (name, number, goal)
    - Date range (start/end)
    - Progress metrics (planned vs completed points)
    """

    __tablename__ = "sprints"

    # Foreign key to project
    project_id = Column(
        PGUUID(as_uuid=True),
        ForeignKey("projects.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )

    # Sprint identification
    name = Column(String(255), nullable=False)
    number = Column(Integer, nullable=False)  # Sprint number within project

    # Sprint goal (what we aim to achieve)
    goal = Column(Text, nullable=True)

    # Date range
    start_date = Column(Date, nullable=False, index=True)
    end_date = Column(Date, nullable=False, index=True)

    # Status
    status: Column[SprintStatus] = Column(
        Enum(SprintStatus),
        default=SprintStatus.PLANNED,
        nullable=False,
        index=True,
    )

    # Progress metrics
    planned_points = Column(Integer, nullable=True)  # Sum of story points at start
    velocity = Column(Integer, nullable=True)  # Sum of completed story points

    # Relationships
    project = relationship("Project", back_populates="sprints")
    issues = relationship("Issue", back_populates="sprint")

    __table_args__ = (
        Index("ix_sprints_project_status", "project_id", "status"),
        Index("ix_sprints_project_number", "project_id", "number"),
        Index("ix_sprints_date_range", "start_date", "end_date"),
    )

    def __repr__(self) -> str:
        return (
            f"<Sprint {self.name} (#{self.number}) "
            f"project={self.project_id} status={self.status.value}>"
        )
