"""AI Primitives: project_ai_config, project_ai_embed_configs, workspace_vectorize_config.

Revision ID: 040
Revises: 039
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

revision = "040"
down_revision = "039"
branch_labels = None
depends_on = None


def upgrade() -> None:
    # project_ai_config — one row per project, upsert pattern
    op.create_table(
        "project_ai_config",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column(
            "project_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("projects.id", ondelete="CASCADE"),
            nullable=False,
            unique=True,
        ),
        # cf_workers_ai | openai | byok
        sa.Column("embedding_provider", sa.String(32), nullable=False, server_default="cf_workers_ai"),
        # resolved from plan; stored for reference and manifest generation
        sa.Column("embedding_model", sa.String(64), nullable=True),
        # BYOK only — opaque ref to Core secret
        sa.Column("embedding_secret_ref", sa.String(128), nullable=True),
        # { "openai": "sk-...", "anthropic": "..." } — all encrypted; BYOK only
        sa.Column("completion_secret_refs_json", postgresql.JSONB, nullable=True),
        # list of allowed provider slugs for this project (plan-derived at config time)
        sa.Column("completion_providers_json", postgresql.JSONB, nullable=True),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
    )
    op.create_index("ix_project_ai_config_project_id", "project_ai_config", ["project_id"])

    # project_ai_embed_configs — which entity fields to auto-embed
    op.create_table(
        "project_ai_embed_configs",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column(
            "project_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("projects.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("entity_key", sa.String(128), nullable=False),
        sa.Column("field_key", sa.String(128), nullable=False),
        sa.Column("auto_embed", sa.Boolean, nullable=False, server_default="true"),
        # null = use project default model
        sa.Column("model_override", sa.String(64), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
        sa.UniqueConstraint(
            "project_id", "entity_key", "field_key",
            name="uq_ai_embed_config_project_entity_field",
        ),
    )
    op.create_index(
        "ix_project_ai_embed_configs_project_id", "project_ai_embed_configs", ["project_id"]
    )

    # workspace_vectorize_config — one row per workspace, created when vectorize index is provisioned
    op.create_table(
        "workspace_vectorize_config",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column(
            "workspace_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("workspaces.id", ondelete="CASCADE"),
            nullable=False,
            unique=True,
        ),
        # opaque CF Vectorize index ID
        sa.Column("vectorize_index_id", sa.String(128), nullable=False),
        sa.Column("index_name", sa.String(128), nullable=False),
        # 768 | 1536 | 3072 — determined by plan at provisioning time
        sa.Column("dimensions", sa.Integer, nullable=False, server_default="768"),
        # cosine | euclidean | dot-product
        sa.Column("metric", sa.String(20), nullable=False, server_default="cosine"),
        # true after plan upgrade — user must trigger bulk re-embed before search works correctly
        sa.Column("needs_reembed", sa.Boolean, nullable=False, server_default="false"),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
    )
    op.create_index(
        "ix_workspace_vectorize_config_workspace_id",
        "workspace_vectorize_config",
        ["workspace_id"],
    )


def downgrade() -> None:
    op.drop_table("workspace_vectorize_config")
    op.drop_table("project_ai_embed_configs")
    op.drop_table("project_ai_config")
