import uuid
from datetime import datetime
from decimal import Decimal
from typing import TYPE_CHECKING

from sqlalchemy import DateTime, ForeignKey, Numeric, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.core.database import Base

if TYPE_CHECKING:
    from app.models.user import User
    from app.models.company import Company


class OvertimeBalance(Base):
    """Kumuliertes Überstundenguthaben pro Mitarbeiter.

    total_hours  = Summe aller genehmigten Überstunden aus time_entries
    taken_hours  = bereits als Freizeitausgleich genommene Stunden
    available    = total_hours - taken_hours
    """
    __tablename__ = "overtime_balances"

    id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    user_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"),
        nullable=False, unique=True, index=True,
    )
    company_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True), ForeignKey("companies.id", ondelete="CASCADE"), nullable=False, index=True
    )
    total_hours: Mapped[Decimal] = mapped_column(Numeric(8, 2), default=Decimal("0"))
    taken_hours: Mapped[Decimal] = mapped_column(Numeric(8, 2), default=Decimal("0"))
    last_calculated: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    last_expiry_applied_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
    )

    user: Mapped["User"] = relationship("User", lazy="noload")
    company: Mapped["Company"] = relationship("Company", lazy="noload")

    @property
    def available_hours(self) -> Decimal:
        return self.total_hours - self.taken_hours

    def __repr__(self) -> str:
        return f"<OvertimeBalance user={self.user_id} total={self.total_hours}h taken={self.taken_hours}h>"
