"""Seed the content-recommendations feature pack: content_relation.

Curated upsell/cross-sell/related-item recommendations, generic across e-commerce
(product) and blog (article) style content instead of two near-identical packs --
config at install time (content_entity_key etc.) says which entity this install
targets, matching the entity-agnostic approach already used by connections-networking/
social-feed's relation fields, except here the target entity isn't fixed at pack-
definition time so a plain indexed text field is used instead of a `relation` field
(which requires a fixed relation_entity_key).

Two other recommendation modes need NO stored entity at all, by design:
- "same category" / "same tag" discovery is a live query against the project's own
  content entity (tag-based discovery only became possible with the companion
  P2HSCloud commit indexing multi_select as one row per selected value).
- AI-assisted "similar items" is a live call to Cloud's existing POST .../ai/search
  (semantic similarity over whatever field was embedded) -- results aren't persisted
  here, always fresh, and gracefully unavailable (not an error) when the project
  hasn't configured AI. Cloud's ai/embed and ai/search are project-native (billed
  through Cloud's own AI credits), not a BYOK connector -- this pack declares no
  connector requirement.

Revision ID: 117
Revises: 116
"""
from datetime import datetime, timezone
from uuid import uuid4

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

revision = "117"
down_revision = "116"
branch_labels = None
depends_on = None

feature_packs = sa.table(
    "feature_packs",
    sa.column("id", postgresql.UUID(as_uuid=True)),
    sa.column("slug", sa.String),
    sa.column("name", sa.String),
    sa.column("description", sa.Text),
    sa.column("version", sa.String),
    sa.column("tags", postgresql.JSONB),
    sa.column("status", sa.String),
    sa.column("composition", postgresql.JSONB),
    sa.column("input_schema", postgresql.JSONB),
    sa.column("access_policy", postgresql.JSONB),
)

_CONTENT_RELATION_ENTITY = {
    "entity_key": "content_relation",
    "name": "Content Relation",
    "plural_name": "Content Relations",
    "schema": {
        "fields": [
            {"key": "source_entity_key", "name": "Source Entity", "type": "text", "required": True, "indexed": True},
            {"key": "source_record_id", "name": "Source Record", "type": "text", "required": True, "indexed": True},
            {"key": "target_entity_key", "name": "Target Entity", "type": "text", "required": True, "indexed": True},
            {"key": "target_record_id", "name": "Target Record", "type": "text", "required": True, "indexed": True},
            {
                "key": "relation_type", "name": "Relation Type", "type": "select", "required": True, "indexed": True,
                "options": ["upsell", "cross_sell", "related"],
            },
            {"key": "rank", "name": "Rank", "type": "number"},
        ],
    },
}

_COMPOSITION = {
    "function_slugs": [],
    "entities": [_CONTENT_RELATION_ENTITY],
    "connector_actions": [],
    "requires": [],
}

_INPUT_SCHEMA = {
    "type": "object",
    "required": ["content_entity_key"],
    "properties": {
        "content_entity_key": {
            "type": "string",
            "description": "The entity this install's recommendations target, e.g. \"product\" or the project's own article/blog entity. Must already be declared.",
        },
        "content_category_field_key": {
            "type": "string",
            "description": "Optional select field on content_entity_key used for \"same category\" baseline discovery.",
        },
        "content_tags_field_key": {
            "type": "string",
            "description": "Optional multi_select field on content_entity_key used for tag-based baseline discovery.",
        },
        "content_text_field_key": {
            "type": "string",
            "description": "Optional text field on content_entity_key to embed for AI-assisted similarity search (POST .../ai/search) when the project has AI configured. Ignored otherwise.",
        },
    },
}


def upgrade() -> None:
    now = datetime.now(timezone.utc)
    op.bulk_insert(
        feature_packs,
        [
            {
                "id": uuid4(),
                "slug": "content-recommendations",
                "name": "Content Recommendations",
                "description": (
                    "Upsell/cross-sell/related-item recommendations for any content "
                    "entity (products, articles, ...) -- curated relations plus "
                    "same-category/tag-based baseline discovery, with optional "
                    "AI-assisted similarity search when the project has Cloud's AI "
                    "configured."
                ),
                "version": "1.0.0",
                "tags": ["recommendations", "discovery", "ai"],
                "status": "active",
                "composition": _COMPOSITION,
                "input_schema": _INPUT_SCHEMA,
                "access_policy": {"minimum_plan": "free"},
                "created_at": now,
                "updated_at": now,
            },
        ],
    )


def downgrade() -> None:
    op.execute("DELETE FROM feature_packs WHERE slug = 'content-recommendations'")
