"""Usage event ORM model for analytics and billing."""

from __future__ import annotations

from datetime import datetime
from uuid import UUID as PyUUID
from uuid import uuid4

from sqlalchemy import Boolean, DateTime, Float, Integer, String
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column

from noteflow.domain.utils.time import utc_now

from .._base import Base


class UsageEventModel(Base):
    """Usage event record for analytics, billing, and observability.

    Tracks resource consumption events like summarization, transcription,
    and other billable or measurable operations.
    """

    __tablename__ = "usage_events"
    __table_args__: dict[str, str] = {"schema": "noteflow"}

    id: Mapped[PyUUID] = mapped_column(
        UUID(as_uuid=True),
        primary_key=True,
        default=uuid4,
    )
    event_type: Mapped[str] = mapped_column(
        String(100),
        nullable=False,
        index=True,
    )
    timestamp: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=utc_now,
        index=True,
    )

    # Resource identifiers
    meeting_id: Mapped[PyUUID | None] = mapped_column(
        UUID(as_uuid=True),
        nullable=True,
        index=True,
    )
    workspace_id: Mapped[PyUUID | None] = mapped_column(
        UUID(as_uuid=True),
        nullable=True,
        index=True,
    )
    project_id: Mapped[PyUUID | None] = mapped_column(
        UUID(as_uuid=True),
        nullable=True,
    )

    # Provider/model tracking
    provider_name: Mapped[str | None] = mapped_column(
        String(50),
        nullable=True,
        index=True,
    )
    model_name: Mapped[str | None] = mapped_column(
        String(100),
        nullable=True,
    )

    # Usage metrics
    tokens_input: Mapped[int | None] = mapped_column(
        Integer,
        nullable=True,
    )
    tokens_output: Mapped[int | None] = mapped_column(
        Integer,
        nullable=True,
    )
    latency_ms: Mapped[float | None] = mapped_column(
        Float,
        nullable=True,
    )

    # Status
    success: Mapped[bool] = mapped_column(
        Boolean,
        nullable=False,
        default=True,
    )
    error_code: Mapped[str | None] = mapped_column(
        String(100),
        nullable=True,
    )

    # Trace context (OTel correlation)
    trace_id: Mapped[str | None] = mapped_column(
        String(32),
        nullable=True,
    )
    span_id: Mapped[str | None] = mapped_column(
        String(16),
        nullable=True,
    )

    # Additional context (flexible key-value store)
    attributes: Mapped[dict[str, object]] = mapped_column(
        JSONB,
        nullable=False,
        default=dict,
    )

    # Metadata
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=utc_now,
    )
