"""add moments + junction tables + moment embeddings

Revision ID: 0041
Revises: 0040
Create Date: 2026-04-25

People, Places, Tasks, and Notes all live in the `notes` table (distinguished
by note_type and is_task). The four junction tables FK to notes(id) but stay
separate so per-link-kind queries don't require a discriminator filter.
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import ARRAY, JSONB


revision = "0041"
down_revision = "0040"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.create_table(
        "moments",
        sa.Column("id", sa.Integer, primary_key=True),
        sa.Column(
            "user_id",
            sa.Integer,
            sa.ForeignKey("users.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column(
            "conversation_id",
            sa.Integer,
            sa.ForeignKey("conversations.id", ondelete="SET NULL"),
            nullable=True,
        ),
        sa.Column(
            "source_message_id",
            sa.Integer,
            sa.ForeignKey("messages.id", ondelete="SET NULL"),
            nullable=True,
        ),
        sa.Column("day_date", sa.Date, nullable=False),
        sa.Column("occurred_at", sa.DateTime(timezone=True), nullable=False),
        sa.Column(
            "recorded_at",
            sa.DateTime(timezone=True),
            nullable=False,
            server_default=sa.text("now()"),
        ),
        sa.Column("content", sa.Text, nullable=False),
        sa.Column("raw_excerpt", sa.Text, nullable=True),
        sa.Column(
            "tags",
            ARRAY(sa.Text),
            nullable=False,
            server_default=sa.text("'{}'::text[]"),
        ),
        sa.Column(
            "pinned",
            sa.Boolean,
            nullable=False,
            server_default=sa.text("false"),
        ),
    )
    op.create_index("ix_moments_user_day", "moments", ["user_id", "day_date"])
    op.create_index("ix_moments_user_occurred", "moments", ["user_id", "occurred_at"])

    # Four junction tables, all FK to notes(id). Separate (vs. one merged
    # table with a discriminator) so per-kind queries don't need a filter.
    for table_name, fk_col in [
        ("moment_people", "person_id"),
        ("moment_places", "place_id"),
        ("moment_tasks", "task_id"),
        ("moment_notes", "note_id"),
    ]:
        op.create_table(
            table_name,
            sa.Column(
                "moment_id",
                sa.Integer,
                sa.ForeignKey("moments.id", ondelete="CASCADE"),
                primary_key=True,
            ),
            sa.Column(
                fk_col,
                sa.Integer,
                sa.ForeignKey("notes.id", ondelete="CASCADE"),
                primary_key=True,
            ),
        )
        op.create_index(f"ix_{table_name}_{fk_col}", table_name, [fk_col])

    op.create_table(
        "moment_embeddings",
        sa.Column(
            "moment_id",
            sa.Integer,
            sa.ForeignKey("moments.id", ondelete="CASCADE"),
            primary_key=True,
        ),
        sa.Column("user_id", sa.Integer, nullable=False),
        sa.Column("embedding", JSONB, nullable=False),
        sa.Column(
            "updated_at",
            sa.DateTime(timezone=True),
            nullable=False,
            server_default=sa.text("now()"),
        ),
    )
    op.create_index("ix_moment_embeddings_user", "moment_embeddings", ["user_id"])


def downgrade() -> None:
    op.drop_index("ix_moment_embeddings_user", table_name="moment_embeddings")
    op.drop_table("moment_embeddings")
    for table_name, fk_col in [
        ("moment_notes", "note_id"),
        ("moment_tasks", "task_id"),
        ("moment_places", "place_id"),
        ("moment_people", "person_id"),
    ]:
        op.drop_index(f"ix_{table_name}_{fk_col}", table_name=table_name)
        op.drop_table(table_name)
    op.drop_index("ix_moments_user_occurred", table_name="moments")
    op.drop_index("ix_moments_user_day", table_name="moments")
    op.drop_table("moments")
