"""Speaker diarization models."""

from __future__ import annotations

from datetime import datetime
from typing import TYPE_CHECKING
from uuid import UUID as PyUUID

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

from noteflow.domain.utils.time import utc_now

from .._base import Base

if TYPE_CHECKING:
    from noteflow.infrastructure.persistence.models.core.meeting import MeetingModel


class DiarizationJobModel(Base):
    """Track background speaker diarization jobs.

    Persisting job state allows recovery after server restart and provides
    client visibility into job progress.
    """

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

    id: Mapped[str] = mapped_column(String(36), primary_key=True)
    meeting_id: Mapped[PyUUID] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("noteflow.meetings.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    status: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    segments_updated: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    speaker_ids: Mapped[list[str]] = mapped_column(
        JSONB,
        nullable=False,
        default=list,
    )
    error_message: Mapped[str] = mapped_column(Text, nullable=False, default="")
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=utc_now,
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=utc_now,
        onupdate=utc_now,
    )
    audio_duration_seconds: Mapped[float | None] = mapped_column(
        Float,
        nullable=True,
    )
    started_at: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True),
        nullable=True,
    )

    # Relationships
    meeting: Mapped[MeetingModel] = relationship(
        "MeetingModel",
        back_populates="diarization_jobs",
    )


class StreamingDiarizationTurnModel(Base):
    """Store speaker turns from real-time streaming diarization.

    These turns are persisted as they arrive for crash resilience
    and can be reloaded if the server restarts during a recording session.
    """

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

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    meeting_id: Mapped[PyUUID] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("noteflow.meetings.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    speaker: Mapped[str] = mapped_column(String(50), nullable=False)
    start_time: Mapped[float] = mapped_column(Float, nullable=False)
    end_time: Mapped[float] = mapped_column(Float, nullable=False)
    confidence: Mapped[float] = mapped_column(Float, nullable=False, default=0.0)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=utc_now,
    )

    # Relationships
    meeting: Mapped[MeetingModel] = relationship(
        "MeetingModel",
        back_populates="streaming_turns",
    )
