"""Summary and intelligence output 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, Text, UniqueConstraint
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
    from noteflow.infrastructure.persistence.models.organization.task import TaskModel


class SummaryModel(Base):
    """Represent an LLM-generated meeting summary."""

    __tablename__ = "summaries"
    __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,
        unique=True,
    )
    executive_summary: Mapped[str] = mapped_column(Text, nullable=False, default="")
    generated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=utc_now,
    )
    # Provider tracking
    provider_name: Mapped[str] = mapped_column(Text, nullable=False, default="")
    model_name: Mapped[str] = mapped_column(Text, nullable=False, default="")
    tokens_used: Mapped[int | None] = mapped_column(Integer, nullable=True)
    latency_ms: Mapped[float | None] = mapped_column(Float, nullable=True)
    # Verification/citation data
    verification: Mapped[dict[str, object]] = mapped_column(
        JSONB,
        nullable=False,
        default=dict,
    )

    # Relationships
    meeting: Mapped[MeetingModel] = relationship(
        "MeetingModel",
        back_populates="summary",
    )
    key_points: Mapped[list[KeyPointModel]] = relationship(
        "KeyPointModel",
        back_populates="summary",
        cascade="all, delete-orphan",
        lazy="selectin",
    )
    action_items: Mapped[list[ActionItemModel]] = relationship(
        "ActionItemModel",
        back_populates="summary",
        cascade="all, delete-orphan",
        lazy="selectin",
    )


class KeyPointModel(Base):
    """Represent an extracted key point from a summary."""

    __tablename__ = "key_points"
    __table_args__: tuple[UniqueConstraint, dict[str, str]] = (
        UniqueConstraint("summary_id", "position", name="key_points_unique_position"),
        {"schema": "noteflow"},
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    summary_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("noteflow.summaries.id", ondelete="CASCADE"),
        nullable=False,
    )
    position: Mapped[int] = mapped_column(Integer, nullable=False)
    text: Mapped[str] = mapped_column(Text, nullable=False)
    segment_ids: Mapped[list[int]] = mapped_column(
        JSONB,
        nullable=False,
        default=list,
    )
    start_time: Mapped[float] = mapped_column(Float, nullable=False, default=0.0)
    end_time: Mapped[float] = mapped_column(Float, nullable=False, default=0.0)

    # Relationships
    summary: Mapped[SummaryModel] = relationship(
        "SummaryModel",
        back_populates="key_points",
    )


class ActionItemModel(Base):
    """Represent an extracted action item from a summary."""

    __tablename__ = "action_items"
    __table_args__: tuple[UniqueConstraint, dict[str, str]] = (
        UniqueConstraint("summary_id", "position", name="action_items_unique_position"),
        {"schema": "noteflow"},
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    summary_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("noteflow.summaries.id", ondelete="CASCADE"),
        nullable=False,
    )
    position: Mapped[int] = mapped_column(Integer, nullable=False)
    text: Mapped[str] = mapped_column(Text, nullable=False)
    segment_ids: Mapped[list[int]] = mapped_column(
        JSONB,
        nullable=False,
        default=list,
    )
    start_time: Mapped[float] = mapped_column(Float, nullable=False, default=0.0)
    end_time: Mapped[float] = mapped_column(Float, nullable=False, default=0.0)
    assignee: Mapped[str] = mapped_column(Text, nullable=False, default="")
    due_date: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True),
        nullable=True,
    )
    priority: Mapped[int] = mapped_column(Integer, nullable=False, default=0)

    # Relationships
    summary: Mapped[SummaryModel] = relationship(
        "SummaryModel",
        back_populates="action_items",
    )
    tasks: Mapped[list[TaskModel]] = relationship(
        "TaskModel",
        back_populates="action_item",
    )
