"""HeadMetricsSnapshot — a daily per-concept time-series point (#114).

The "amount of change over time" reporting the operator asked for: once a day,
record each concept's auto-applied VOLUME (current head_auto tags), cumulative
misfires/under-fires, and the head's measured quality. Plotting these rows over
time shows whether auto-apply is landing better/worse and whether tagging more is
sharpening a concept — the signal for tuning the precision target + support floor.
"""

from datetime import datetime

from sqlalchemy import DateTime, Float, ForeignKey, Integer, String, func
from sqlalchemy.orm import Mapped, mapped_column

from .base import Base


class HeadMetricsSnapshot(Base):
    __tablename__ = "head_metrics_snapshot"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    tag_id: Mapped[int] = mapped_column(
        ForeignKey("tag.id", ondelete="CASCADE"), index=True
    )
    # Denormalized so a snapshot stays readable even if the tag is later renamed.
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    snapshot_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now(), index=True
    )
    # Current count of source='head_auto' applications still standing.
    n_auto_applied: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    n_misfires: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    n_underfires: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    # The head's measured quality at snapshot time (null if no head exists).
    ap: Mapped[float | None] = mapped_column(Float, nullable=True)
    precision_cv: Mapped[float | None] = mapped_column(Float, nullable=True)
    recall: Mapped[float | None] = mapped_column(Float, nullable=True)
    n_pos: Mapped[int | None] = mapped_column(Integer, nullable=True)
