"""Task management models."""

from __future__ import annotations

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

from sqlalchemy import CheckConstraint, DateTime, ForeignKey, Integer, 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
    from noteflow.infrastructure.persistence.models.core.summary import ActionItemModel
    from noteflow.infrastructure.persistence.models.entities.speaker import PersonModel
    from noteflow.infrastructure.persistence.models.identity.identity import (
        WorkspaceModel,
    )


class TaskModel(Base):
    """Represent a user-managed task, optionally derived from an action item."""

    __tablename__ = "tasks"
    __table_args__: tuple[CheckConstraint, dict[str, str]] = (
        CheckConstraint(
            "status IN ('open', 'done', 'dismissed')",
            name="tasks_status_chk",
        ),
        {"schema": "noteflow"},
    )

    id: Mapped[PyUUID] = mapped_column(
        UUID(as_uuid=True),
        primary_key=True,
        default=uuid4,
    )
    workspace_id: Mapped[PyUUID] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("noteflow.workspaces.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    meeting_id: Mapped[PyUUID | None] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("noteflow.meetings.id", ondelete="SET NULL"),
        nullable=True,
    )
    action_item_id: Mapped[int | None] = mapped_column(
        Integer,
        ForeignKey("noteflow.action_items.id", ondelete="SET NULL"),
        nullable=True,
    )
    text: Mapped[str] = mapped_column(Text, nullable=False)
    status: Mapped[str] = mapped_column(Text, nullable=False, default="open")
    assignee_person_id: Mapped[PyUUID | None] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("noteflow.persons.id", ondelete="SET NULL"),
        nullable=True,
    )
    due_date: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True),
        nullable=True,
    )
    priority: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    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,
    )
    completed_at: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True),
        nullable=True,
    )
    metadata_: Mapped[dict[str, object]] = mapped_column(
        "metadata",
        JSONB,
        nullable=False,
        default=dict,
    )

    # Relationships
    workspace: Mapped[WorkspaceModel] = relationship(
        "WorkspaceModel",
        back_populates="tasks",
    )
    meeting: Mapped[MeetingModel | None] = relationship(
        "MeetingModel",
        back_populates="tasks",
    )
    action_item: Mapped[ActionItemModel | None] = relationship(
        "ActionItemModel",
        back_populates="tasks",
    )
    assignee_person: Mapped[PersonModel | None] = relationship(
        "PersonModel",
        back_populates="assigned_tasks",
    )
