"""#

Revision ID: e9d7edf701e1
Revises:
Create Date: 2025-10-04 10:31:31.176030

"""

from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision: str = "e9d7edf701e1"
down_revision: Union[str, Sequence[str], None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    """Upgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "threads",
        sa.Column("user_id", sa.String(length=255), nullable=False, comment="External user identifier"),
        sa.Column("title", sa.String(length=255), nullable=True, comment="Optional thread title"),
        sa.Column("is_active", sa.Boolean(), nullable=False, comment="Whether thread is active"),
        sa.Column("agent_id", sa.String(length=255), nullable=True, comment="Associated agent identifier"),
        sa.Column("extra_data", sa.JSON(), nullable=True, comment="Additional thread metadata"),
        sa.Column("id", sa.String(length=36), nullable=False, comment="Primary key UUID"),
        sa.Column(
            "created_at",
            sa.DateTime(timezone=True),
            server_default=sa.text("(CURRENT_TIMESTAMP)"),
            nullable=False,
            comment="Record creation timestamp",
        ),
        sa.Column(
            "updated_at",
            sa.DateTime(timezone=True),
            server_default=sa.text("(CURRENT_TIMESTAMP)"),
            nullable=False,
            comment="Record last update timestamp",
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_threads_agent_id", "threads", ["agent_id"], unique=False)
    op.create_index("ix_threads_is_active", "threads", ["is_active"], unique=False)
    op.create_index(op.f("ix_threads_user_id"), "threads", ["user_id"], unique=False)
    op.create_index("ix_threads_user_id_created", "threads", ["user_id", "created_at"], unique=False)
    op.create_table(
        "user_facts",
        sa.Column("user_id", sa.String(length=255), nullable=False, comment="External user identifier"),
        sa.Column("fact_id", sa.String(length=36), nullable=False, comment="Unique fact identifier"),
        sa.Column("fact_data", sa.JSON(), nullable=False, comment="Fact content and metadata"),
        sa.Column("fact_type", sa.String(length=100), nullable=True, comment="Type or category of fact"),
        sa.Column("embedding", sa.JSON(), nullable=True, comment="Vector embedding for semantic search"),
        sa.Column("importance_score", sa.Float(), nullable=True, comment="Importance score for fact ranking"),
        sa.Column("expires_at", sa.DateTime(timezone=True), nullable=True, comment="Optional expiration timestamp"),
        sa.Column("extra_data", sa.JSON(), nullable=True, comment="Additional fact metadata"),
        sa.Column("id", sa.String(length=36), nullable=False, comment="Primary key UUID"),
        sa.Column(
            "created_at",
            sa.DateTime(timezone=True),
            server_default=sa.text("(CURRENT_TIMESTAMP)"),
            nullable=False,
            comment="Record creation timestamp",
        ),
        sa.Column(
            "updated_at",
            sa.DateTime(timezone=True),
            server_default=sa.text("(CURRENT_TIMESTAMP)"),
            nullable=False,
            comment="Record last update timestamp",
        ),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("fact_id"),
    )
    op.create_index("ix_user_facts_expires", "user_facts", ["expires_at"], unique=False)
    op.create_index("ix_user_facts_fact_type", "user_facts", ["fact_type"], unique=False)
    op.create_index("ix_user_facts_importance", "user_facts", ["importance_score"], unique=False)
    op.create_index(op.f("ix_user_facts_user_id"), "user_facts", ["user_id"], unique=False)
    op.create_index("ix_user_facts_user_id_created", "user_facts", ["user_id", "created_at"], unique=False)
    op.create_table(
        "messages",
        sa.Column("thread_id", sa.String(length=36), nullable=False, comment="Reference to parent thread"),
        sa.Column("message_id", sa.String(length=36), nullable=False, comment="Unique message identifier"),
        sa.Column("role", sa.String(length=50), nullable=False, comment="Message role: user, assistant, system, tool"),
        sa.Column("content", sa.Text(), nullable=False, comment="Message content"),
        sa.Column(
            "user_id", sa.String(length=255), nullable=True, comment="External user identifier for user messages"
        ),
        sa.Column("agent_id", sa.String(length=255), nullable=True, comment="Agent identifier for assistant messages"),
        sa.Column("run_id", sa.String(length=36), nullable=True, comment="Run identifier for agent execution tracing"),
        sa.Column("structured_response", sa.JSON(), nullable=True, comment="Structured response data from agents"),
        sa.Column("tool_calls", sa.JSON(), nullable=True, comment="Tool calls made during message processing"),
        sa.Column("extra_data", sa.JSON(), nullable=True, comment="Additional message metadata"),
        sa.Column("processing_time_ms", sa.Integer(), nullable=True, comment="Processing time in milliseconds"),
        sa.Column("token_count", sa.Integer(), nullable=True, comment="Token count for this message"),
        sa.Column("id", sa.String(length=36), nullable=False, comment="Primary key UUID"),
        sa.Column(
            "created_at",
            sa.DateTime(timezone=True),
            server_default=sa.text("(CURRENT_TIMESTAMP)"),
            nullable=False,
            comment="Record creation timestamp",
        ),
        sa.Column(
            "updated_at",
            sa.DateTime(timezone=True),
            server_default=sa.text("(CURRENT_TIMESTAMP)"),
            nullable=False,
            comment="Record last update timestamp",
        ),
        sa.ForeignKeyConstraint(["thread_id"], ["threads.id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("message_id"),
    )
    op.create_index("ix_messages_agent_id", "messages", ["agent_id"], unique=False)
    op.create_index("ix_messages_message_id", "messages", ["message_id"], unique=False)
    op.create_index("ix_messages_role", "messages", ["role"], unique=False)
    op.create_index("ix_messages_run_id", "messages", ["run_id"], unique=False)
    op.create_index(op.f("ix_messages_thread_id"), "messages", ["thread_id"], unique=False)
    op.create_index("ix_messages_thread_id_created", "messages", ["thread_id", "created_at"], unique=False)
    op.create_index("ix_messages_user_id", "messages", ["user_id"], unique=False)
    op.create_table(
        "checkpoints",
        sa.Column("thread_id", sa.String(length=36), nullable=False, comment="Reference to parent thread"),
        sa.Column("checkpoint_id", sa.String(length=36), nullable=False, comment="Unique checkpoint identifier"),
        sa.Column(
            "checkpoint_type",
            sa.String(length=50),
            nullable=False,
            comment="Type of checkpoint: llm_call, tool_call, user_input, etc.",
        ),
        sa.Column("state_data", sa.JSON(), nullable=False, comment="Serialized LangGraph state data"),
        sa.Column("message_id", sa.String(length=36), nullable=True, comment="Associated message identifier"),
        sa.Column("agent_id", sa.String(length=255), nullable=True, comment="Agent identifier"),
        sa.Column("run_id", sa.String(length=36), nullable=True, comment="Run identifier for tracing"),
        sa.Column("sequence_number", sa.Integer(), nullable=False, comment="Sequence number within thread"),
        sa.Column("extra_data", sa.JSON(), nullable=True, comment="Additional checkpoint metadata"),
        sa.Column("id", sa.String(length=36), nullable=False, comment="Primary key UUID"),
        sa.Column(
            "created_at",
            sa.DateTime(timezone=True),
            server_default=sa.text("(CURRENT_TIMESTAMP)"),
            nullable=False,
            comment="Record creation timestamp",
        ),
        sa.Column(
            "updated_at",
            sa.DateTime(timezone=True),
            server_default=sa.text("(CURRENT_TIMESTAMP)"),
            nullable=False,
            comment="Record last update timestamp",
        ),
        sa.ForeignKeyConstraint(
            ["message_id"],
            ["messages.message_id"],
        ),
        sa.ForeignKeyConstraint(["thread_id"], ["threads.id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("checkpoint_id"),
    )
    op.create_index("ix_checkpoints_message_id", "checkpoints", ["message_id"], unique=False)
    op.create_index("ix_checkpoints_run_id", "checkpoints", ["run_id"], unique=False)
    op.create_index(op.f("ix_checkpoints_thread_id"), "checkpoints", ["thread_id"], unique=False)
    op.create_index("ix_checkpoints_thread_id_sequence", "checkpoints", ["thread_id", "sequence_number"], unique=False)
    op.create_index("ix_checkpoints_type", "checkpoints", ["checkpoint_type"], unique=False)
    op.drop_index(op.f("ix_approvals_agent_id"), table_name="approvals")
    op.drop_index(op.f("ix_approvals_thread_id"), table_name="approvals")
    op.drop_table("approvals")
    # ### end Alembic commands ###


def downgrade() -> None:
    """Downgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "approvals",
        sa.Column("id", sa.VARCHAR(length=64), nullable=False),
        sa.Column("agent_id", sa.VARCHAR(length=128), nullable=False),
        sa.Column("thread_id", sa.VARCHAR(length=128), nullable=False),
        sa.Column("channel_id", sa.VARCHAR(length=64), nullable=False),
        sa.Column("view_json", sa.TEXT(), nullable=False),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(op.f("ix_approvals_thread_id"), "approvals", ["thread_id"], unique=False)
    op.create_index(op.f("ix_approvals_agent_id"), "approvals", ["agent_id"], unique=False)
    op.drop_index("ix_checkpoints_type", table_name="checkpoints")
    op.drop_index("ix_checkpoints_thread_id_sequence", table_name="checkpoints")
    op.drop_index(op.f("ix_checkpoints_thread_id"), table_name="checkpoints")
    op.drop_index("ix_checkpoints_run_id", table_name="checkpoints")
    op.drop_index("ix_checkpoints_message_id", table_name="checkpoints")
    op.drop_table("checkpoints")
    op.drop_index("ix_messages_user_id", table_name="messages")
    op.drop_index("ix_messages_thread_id_created", table_name="messages")
    op.drop_index(op.f("ix_messages_thread_id"), table_name="messages")
    op.drop_index("ix_messages_run_id", table_name="messages")
    op.drop_index("ix_messages_role", table_name="messages")
    op.drop_index("ix_messages_message_id", table_name="messages")
    op.drop_index("ix_messages_agent_id", table_name="messages")
    op.drop_table("messages")
    op.drop_index("ix_user_facts_user_id_created", table_name="user_facts")
    op.drop_index(op.f("ix_user_facts_user_id"), table_name="user_facts")
    op.drop_index("ix_user_facts_importance", table_name="user_facts")
    op.drop_index("ix_user_facts_fact_type", table_name="user_facts")
    op.drop_index("ix_user_facts_expires", table_name="user_facts")
    op.drop_table("user_facts")
    op.drop_index("ix_threads_user_id_created", table_name="threads")
    op.drop_index(op.f("ix_threads_user_id"), table_name="threads")
    op.drop_index("ix_threads_is_active", table_name="threads")
    op.drop_index("ix_threads_agent_id", table_name="threads")
    op.drop_table("threads")
    # ### end Alembic commands ###
