"""
會議資料表 Model(階段 4)。

整合進對話流程:會議錄音 → Whisper → Claude 摘要 → 在團隊頻道發訊息。
不另設「會議室分頁」,符合「所有對話一個地方」的設計。

5 張相關表:
  - meetings              ─ 會議基本資料 + 處理狀態
  - meeting_transcripts   ─ 逐字稿(分段,含時間戳)
  - meeting_summaries     ─ 摘要(每場 1 筆)
  - meeting_decisions     ─ 重要決策(可有多筆)
  - meeting_action_items  ─ 待辦事項(可一鍵轉成 task)
"""

from datetime import datetime
from uuid import UUID, uuid4

from sqlalchemy import JSON, BigInteger, DateTime, Float, ForeignKey, Integer, String, Text, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.database import Base
from app.models.user import TimestampMixin, User


class Meeting(Base, TimestampMixin):
    """會議。"""

    __tablename__ = "meetings"

    id: Mapped[UUID] = mapped_column(Uuid(as_uuid=True), primary_key=True, default=uuid4)
    title: Mapped[str] = mapped_column(String(300), nullable=False, default="未命名會議")

    # uploaded(剛上傳) / transcribing / summarizing / completed / failed
    status: Mapped[str] = mapped_column(String(20), nullable=False, default="uploaded", index=True)
    error_message: Mapped[str | None] = mapped_column(Text, nullable=True)

    # 音訊檔資訊
    audio_path: Mapped[str | None] = mapped_column(String(1000), nullable=True)
    audio_size_bytes: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
    audio_duration_seconds: Mapped[float | None] = mapped_column(Float, nullable=True)
    audio_mime_type: Mapped[str | None] = mapped_column(String(100), nullable=True)

    # 來源:從哪個訊息觸發(讓會議摘要能 reply 那則上傳訊息)
    source_message_id: Mapped[UUID | None] = mapped_column(
        Uuid(as_uuid=True), nullable=True
    )
    # Coba 把摘要發到哪個頻道
    summary_message_id: Mapped[UUID | None] = mapped_column(
        Uuid(as_uuid=True), nullable=True
    )

    created_by: Mapped[UUID] = mapped_column(
        Uuid(as_uuid=True),
        ForeignKey("users.id", ondelete="RESTRICT"),
        nullable=False,
        index=True,
    )

    # 關聯
    creator: Mapped[User] = relationship(foreign_keys=[created_by], lazy="joined")
    transcripts: Mapped[list["MeetingTranscript"]] = relationship(
        back_populates="meeting", cascade="all, delete-orphan", lazy="selectin"
    )
    summary: Mapped["MeetingSummary | None"] = relationship(
        back_populates="meeting", cascade="all, delete-orphan", uselist=False, lazy="joined"
    )
    decisions: Mapped[list["MeetingDecision"]] = relationship(
        back_populates="meeting", cascade="all, delete-orphan", lazy="selectin"
    )
    action_items: Mapped[list["MeetingActionItem"]] = relationship(
        back_populates="meeting", cascade="all, delete-orphan", lazy="selectin"
    )

    def __repr__(self) -> str:
        return f"<Meeting {self.title!r} status={self.status}>"


class MeetingTranscript(Base):
    """逐字稿:一段一段存(speaker / 起始時間 / 內容)。"""

    __tablename__ = "meeting_transcripts"

    id: Mapped[UUID] = mapped_column(Uuid(as_uuid=True), primary_key=True, default=uuid4)
    meeting_id: Mapped[UUID] = mapped_column(
        Uuid(as_uuid=True),
        ForeignKey("meetings.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    # Whisper 的 speaker label(目前 faster-whisper 不做 diarization,先存 speaker_0)
    # 階段 5 升級到 WhisperX 才有真正分人
    speaker_label: Mapped[str] = mapped_column(String(50), nullable=False, default="speaker_0")
    speaker_user_id: Mapped[UUID | None] = mapped_column(
        Uuid(as_uuid=True),
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
    )
    start_time: Mapped[float] = mapped_column(Float, nullable=False)   # 秒
    end_time: Mapped[float] = mapped_column(Float, nullable=False)
    content: Mapped[str] = mapped_column(Text, nullable=False)
    confidence: Mapped[float | None] = mapped_column(Float, nullable=True)
    order_index: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), nullable=False
    )

    meeting: Mapped[Meeting] = relationship(back_populates="transcripts")


class MeetingSummary(Base):
    """會議摘要(每場 1 筆)。"""

    __tablename__ = "meeting_summaries"

    id: Mapped[UUID] = mapped_column(Uuid(as_uuid=True), primary_key=True, default=uuid4)
    meeting_id: Mapped[UUID] = mapped_column(
        Uuid(as_uuid=True),
        ForeignKey("meetings.id", ondelete="CASCADE"),
        nullable=False,
        unique=True,
    )
    # 三句話濃縮
    executive_summary: Mapped[str] = mapped_column(Text, nullable=False)
    # 主題清單(JSON 陣列,例如 ["產品定位", "Q4 預算", "新客戶 A"])
    key_topics: Mapped[list[str] | None] = mapped_column(JSON, nullable=True)
    # 用了哪個 model 產生
    generated_by: Mapped[str] = mapped_column(String(50), nullable=False, default="claude-sonnet")
    # token 用量(成本追蹤)
    input_tokens: Mapped[int | None] = mapped_column(Integer, nullable=True)
    output_tokens: Mapped[int | None] = mapped_column(Integer, nullable=True)

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), nullable=False
    )

    meeting: Mapped[Meeting] = relationship(back_populates="summary")


class MeetingDecision(Base):
    """會議裡的重要決策。"""

    __tablename__ = "meeting_decisions"

    id: Mapped[UUID] = mapped_column(Uuid(as_uuid=True), primary_key=True, default=uuid4)
    meeting_id: Mapped[UUID] = mapped_column(
        Uuid(as_uuid=True),
        ForeignKey("meetings.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    decision: Mapped[str] = mapped_column(Text, nullable=False)
    context: Mapped[str | None] = mapped_column(Text, nullable=True)   # 為什麼這樣決定
    order_index: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), nullable=False
    )

    meeting: Mapped[Meeting] = relationship(back_populates="decisions")


class MeetingActionItem(Base):
    """會議自動抽出的待辦,可一鍵轉成正式 task。"""

    __tablename__ = "meeting_action_items"

    id: Mapped[UUID] = mapped_column(Uuid(as_uuid=True), primary_key=True, default=uuid4)
    meeting_id: Mapped[UUID] = mapped_column(
        Uuid(as_uuid=True),
        ForeignKey("meetings.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    description: Mapped[str] = mapped_column(Text, nullable=False)
    suggested_assignee_id: Mapped[UUID | None] = mapped_column(
        Uuid(as_uuid=True),
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
    )
    suggested_due_date: Mapped[str | None] = mapped_column(String(20), nullable=True)   # YYYY-MM-DD,字串方便
    # 確認後轉成的 task(若已轉)
    converted_task_id: Mapped[UUID | None] = mapped_column(
        Uuid(as_uuid=True),
        ForeignKey("tasks.id", ondelete="SET NULL"),
        nullable=True,
    )
    order_index: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), nullable=False
    )

    meeting: Mapped[Meeting] = relationship(back_populates="action_items")
