"""events 1차 컨테이너 ORM (개인 운영 로그 / 일정 / 할 일 / 회고)

PR-1 (migrations 239~247) 의 본체. kind enum 으로 task/calendar_event/activity_log
세 변형을 통합 관리. memo_document_id 는 메모 link (optional).
"""

from datetime import datetime
from typing import Any

from sqlalchemy import (
    BigInteger,
    Boolean,
    DateTime,
    ForeignKey,
    SmallInteger,
    String,
    Text,
)
from sqlalchemy.dialects.postgresql import ENUM as PgEnum
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column

from core.database import Base

# Postgres enum 재선언 X (create_type=False) — migration 239~243 이 권위.
EventKindEnum = PgEnum(
    "task",
    "calendar_event",
    "activity_log",
    name="event_kind",
    create_type=False,
)
EventStatusEnum = PgEnum(
    "inbox",
    "next",
    "scheduled",
    "in_progress",
    "done",
    "cancelled",
    "deferred",
    name="event_status",
    create_type=False,
)
EventSourceEnum = PgEnum(
    "manual",
    "memo",
    "email",
    "chat",
    "webhook",
    "git_commit",
    "claude_code",
    name="event_source",
    create_type=False,
)
EventActorEnum = PgEnum(
    "manual",
    "eid",
    "email_ingest",
    "system",
    name="event_actor",
    create_type=False,
)


class Event(Base):
    __tablename__ = "events"

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
    title: Mapped[str] = mapped_column(Text, nullable=False)
    description: Mapped[str | None] = mapped_column(Text)
    kind: Mapped[str] = mapped_column(EventKindEnum, nullable=False)
    status: Mapped[str] = mapped_column(EventStatusEnum, nullable=False, default="inbox")

    # 시간 필드 — kind 별 의미가 다름 (CHECK 제약은 migration 244)
    due_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    start_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    end_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    started_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    ended_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    all_day: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
    timezone: Mapped[str | None] = mapped_column(Text)

    # lifecycle
    defer_until: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    cancelled_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))

    priority: Mapped[int | None] = mapped_column(SmallInteger)
    project_tag: Mapped[str | None] = mapped_column(String(64))
    tags: Mapped[list[Any]] = mapped_column(JSONB, nullable=False, default=list)

    # 출처 / 외부 식별자
    source: Mapped[str] = mapped_column(EventSourceEnum, nullable=False, default="manual")
    source_ref: Mapped[str | None] = mapped_column(Text)
    raw_metadata: Mapped[dict[str, Any]] = mapped_column(JSONB, nullable=False, default=dict)

    # 메모 link (optional, ON DELETE SET NULL)
    memo_document_id: Mapped[int | None] = mapped_column(
        BigInteger, ForeignKey("documents.id", ondelete="SET NULL")
    )

    # 인증 / actor
    user_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("users.id"), nullable=False
    )
    created_by: Mapped[str] = mapped_column(EventActorEnum, nullable=False, default="manual")

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=datetime.now, nullable=False
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=datetime.now, onupdate=datetime.now, nullable=False
    )
