"""drop meta + rating tag kinds — operator-retired 2026-05-26

Revision ID: 0023
Revises: 0022
Create Date: 2026-05-26

Operator decided meta + rating aren't valid tag kinds for FC. Per-row
behavior: DELETE existing rows (operator chose "clean break" over
"convert to general"). All cascading FKs (image_tag, tag_alias,
tag_allowlist, tag_reference_embedding, tag_suggestion_rejection,
series_page) use ondelete="CASCADE" so a single DELETE on tag cleans
the related rows in one go.

After the data cleanup, recreate the tag_kind ENUM without 'meta' /
'rating' (Postgres has no `ALTER TYPE ... DROP VALUE`; standard
rename-create-cast-drop dance). The server default 'general' is
dropped before the type swap and restored after.
"""
from typing import Sequence, Union

from alembic import op

revision: str = "0023"
down_revision: Union[str, None] = "0022"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    # 1. Delete tags of the retired kinds. CASCADE handles related tables.
    op.execute("DELETE FROM tag WHERE kind IN ('meta', 'rating')")

    # 2. Drop the CHECK constraint that references the enum's literal
    #    values. Postgres can't resolve `kind = 'character'` across the
    #    type swap below — the literal would bind to the new tag_kind
    #    but the column is on tag_kind_old, producing
    #    "operator does not exist: tag_kind = tag_kind_old".
    #    (Operator-hit during the v26.05.26.5 deploy attempt; ck was
    #    originally added by alembic 0002.) Recreated post-swap.
    op.drop_constraint(
        "ck_tag_fandom_requires_character", "tag", type_="check"
    )

    # 3. Drop the server default — ALTER COLUMN TYPE can't carry it
    #    across the type swap below.
    op.execute("ALTER TABLE tag ALTER COLUMN kind DROP DEFAULT")

    # 4. Recreate the tag_kind enum without meta/rating.
    op.execute("ALTER TYPE tag_kind RENAME TO tag_kind_old")
    op.execute(
        "CREATE TYPE tag_kind AS ENUM ("
        "'artist', 'character', 'fandom', 'general', "
        "'series', 'archive', 'post'"
        ")"
    )
    op.execute(
        "ALTER TABLE tag "
        "ALTER COLUMN kind TYPE tag_kind "
        "USING kind::text::tag_kind"
    )
    op.execute("DROP TYPE tag_kind_old")

    # 5. Restore the server default.
    op.execute("ALTER TABLE tag ALTER COLUMN kind SET DEFAULT 'general'")

    # 6. Restore the CHECK constraint (now bound to the new tag_kind).
    op.create_check_constraint(
        "ck_tag_fandom_requires_character",
        "tag",
        "(fandom_id IS NULL) OR (kind = 'character')",
    )


def downgrade() -> None:
    # Add the values back to the enum so old code can boot. The deleted
    # tag rows are gone permanently — no safe restore.
    op.drop_constraint(
        "ck_tag_fandom_requires_character", "tag", type_="check"
    )
    op.execute("ALTER TABLE tag ALTER COLUMN kind DROP DEFAULT")
    op.execute("ALTER TYPE tag_kind RENAME TO tag_kind_old")
    op.execute(
        "CREATE TYPE tag_kind AS ENUM ("
        "'artist', 'character', 'fandom', 'general', "
        "'series', 'archive', 'post', 'meta', 'rating'"
        ")"
    )
    op.execute(
        "ALTER TABLE tag "
        "ALTER COLUMN kind TYPE tag_kind "
        "USING kind::text::tag_kind"
    )
    op.execute("DROP TYPE tag_kind_old")
    op.execute("ALTER TABLE tag ALTER COLUMN kind SET DEFAULT 'general'")
    op.create_check_constraint(
        "ck_tag_fandom_requires_character",
        "tag",
        "(fandom_id IS NULL) OR (kind = 'character')",
    )
