"""Seed file-attachments: subject-agnostic file_id relation via data.entity.

Revision ID: 141
Revises: 140
"""
from datetime import datetime, timezone
from uuid import uuid4

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

revision = "141"
down_revision = "140"
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),
)

# Visibility is inherited from the subject record at Cloud runtime. This
# entity policy only admits authenticated create/read/delete; it is not a
# per-file ACL. Update is omitted so the relation stays immutable.
_ATTACHMENT_ACCESS_POLICY = {
    "version": 1,
    "roles": {
        "member": {
            "create": {"effect": "allow", "scope": "all"},
            "read": {"effect": "allow", "scope": "all"},
            "delete": {"effect": "allow", "scope": "all"},
        },
        "admin": {
            "create": {"effect": "allow", "scope": "all"},
            "read": {"effect": "allow", "scope": "all"},
            "delete": {"effect": "allow", "scope": "all"},
        },
        "super_admin": {
            "create": {"effect": "allow", "scope": "all"},
            "read": {"effect": "allow", "scope": "all"},
            "delete": {"effect": "allow", "scope": "all"},
        },
    },
}

_FILE_ATTACHMENT_ENTITY = {
    "entity_key": "file_attachment",
    "name": "File Attachment",
    "plural_name": "File Attachments",
    "schema": {
        "fields": [
            {
                "key": "file_id",
                "name": "File",
                "type": "text",
                "required": True,
                "indexed": True,
            },
            {
                "key": "subject_entity_key",
                "name": "Subject Entity",
                "type": "text",
                "required": True,
                "indexed": True,
            },
            {
                "key": "subject_record_id",
                "name": "Subject Record",
                "type": "text",
                "required": True,
                "indexed": True,
            },
        ],
        "access_policy": _ATTACHMENT_ACCESS_POLICY,
    },
}


def upgrade() -> None:
    from src.domain.feature_packs.normalize import stamp_composition

    now = datetime.now(timezone.utc)
    raw_composition = {
        "function_slugs": [],
        "entities": [_FILE_ATTACHMENT_ENTITY],
        "connector_actions": [],
        "requires": [],
    }
    stamped = stamp_composition("file-attachments", raw_composition)
    assert stamped["entities"][0]["schema"]["access_policy"] == _ATTACHMENT_ACCESS_POLICY
    op.bulk_insert(
        feature_packs,
        [
            {
                "id": uuid4(),
                "slug": "file-attachments",
                "name": "File Attachments",
                "description": (
                    "Subject-agnostic attachment relation: opaque file_id plus "
                    "(subject_entity_key, subject_record_id). Uses data.entity "
                    "and the existing platform storage authority. Default object "
                    "storage is an implementation detail and is never disclosed "
                    "to Codegen or generated apps as a provider, bucket, or SDK."
                ),
                "version": "1.0.0",
                "tags": ["files", "attachments", "operations"],
                "status": "active",
                "composition": stamped,
                "input_schema": {"type": "object", "properties": {}},
                "access_policy": {"minimum_plan": "free"},
                "created_at": now,
                "updated_at": now,
            },
        ],
    )


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