"""Measurement model for storing individual measurements."""
from datetime import datetime
from typing import Optional

from sqlalchemy import (
    BigInteger, Boolean, DECIMAL, DateTime, Enum, ForeignKey,
    Integer, String, func,
)
from sqlalchemy.orm import Mapped, mapped_column

from src.backend.database import Base


class Measurement(Base):
    __tablename__ = "measurements"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    subtask_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("recipe_subtasks.id"), nullable=False, index=True
    )
    version_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("recipe_versions.id"), nullable=False, index=True
    )
    measured_by: Mapped[int] = mapped_column(
        Integer, ForeignKey("users.id"), nullable=False, index=True
    )

    # Measurement data
    value: Mapped[float] = mapped_column(DECIMAL(12, 6), nullable=False)
    pass_fail: Mapped[str] = mapped_column(
        Enum("pass", "warning", "fail", name="pass_fail_enum"), nullable=False
    )
    deviation: Mapped[Optional[float]] = mapped_column(DECIMAL(12, 6), nullable=True)

    # Traceability
    lot_number: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, index=True)
    serial_number: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, index=True)

    # Input method
    input_method: Mapped[str] = mapped_column(
        Enum("usb_caliper", "manual", name="input_method_enum"),
        nullable=False,
        default="manual",
    )

    # Timestamp
    measured_at: Mapped[datetime] = mapped_column(
        DateTime, nullable=False, server_default=func.now(), index=True
    )

    # CSV sync flag
    synced_to_csv: Mapped[bool] = mapped_column(Boolean, default=False)

    def __repr__(self) -> str:
        return f"<Measurement subtask={self.subtask_id} value={self.value} {self.pass_fail}>"
